diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 017f9671..7236d4b1 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -3,7 +3,7 @@ ## Supported Versions After each new major release, the previous release will be supported for no -less than 2 years, unless explictly stated otherwise. This may mean that there +less than 2 years, unless explicitly stated otherwise. This may mean that there are multiple supported versions at any given time. ## Reporting a Vulnerability diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index f54ccd03..b37fe5d0 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -7,28 +7,30 @@ on: jobs: phpstan: name: PHPStan - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.0' - tools: composer:2.1 + php-version: '8.1' + tools: composer:v2 coverage: none + env: + update: true - name: Install Dependencies - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 command: composer update --no-interaction --no-progress - name: Install PHPStan - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 @@ -39,28 +41,30 @@ jobs: psalm: name: Psalm - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.0' - tools: composer:2.1 + php-version: '8.1' + tools: composer:v2 coverage: none + env: + update: true - name: Install Dependencies - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 command: composer update --no-interaction --no-progress - name: Install Psalm - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3464fb5b..f2a04d29 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,35 +7,37 @@ on: jobs: tests: name: PHP ${{ matrix.php }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 strategy: matrix: - php: ['7.4', '8.0', '8.1'] + php: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - tools: composer:2.1 + tools: composer:v2 coverage: none + env: + update: true - name: Setup Problem Matchers run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - name: Install Dependencies - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 command: composer update --no-interaction --no-progress - name: Install PHPUnit - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v3 with: timeout_minutes: 5 max_attempts: 5 diff --git a/.styleci.yml b/.styleci.yml index 0eeb39ab..87da8d09 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -16,6 +16,6 @@ enabled: disabled: - native_constant_invocation_symfony - native_function_invocation_symfony - - no_superfluous_phpdoc_tags_symfony + - phpdoc_align - phpdoc_to_comment - phpdoc_var_without_name diff --git a/CHANGELOG.md b/CHANGELOG.md index b63d5419..65398fb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,106 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [12.0.0] - 2025-02-23 + +* Add PHP 8.4 support +* Drop support for PHP earlier than 8.1 +* Moved various param types to native PHP types + +## [11.14.0] - 2024-03-11 + +* Add support for `php-http/cache-plugin:^2.0` +* Add support for `'approved'` `status` in `Project::events` +* Add support for `name` in `createRelease` and `updateRelease` +* Add support for date filtering to `GroupsMilestones::all()` +* Update `MergeRequests::all` to use millisecond precision for date filters + +## [11.13.0] - 2023-12-03 + +* Add support for `symfony/options-resolver:^7.0` +* Add support for `status` and `environment` in `Deployments::all` +* Add support for `Groups::search`, `Projects::search`, and `Search::all` + +## [11.12.0] - 2023-10-08 + +* Add PHP 8.3 support +* Add `Projects::updateProtectedBranch` and `Projects::updateApprovalsConfiguration` +* Add support for `environment_scope` in `Projects::removeVariable` +* Add support for `filter` in `Projects::variable` +* Add support for `author` in `Repositories::commits` +* Add support for additional parameters in `Projects::labels` and `Groups::labels` + +## [11.11.1] - 2023-10-08 + +* Fixed double encoding of job name in artifacts download + +## [11.11.0] - 2023-07-17 + +* Add support for `author_id` in `Issues::all` +* Add support for `tier` in `Environments::create` +* Add support for `expires_at` in `Groups::addMember` +* Add support for `include_retried` in `Jobs::pipelineBridges` +* Add support for additional parameters in `Projects::deployment` +* Add support for additional parameters in `Projects::forks` +* Add support for `Events::all` +* Add support for `Users::removeUserIdentity` +* Add support for `MergeRequests::showParticipants` + +## [11.10.0] - 2023-04-30 + +* Add support for `Packages::addGenericFile` +* Add support for `Milestones::mergeRequests` +* Add support for `Project::removeTrigger` +* Add support for `Schedules::takeOwnership` and `Schedules::play` +* Add support for `access_level` in `Projects::createProjectAccessToken` +* Add support for `expires_at` in `Projects::addMember` and `Projects::saveMember` +* Add support for `order_by` `version` in `Tags::all` +* Added support for `psr/http-message` v2 + +## [11.9.1] - 2023-04-30 + +* Corrected upload avatar endpoint + +## [11.9.0] - 2023-03-06 + +* Add PHP 8.2 support +* Add support for group and project deploy tokens +* Add source parameter to pipelines API +* Add support for `Jobs::artifactByJobId` +* Add support for `Users::usersStarredProjects` +* Add support for `Groups::issues` +* Add support for `Groups::iterations` +* Add support for `Projects::iterations` +* Add support for `Projects::projectAccessToken` +* Add support for `Projects::pipelineTestReport` +* Add support for `Projects::pipelineTestReportSummary` +* Add support for `allowed_to_create` in `Projects::addProtectedTag` +* Add support for `update_at` order by in `Projects::pipelines` +* Added additional parameters to `Issues::all` +* Added additional parameters to `Issues::group` +* Added the ability to authenticate with a job token + +## [11.8.0] - 2022-04-24 + +* Add support for `reviewer_id` and `wip` params in `MergeRequests::all()` +* Add support for `GroupEpics::issues()` +* Add support for `Projects::pipelineJobs()` and protected tags +* Add support for the confidential filter in `Issues:all()` +* Allow specifying params in `Wiki::showAll()` +* Allow specifying params in `SystemHooks::create()` +* Allow `chmod` action and `execute_filemode` attribute +* Implement group merge requests endpoints +* Implement event endpoints + +[11.8.0]: https://github.com/GitLabPHP/Client/compare/11.7.1...11.8.0 + +## [11.7.1] - 2022-04-24 + +* Fixed `GroupsEpic::all()` method +* Fixed `Projects::createPipeline()` method + +[11.7.1]: https://github.com/GitLabPHP/Client/compare/11.7.0...11.7.1 + ## [11.7.0] - 2022-01-24 * Dropped PHP 7.2 and 7.3 support diff --git a/LICENSE b/LICENSE index 8258d734..9cebae09 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License Copyright (c) 2012-2018 Matt Humphrey -Copyright (c) 2018-2022 Graham Campbell +Copyright (c) 2018-2025 Graham Campbell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 384c41c0..a451bbc1 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,24 @@ install: - @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:8.0-base update - @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:8.0-base bin all update + @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:8.1-base update + @docker run -it -w /data -v ${PWD}:/data:delegated -v ~/.composer:/root/.composer:delegated --entrypoint composer --rm registry.gitlab.com/grahamcampbell/php:8.1-base bin all update phpunit: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpunit --rm registry.gitlab.com/grahamcampbell/php:8.0-cli + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpunit --rm registry.gitlab.com/grahamcampbell/php:8.1-cli phpstan-analyze: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:8.0-cli analyze + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:8.1-cli analyze phpstan-baseline: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:8.0-cli analyze --generate-baseline + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/phpstan --rm registry.gitlab.com/grahamcampbell/php:8.1-cli analyze --generate-baseline psalm-analyze: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.0-cli + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.1-cli psalm-baseline: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.0-cli --set-baseline=psalm-baseline.xml + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.1-cli --set-baseline=psalm-baseline.xml psalm-show-info: - @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.0-cli --show-info=true + @docker run -it -w /data -v ${PWD}:/data:delegated --entrypoint vendor/bin/psalm.phar --rm registry.gitlab.com/grahamcampbell/php:8.1-cli --show-info=true test: phpunit phpstan-analyze psalm-analyze diff --git a/README.md b/README.md index 5ccd76cd..35065ecd 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ We present a modern [GitLab API v4](https://docs.gitlab.com/ce/api/) client for ![Banner](https://user-images.githubusercontent.com/2829600/86969006-fc2e3b00-c164-11ea-80b7-8750160a65c4.png)

-Build Status +Build Status StyleCI Status Software License Packagist Downloads @@ -23,12 +23,12 @@ Check out the [change log](CHANGELOG.md), [releases](https://github.com/GitLabPH ## Installation -This version supports [PHP](https://php.net) 7.4-8.1. To get started, simply require the project using [Composer](https://getcomposer.org). You will also need to install packages that "provide" [`psr/http-client-implementation`](https://packagist.org/providers/psr/http-client-implementation) and [`psr/http-factory-implementation`](https://packagist.org/providers/psr/http-factory-implementation). +This version supports [PHP](https://php.net) 8.1-8.4. To get started, simply require the project using [Composer](https://getcomposer.org). You will also need to install packages that "provide" [`psr/http-client-implementation`](https://packagist.org/providers/psr/http-client-implementation) and [`psr/http-factory-implementation`](https://packagist.org/providers/psr/http-factory-implementation). ### Standard Installation ```bash -$ composer require "m4tthumphrey/php-gitlab-api:^11.7" "guzzlehttp/guzzle:^7.4" "http-interop/http-factory-guzzle:^1.2" +$ composer require "m4tthumphrey/php-gitlab-api:^12.0" "guzzlehttp/guzzle:^7.9.2" ``` ### Framework Integration @@ -36,13 +36,13 @@ $ composer require "m4tthumphrey/php-gitlab-api:^11.7" "guzzlehttp/guzzle:^7.4" #### Laravel: ```bash -$ composer require "graham-campbell/gitlab:^6.0" +$ composer require "graham-campbell/gitlab:^8.0" ``` #### Symfony: ```bash -$ composer require "zeichen32/gitlabapibundle:^6.0" "symfony/http-client:^5.4" "nyholm/psr7:^1.4" +$ composer require "zeichen32/gitlabapibundle:^7.0" ``` We are decoupled from any HTTP messaging client by using [PSR-7](https://www.php-fig.org/psr/psr-7/), [PSR-17](https://www.php-fig.org/psr/psr-17/), [PSR-18](https://www.php-fig.org/psr/psr-18/), and [HTTPlug](https://httplug.io/). You can visit [HTTPlug for library users](https://docs.php-http.org/en/latest/httplug/users.html) to get more information about installing HTTPlug related packages. The framework integration [graham-campbell/gitlab](https://github.com/GrahamCampbell/Laravel-GitLab) is by [Graham Campbell](https://github.com/GrahamCampbell) and [zeichen32/gitlabapibundle](https://github.com/Zeichen32/GitLabApiBundle) is by [Jens Averkamp](https://github.com/Zeichen32). @@ -95,7 +95,7 @@ $builder->addPlugin($plugin); $client = new Gitlab\Client($builder); ``` -One can read more about HTTPlug plugins [here](https://docs.php-http.org/en/latest/plugins/introduction.html#how-it-works). Take a look around the [API methods](https://github.com/GitLabPHP/Client/tree/11.2/src/Api), and please feel free to report any bugs, noting our [code of conduct](.github/CODE_OF_CONDUCT.md). +One can read more about HTTPlug plugins [here](https://docs.php-http.org/en/latest/plugins/introduction.html#how-it-works). Take a look around the [API methods](https://github.com/GitLabPHP/Client/tree/12.0/src/Api), and please feel free to report any bugs, noting our [code of conduct](.github/CODE_OF_CONDUCT.md). ## Contributing diff --git a/composer.json b/composer.json index a8f1dd16..487fb319 100644 --- a/composer.json +++ b/composer.json @@ -26,25 +26,23 @@ } ], "require": { - "php": "^7.4.15 || ^8.0.2", + "php": "^8.1", "ext-json": "*", "ext-xml": "*", - "php-http/cache-plugin": "^1.7.5", - "php-http/client-common": "^2.5", - "php-http/discovery": "^1.14", - "php-http/httplug": "^2.2", - "php-http/multipart-stream-builder": "^1.2", - "psr/cache": "^1.0 || ^2.0 || ^3.0", + "php-http/cache-plugin": "^2.0.1", + "php-http/client-common": "^2.7.2", + "php-http/discovery": "^1.20.0", + "php-http/httplug": "^2.4.1", + "php-http/multipart-stream-builder": "^1.4.2", + "psr/cache": "^2.0 || ^3.0", "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0", - "psr/http-message": "^1.0", - "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0", - "symfony/polyfill-php80": "^1.17" + "psr/http-message": "^1.1 || ^2.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "guzzlehttp/guzzle": "^7.4", - "http-interop/http-factory-guzzle": "^1.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "guzzlehttp/guzzle": "^7.9.2" }, "autoload": { "psr-4": { @@ -59,7 +57,14 @@ "config": { "preferred-install": "dist", "allow-plugins": { - "bamarni/composer-bin-plugin": true + "bamarni/composer-bin-plugin": true, + "php-http/discovery": true + } + }, + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false } } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1c3433e2..3ee84310 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,27 +1,104 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#1 \\$callback of function set_error_handler expects \\(callable\\(int, string, string, int, array\\)\\: bool\\)\\|null, Closure\\(\\)\\: void given\\.$#" + message: '#^Parameter \#1 \$callback of function set_error_handler expects \(callable\(int, string, string, int\)\: bool\)\|null, Closure\(\)\: void given\.$#' + identifier: argument.type count: 1 path: src/Api/AbstractApi.php - - message: "#^Parameter \\#2 \\$resource of method Http\\\\Message\\\\MultipartStream\\\\MultipartStreamBuilder\\:\\:addResource\\(\\) expects Psr\\\\Http\\\\Message\\\\StreamInterface\\|resource\\|string, mixed given\\.$#" + message: '#^Parameter \#2 \$resource of method Http\\Message\\MultipartStream\\MultipartStreamBuilder\:\:addResource\(\) expects Psr\\Http\\Message\\StreamInterface\|resource\|string, mixed given\.$#' + identifier: argument.type count: 1 path: src/Api/AbstractApi.php - - message: "#^Property Gitlab\\\\Api\\\\AbstractApi\\:\\:\\$perPage is never written, only read\\.$#" + message: '#^Parameter \#4 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#' + identifier: argument.type count: 1 path: src/Api/AbstractApi.php - - message: "#^Cannot cast mixed to string\\.$#" + message: '#^Property Gitlab\\Api\\AbstractApi\:\:\$perPage \(int\|null\) is never assigned int so it can be removed from the property type\.$#' + identifier: property.unusedType + count: 1 + path: src/Api/AbstractApi.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: src/Api/Groups.php + + - + message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 2 + path: src/Api/Projects.php + + - + message: '#^Parameter \#1 \$array of function array_values expects array\, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Api/Projects.php + + - + message: '#^Parameter \#1 \$options of method Symfony\\Component\\OptionsResolver\\OptionsResolver\:\:resolve\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/Api/Repositories.php + + - + message: '#^Parameter \#1 \$uri of static method Gitlab\\Api\\AbstractApi\:\:encodePath\(\) expects int\|string, mixed given\.$#' + identifier: argument.type + count: 3 + path: src/Api/RepositoryFiles.php + + - + message: '#^Parameter \#1 \$message of static method Gitlab\\HttpClient\\Message\\ResponseMediator\:\:getMessageAsString\(\) expects array, mixed given\.$#' + identifier: argument.type + count: 1 + path: src/HttpClient/Message/ResponseMediator.php + + - + message: '#^Parameter \#3 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null, mixed given\.$#' + identifier: argument.type + count: 2 + path: src/HttpClient/Message/ResponseMediator.php + + - + message: '#^PHPDoc tag @return contains generic type Http\\Promise\\Promise\ but interface Http\\Promise\\Promise is not generic\.$#' + identifier: generics.notGeneric + count: 1 + path: src/HttpClient/Plugin/Authentication.php + + - + message: '#^PHPDoc tag @return contains generic type Http\\Promise\\Promise\ but interface Http\\Promise\\Promise is not generic\.$#' + identifier: generics.notGeneric + count: 1 + path: src/HttpClient/Plugin/ExceptionThrower.php + + - + message: '#^PHPDoc tag @var with type string is not subtype of native type non\-empty\-string\|false\.$#' + identifier: varTag.nativeType + count: 1 + path: src/HttpClient/Util/JsonArray.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string count: 1 path: src/HttpClient/Util/QueryStringBuilder.php - - message: "#^Variable method call on Gitlab\\\\Api\\\\AbstractApi\\.$#" + message: '#^PHPDoc tag @var with type Closure\(Gitlab\\Api\\AbstractApi\)\: Gitlab\\Api\\AbstractApi is not subtype of type Closure\(Gitlab\\Api\\AbstractApi\)\: Gitlab\\Api\\AbstractApi\.$#' + identifier: varTag.type + count: 1 + path: src/ResultPager.php + + - + message: '#^Variable method call on Gitlab\\Api\\AbstractApi\.$#' + identifier: method.dynamicName count: 1 path: src/ResultPager.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 892f32f8..40f6a875 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,21 +2,15 @@ includes: - phpstan-baseline.neon - vendor-bin/phpstan/vendor/phpstan/phpstan-deprecation-rules/rules.neon - vendor-bin/phpstan/vendor/phpstan/phpstan-strict-rules/rules.neon - - vendor-bin/phpstan/vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon - -rules: - - Ergebnis\PHPStan\Rules\Closures\NoNullableReturnTypeDeclarationRule - - Ergebnis\PHPStan\Rules\Expressions\NoCompactRule - - Ergebnis\PHPStan\Rules\Expressions\NoEmptyRule - - Ergebnis\PHPStan\Rules\Expressions\NoEvalRule - - Ergebnis\PHPStan\Rules\Files\DeclareStrictTypesRule - - Ergebnis\PHPStan\Rules\Methods\PrivateInFinalClassRule parameters: level: max - checkMissingIterableValueType: false paths: - src ignoreErrors: - '#Only booleans are allowed in an if condition#' - '#PHPDoc tag \@var above a method has no effect.#' + - '#return type has no value type specified in iterable type array#' + - '#no value type specified in iterable type array#' + - '#expects array\, array given#' + - '#expects array\, array given#' diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 1ba23a0a..b689bdf4 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,29 +1,13 @@ - - - - ./tests - - - - - ./src - - + + + + ./tests + + + + + ./src + + diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 33fdc838..3c19e346 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,14 +1,35 @@ - + - + + + + + + + + + + + + ]]> + + + + + ]]> + - - $clone->perPage + + perPage]]> - - $closure($api) - diff --git a/psalm.xml b/psalm.xml index 6b3b81a1..3dd74b68 100644 --- a/psalm.xml +++ b/psalm.xml @@ -6,6 +6,8 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config%20vendor/vimeo/psalm/config.xsd" errorBaseline="psalm-baseline.xml" + findUnusedBaselineEntry="true" + findUnusedCode="false" > diff --git a/src/Api/AbstractApi.php b/src/Api/AbstractApi.php index 70f899ad..b0219ac4 100644 --- a/src/Api/AbstractApi.php +++ b/src/Api/AbstractApi.php @@ -39,41 +39,31 @@ abstract class AbstractApi private const URI_PREFIX = '/api/v4/'; /** - * The client instance. + * The access levels for groups and projects + * as defined in the Gitlab::Access module. * - * @var Client - */ - private $client; - - /** - * The per page parameter. + * @see https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/access.rb * - * @var int|null + * @var array */ - private $perPage; + protected const ACCESS_LEVELS = [0, 10, 20, 30, 40, 50]; + + private readonly Client $client; + + private ?int $perPage; - /** - * Create a new API instance. - * - * @param Client $client - * - * @return void - */ public function __construct(Client $client) { $this->client = $client; + $this->perPage = null; } /** * Send a GET request with query params and return the raw response. * - * @param string $uri - * @param array $params * @param array $headers * * @throws \Http\Client\Exception - * - * @return \Psr\Http\Message\ResponseInterface */ protected function getAsResponse(string $uri, array $params = [], array $headers = []): ResponseInterface { @@ -85,13 +75,10 @@ protected function getAsResponse(string $uri, array $params = [], array $headers } /** - * @param string $uri * @param array $params * @param array $headers - * - * @return mixed */ - protected function get(string $uri, array $params = [], array $headers = []) + protected function get(string $uri, array $params = [], array $headers = []): mixed { $response = $this->getAsResponse($uri, $params, $headers); @@ -99,14 +86,12 @@ protected function get(string $uri, array $params = [], array $headers = []) } /** - * @param string $uri * @param array $params * @param array $headers * @param array $files - * - * @return mixed + * @param array $uriParams */ - protected function post(string $uri, array $params = [], array $headers = [], array $files = []) + protected function post(string $uri, array $params = [], array $headers = [], array $files = [], array $uriParams = []): mixed { if (0 < \count($files)) { $builder = $this->createMultipartStreamBuilder($params, $files); @@ -120,20 +105,17 @@ protected function post(string $uri, array $params = [], array $headers = [], ar } } - $response = $this->client->getHttpClient()->post(self::prepareUri($uri), $headers, $body); + $response = $this->client->getHttpClient()->post(self::prepareUri($uri, $uriParams), $headers, $body); return ResponseMediator::getContent($response); } /** - * @param string $uri * @param array $params * @param array $headers * @param array $files - * - * @return mixed */ - protected function put(string $uri, array $params = [], array $headers = [], array $files = []) + protected function put(string $uri, array $params = [], array $headers = [], array $files = []): mixed { if (0 < \count($files)) { $builder = $this->createMultipartStreamBuilder($params, $files); @@ -153,13 +135,52 @@ protected function put(string $uri, array $params = [], array $headers = [], arr } /** - * @param string $uri * @param array $params * @param array $headers - * - * @return mixed + * @param array $files + */ + protected function patch(string $uri, array $params = [], array $headers = [], array $files = []): mixed + { + if (0 < \count($files)) { + $builder = $this->createMultipartStreamBuilder($params, $files); + $body = self::prepareMultipartBody($builder); + $headers = self::addMultipartContentType($headers, $builder); + } else { + $body = self::prepareJsonBody($params); + + if (null !== $body) { + $headers = self::addJsonContentType($headers); + } + } + + $response = $this->client->getHttpClient()->patch(self::prepareUri($uri), $headers, $body ?? ''); + + return ResponseMediator::getContent($response); + } + + /** + * @param array $headers + * @param array $uriParams + */ + protected function putFile(string $uri, string $file, array $headers = [], array $uriParams = []): mixed + { + $resource = self::tryFopen($file, 'r'); + $body = $this->client->getStreamFactory()->createStreamFromResource($resource); + + if ($body->isReadable()) { + $headers = \array_merge([ResponseMediator::CONTENT_TYPE_HEADER => self::guessFileContentType($file)], $headers); + } + + $response = $this->client->getHttpClient()->put(self::prepareUri($uri, $uriParams), $headers, $body); + + return ResponseMediator::getContent($response); + } + + /** + * @param array $params + * @param array $headers */ - protected function delete(string $uri, array $params = [], array $headers = []) + protected function delete(string $uri, array $params = [], array $headers = []): mixed { $body = self::prepareJsonBody($params); @@ -172,31 +193,18 @@ protected function delete(string $uri, array $params = [], array $headers = []) return ResponseMediator::getContent($response); } - /** - * @param int|string $uri - * - * @return string - */ - protected static function encodePath($uri): string + protected static function encodePath(int|string $uri): string { return \rawurlencode((string) $uri); } - /** - * @param int|string $id - * @param string $uri - * - * @return string - */ - protected function getProjectPath($id, string $uri): string + protected function getProjectPath(int|string $id, string $uri): string { return 'projects/'.self::encodePath($id).'/'.$uri; } /** * Create a new OptionsResolver with page and per_page options. - * - * @return OptionsResolver */ protected function createOptionsResolver(): OptionsResolver { @@ -219,11 +227,6 @@ protected function createOptionsResolver(): OptionsResolver /** * Prepare the request URI. - * - * @param string $uri - * @param array $query - * - * @return string */ private static function prepareUri(string $uri, array $query = []): string { @@ -239,8 +242,6 @@ private static function prepareUri(string $uri, array $query = []): string * * @param array $params * @param array $files - * - * @return MultipartStreamBuilder */ private function createMultipartStreamBuilder(array $params = [], array $files = []): MultipartStreamBuilder { @@ -264,10 +265,6 @@ private function createMultipartStreamBuilder(array $params = [], array $files = /** * Prepare the request multipart body. - * - * @param MultipartStreamBuilder $builder - * - * @return StreamInterface */ private static function prepareMultipartBody(MultipartStreamBuilder $builder): StreamInterface { @@ -278,7 +275,6 @@ private static function prepareMultipartBody(MultipartStreamBuilder $builder): S * Add the multipart content type to the headers if one is not already present. * * @param array $headers - * @param MultipartStreamBuilder $builder * * @return array */ @@ -293,8 +289,6 @@ private static function addMultipartContentType(array $headers, MultipartStreamB * Prepare the request JSON body. * * @param array $params - * - * @return string|null */ private static function prepareJsonBody(array $params): ?string { @@ -361,10 +355,6 @@ private static function tryFopen(string $filename, string $mode) /** * Guess the content type of the file if possible. - * - * @param string $file - * - * @return string */ private static function guessFileContentType(string $file): string { diff --git a/src/Api/DeployKeys.php b/src/Api/DeployKeys.php index 1a94e576..9259d25c 100644 --- a/src/Api/DeployKeys.php +++ b/src/Api/DeployKeys.php @@ -16,12 +16,7 @@ class DeployKeys extends AbstractApi { - /** - * @param array $parameters - * - * @return mixed - */ - public function all(array $parameters = []) + public function all(array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); diff --git a/src/Api/Deployments.php b/src/Api/Deployments.php index f0fcbcc6..3770bf9d 100644 --- a/src/Api/Deployments.php +++ b/src/Api/Deployments.php @@ -17,17 +17,18 @@ class Deployments extends AbstractApi { /** - * @param int|string $project_id * @param array $parameters { * * @var string $order_by Return deployments ordered by id, iid, created_at, updated_at, * or ref fields (default is id) * @var string $sort Return deployments sorted in asc or desc order (default is desc) + * @var string $status Return deployments filtered by status of deployment allowed + * values of status are 'created', 'running', 'success', 'failed', + * 'canceled', 'blocked' + * @var string $environment Return deployments filtered to a particular environment * } - * - * @return mixed */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('order_by') @@ -36,17 +37,16 @@ public function all($project_id, array $parameters = []) $resolver->setDefined('sort') ->setAllowedTypes('sort', 'string') ->setAllowedValues('sort', ['desc', 'asc']); + $resolver->setDefined('status') + ->setAllowedTypes('status', 'string') + ->setAllowedValues('status', ['created', 'running', 'success', 'failed', 'canceled', 'blocked']); + $resolver->setDefined('environment') + ->setAllowedTypes('environment', 'string'); return $this->get($this->getProjectPath($project_id, 'deployments'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $deployment_id - * - * @return mixed - */ - public function show($project_id, int $deployment_id) + public function show(int|string $project_id, int $deployment_id): mixed { return $this->get($this->getProjectPath($project_id, 'deployments/'.$deployment_id)); } diff --git a/src/Api/Environments.php b/src/Api/Environments.php index 9f01cdf6..b83693a9 100644 --- a/src/Api/Environments.php +++ b/src/Api/Environments.php @@ -18,13 +18,7 @@ class Environments extends AbstractApi { - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('name') @@ -39,16 +33,14 @@ public function all($project_id, array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $name The name of the environment * @var string $external_url Place to link to for this environment + * @var string $tier The tier of the new environment. Allowed values are production, staging, testing, development, and other. * } - * - * @return mixed */ - public function create($project_id, array $parameters = []) + public function create(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setDefined('name') @@ -56,39 +48,23 @@ public function create($project_id, array $parameters = []) ->setAllowedTypes('name', 'string'); $resolver->setDefined('external_url') ->setAllowedTypes('external_url', 'string'); + $resolver->setDefined('tier') + ->setAllowedValues('tier', ['production', 'staging', 'testing', 'development', 'other']); return $this->post($this->getProjectPath($project_id, 'environments'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $environment_id - * - * @return mixed - */ - public function remove($project_id, int $environment_id) + public function remove(int|string $project_id, int $environment_id): mixed { return $this->delete($this->getProjectPath($project_id, 'environments/'.$environment_id)); } - /** - * @param int|string $project_id - * @param int $environment_id - * - * @return mixed - */ - public function stop($project_id, int $environment_id) + public function stop(int|string $project_id, int $environment_id): mixed { return $this->post($this->getProjectPath($project_id, 'environments/'.self::encodePath($environment_id).'/stop')); } - /** - * @param int|string $project_id - * @param int $environment_id - * - * @return mixed - */ - public function show($project_id, int $environment_id) + public function show(int|string $project_id, int $environment_id): mixed { return $this->get($this->getProjectPath($project_id, 'environments/'.self::encodePath($environment_id))); } diff --git a/src/Api/Events.php b/src/Api/Events.php new file mode 100644 index 00000000..74f3d1cd --- /dev/null +++ b/src/Api/Events.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +use Symfony\Component\OptionsResolver\Options; + +class Events extends AbstractApi +{ + /** + * @param array $parameters { + * + * @var string $action include only events of a particular action type + * @var string $target_type include only events of a particular target type + * @var \DateTimeInterface $before include only events created before a particular date + * @var \DateTimeInterface $after include only events created after a particular date + * @var string $scope include all events across a user’s projects + * @var string $sort sort events in asc or desc order by created_at + * + * } + */ + public function all(array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('Y-m-d'); + }; + + $resolver->setDefined('action'); + $resolver->setDefined('target_type'); + $resolver->setDefined('before') + ->setAllowedTypes('before', \DateTimeInterface::class) + ->setNormalizer('before', $datetimeNormalizer) + ; + $resolver->setDefined('after') + ->setAllowedTypes('after', \DateTimeInterface::class) + ->setNormalizer('after', $datetimeNormalizer) + ; + $resolver->setDefined('scope'); + $resolver->setDefined('sort'); + + return $this->get('events', $resolver->resolve($parameters)); + } +} diff --git a/src/Api/Groups.php b/src/Api/Groups.php index ad45e73a..7104d345 100644 --- a/src/Api/Groups.php +++ b/src/Api/Groups.php @@ -14,11 +14,38 @@ namespace Gitlab\Api; +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; +use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; class Groups extends AbstractApi { + /** + * @var string + */ + public const STATE_ALL = 'all'; + + /** + * @var string + */ + public const STATE_MERGED = 'merged'; + + /** + * @var string + */ + public const STATE_OPENED = 'opened'; + + /** + * @var string + */ + public const STATE_CLOSED = 'closed'; + + /** + * @var string + */ + public const STATE_LOCKED = 'locked'; + /** * @param array $parameters { * @@ -32,39 +59,20 @@ class Groups extends AbstractApi * @var int $min_access_level limit by groups in which the current user has at least this access level * @var bool $top_level_only limit to top level groups, excluding all subgroups * } - * - * @return mixed */ - public function all(array $parameters = []) + public function all(array $parameters = []): mixed { $resolver = $this->getGroupSearchResolver(); return $this->get('groups', $resolver->resolve($parameters)); } - /** - * @param int|string $id - * - * @return mixed - */ - public function show($id) + public function show(int|string $id): mixed { return $this->get('groups/'.self::encodePath($id)); } - /** - * @param string $name - * @param string $path - * @param string $description - * @param string $visibility - * @param bool $lfs_enabled - * @param bool $request_access_enabled - * @param int $parent_id - * @param int $shared_runners_minutes_limit - * - * @return mixed - */ - public function create(string $name, string $path, string $description = null, string $visibility = 'private', bool $lfs_enabled = null, bool $request_access_enabled = null, int $parent_id = null, int $shared_runners_minutes_limit = null) + public function create(string $name, string $path, ?string $description = null, string $visibility = 'private', ?bool $lfs_enabled = null, ?bool $request_access_enabled = null, ?int $parent_id = null, ?int $shared_runners_minutes_limit = null): mixed { $params = [ 'name' => $name, @@ -82,45 +90,22 @@ public function create(string $name, string $path, string $description = null, s })); } - /** - * @param int|string $id - * @param array $params - * - * @return mixed - */ - public function update($id, array $params) + public function update(int|string $id, array $params): mixed { return $this->put('groups/'.self::encodePath($id), $params); } - /** - * @param int|string $group_id - * - * @return mixed - */ - public function remove($group_id) + public function remove(int|string $group_id): mixed { return $this->delete('groups/'.self::encodePath($group_id)); } - /** - * @param int|string $group_id - * @param int|string $project_id - * - * @return mixed - */ - public function transfer($group_id, $project_id) + public function transfer(int|string $group_id, int|string $project_id): mixed { return $this->post('groups/'.self::encodePath($group_id).'/projects/'.self::encodePath($project_id)); } - /** - * @param int|string $group_id - * @param array $parameters - * - * @return mixed - */ - public function allMembers($group_id, array $parameters = []) + public function allMembers(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('query'); @@ -135,15 +120,12 @@ public function allMembers($group_id, array $parameters = []) } /** - * @param int|string $group_id * @param array $parameters { * * @var string $query A query string to search for members. * } - * - * @return mixed */ - public function members($group_id, array $parameters = []) + public function members(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('query'); @@ -157,51 +139,37 @@ public function members($group_id, array $parameters = []) return $this->get('groups/'.self::encodePath($group_id).'/members', $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param int $user_id - * - * @return mixed - */ - public function member($group_id, int $user_id) + public function member(int|string $group_id, int $user_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/members/'.self::encodePath($user_id)); } - /** - * @param int|string $group_id - * @param int $user_id - * - * @return mixed - */ - public function allMember($group_id, int $user_id) + public function allMember(int|string $group_id, int $user_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/members/all/'.self::encodePath($user_id)); } - /** - * @param int|string $group_id - * @param int $user_id - * @param int $access_level - * - * @return mixed - */ - public function addMember($group_id, int $user_id, int $access_level) + public function addMember(int|string $group_id, int $user_id, int $access_level, array $parameters = []): mixed { - return $this->post('groups/'.self::encodePath($group_id).'/members', [ + $dateNormalizer = function (OptionsResolver $optionsResolver, \DateTimeInterface $date): string { + return $date->format('Y-m-d'); + }; + + $resolver = $this->createOptionsResolver() + ->setDefined('expires_at') + ->setAllowedTypes('expires_at', \DateTimeInterface::class) + ->setNormalizer('expires_at', $dateNormalizer) + ; + + $parameters = \array_merge([ 'user_id' => $user_id, 'access_level' => $access_level, - ]); + ], $resolver->resolve($parameters)); + + return $this->post('groups/'.self::encodePath($group_id).'/members', $parameters); } - /** - * @param int|string $group_id - * @param int $user_id - * @param int $access_level - * - * @return mixed - */ - public function saveMember($group_id, int $user_id, int $access_level) + public function saveMember(int|string $group_id, int $user_id, int $access_level): mixed { return $this->put('groups/'.self::encodePath($group_id).'/members/'.self::encodePath($user_id), [ 'access_level' => $access_level, @@ -209,16 +177,13 @@ public function saveMember($group_id, int $user_id, int $access_level) } /** - * @param int|string $group_id * @param array $parameters { * * @var int $group_access the access level to grant the group * @var string $expires_at share expiration date in ISO 8601 format: 2016-09-26 * } - * - * @return mixed */ - public function addShare($group_id, array $parameters = []) + public function addShare(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -241,19 +206,12 @@ public function addShare($group_id, array $parameters = []) return $this->post('groups/'.self::encodePath($group_id).'/share', $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param int $user_id - * - * @return mixed - */ - public function removeMember($group_id, int $user_id) + public function removeMember(int|string $group_id, int $user_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/members/'.self::encodePath($user_id)); } /** - * @param int|string $id * @param array $parameters { * * @var bool $archived limit by archived status @@ -271,10 +229,8 @@ public function removeMember($group_id, int $user_id) * @var bool $include_subgroups Include projects in subgroups of this group (default is false) * @var bool $with_custom_attributes Include custom attributes in response (admins only). * } - * - * @return mixed */ - public function projects($id, array $parameters = []) + public function projects(int|string $id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -332,7 +288,6 @@ public function projects($id, array $parameters = []) } /** - * @param int|string $group_id * @param array $parameters { * * @var int[] $skip_groups skip the group IDs passes @@ -343,10 +298,8 @@ public function projects($id, array $parameters = []) * @var bool $statistics include group statistics (admins only) * @var bool $owned Limit by groups owned by the current user. * } - * - * @return mixed */ - public function subgroups($group_id, array $parameters = []) + public function subgroups(int|string $group_id, array $parameters = []): mixed { $resolver = $this->getSubgroupSearchResolver(); @@ -354,90 +307,182 @@ public function subgroups($group_id, array $parameters = []) } /** - * @param int|string $group_id - * @param array $parameters + * @param array $parameters { * - * @return mixed + * @var string $assignee_id Return issues assigned to the given user id. Mutually exclusive with assignee_username. + * None returns unassigned issues. Any returns issues with an assignee. + * @var string $assignee_username Return issues assigned to the given username. Similar to assignee_id and mutually exclusive with assignee_id. + * In GitLab CE, the assignee_username array should only contain a single value. Otherwise, an invalid parameter error is returned. + * @var int $author_id Return issues created by the given user id. Mutually exclusive with author_username. + * Combine with scope=all or scope=assigned_to_me. + * @var string $author_username Return issues created by the given username. Similar to author_id and mutually exclusive with author_id. + * @var bool $confidential Filter confidential or public issues + * @var \DateTimeInterface $created_after Return issues created after the given time (inclusive) + * @var \DateTimeInterface $created_before Return issues created before the given time (inclusive) + * @var int $iteration_id Return issues assigned to the given iteration ID. None returns issues that do not belong to an iteration. Any returns issues that belong to an iteration. Mutually exclusive with iteration_title. + * @var string $iteration_title Return issues assigned to the iteration with the given title. Similar to iteration_id and mutually exclusive with iteration_id. + * @var string $labels Comma-separated list of label names, issues must have all labels to be returned. None lists all issues with no labels. Any lists all issues with at least one label. No+Label (Deprecated) lists all issues with no labels. Predefined names are case-insensitive. + * @var string $milestone The milestone title. None lists all issues with no milestone. Any lists all issues that have an assigned milestone. + * @var string $my_reaction_emoji Return issues reacted by the authenticated user by the given emoji. None returns issues not given a reaction. Any returns issues given at least one reaction. + * @var bool $non_archived Return issues from non archived projects. Default is true. + * @var string $not Return issues that do not match the parameters supplied. Accepts: labels, milestone, author_id, author_username, assignee_id, assignee_username, my_reaction_emoji, search, in + * @var string $order_by Return issues ordered by created_at, updated_at, priority, due_date, relative_position, label_priority, milestone_due, popularity, weight fields. Default is created_at + * @var string $scope Return issues for the given scope: created_by_me, assigned_to_me or all. Defaults to all. + * @var string $search Search group issues against their title and description + * @var string $sort Return issues sorted in asc or desc order. Default is desc + * @var string $state Return all issues or just those that are opened or closed + * @var \DateTimeInterface $updated_after Return issues updated on or after the given time. Expected in ISO 8601 format (2019-03-15T08:00:00Z) + * @var \DateTimeInterface $updated_before Return issues updated on or before the given time. Expected in ISO 8601 format (2019-03-15T08:00:00Z) + * @var int $weight Return issues with the specified weight. None returns issues with no weight assigned. Any returns issues with a weight assigned. + * @var bool $with_labels_details If true, the response returns more details for each label in labels field: :name, :color, :description, :description_html, :text_color. Default is false. + * } */ - public function labels($group_id, array $parameters = []) + public function issues(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; - return $this->get('groups/'.self::encodePath($group_id).'/labels', $resolver->resolve($parameters)); + $resolver->setDefined('assignee_id'); + $resolver->setDefined('assignee_username') + ->setAllowedTypes('assignee_username', 'string'); + + $resolver->setDefined('author_id'); + $resolver->setDefined('author_username') + ->setAllowedTypes('author_username', 'string'); + + $resolver->setDefined('confidential') + ->setAllowedTypes('confidential', 'bool') + ->setNormalizer('confidential', $booleanNormalizer); + + $resolver->setDefined('created_after') + ->setAllowedTypes('created_after', \DateTimeInterface::class) + ->setNormalizer('created_after', $datetimeNormalizer); + $resolver->setDefined('created_before') + ->setAllowedTypes('created_before', \DateTimeInterface::class) + ->setNormalizer('created_before', $datetimeNormalizer); + + $resolver->setDefined('updated_after') + ->setAllowedTypes('updated_after', \DateTimeInterface::class) + ->setNormalizer('updated_after', $datetimeNormalizer); + $resolver->setDefined('updated_before') + ->setAllowedTypes('updated_before', \DateTimeInterface::class) + ->setNormalizer('updated_before', $datetimeNormalizer); + + $resolver->setDefined('iteration_id'); + $resolver->setDefined('iteration_title') + ->setAllowedTypes('iteration_title', 'string'); + + $resolver->setDefined('labels') + ->setAllowedTypes('labels', 'string'); + + $resolver->setDefined('milestone') + ->setAllowedTypes('milestone', 'string'); + + $resolver->setDefined('my_reaction_emoji') + ->setAllowedTypes('my_reaction_emoji', 'string'); + + $resolver->setDefined('non_archived') + ->setAllowedTypes('non_archived', 'bool') + ->setNormalizer('non_archived', $booleanNormalizer); + + $resolver->setDefined('not') + ->setAllowedTypes('not', 'string'); + + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at', 'updated_at']); + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']); + + $resolver->setDefined('scope') + ->setAllowedTypes('scope', 'string'); + + $resolver->setDefined('search') + ->setAllowedTypes('search', 'string'); + + $resolver->setDefined('state') + ->setAllowedValues('state', [self::STATE_ALL, self::STATE_OPENED, self::STATE_CLOSED]); + + $resolver->setDefined('weight'); + + $resolver->setDefined('with_labels_details') + ->setAllowedTypes('with_labels_details', 'bool') + ->setNormalizer('with_labels_details', $booleanNormalizer); + + return $this->get('groups/'.self::encodePath($group_id).'/issues', $resolver->resolve($parameters)); } /** - * @param int|string $group_id - * @param array $params + * @param array $parameters { * - * @return mixed + * @var bool $with_counts Whether or not to include issue and merge request counts. Defaults to false. + * @var bool $include_ancestor_groups Include ancestor groups. Defaults to true. + * @var bool $include_descendant_groups Include descendant groups. Defaults to false. + * @var bool $only_group_labels Toggle to include only group labels or also project labels. Defaults to true. + * @var string $search Keyword to filter labels by. + * } */ - public function addLabel($group_id, array $params) + public function labels(int|string $group_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + + $resolver->setDefined('with_counts') + ->setAllowedTypes('with_counts', 'bool'); + + $resolver->setDefined('include_ancestor_groups') + ->setAllowedTypes('include_ancestor_groups', 'bool'); + + $resolver->setDefined('include_descendant_groups') + ->setAllowedTypes('include_descendant_groups', 'bool'); + + $resolver->setDefined('only_group_labels') + ->setAllowedTypes('only_group_labels', 'bool'); + + $resolver->setDefined('search') + ->setAllowedTypes('search', 'string'); + + return $this->get('groups/'.self::encodePath($group_id).'/labels', $resolver->resolve($parameters)); + } + + public function addLabel(int|string $group_id, array $params): mixed { return $this->post('groups/'.self::encodePath($group_id).'/labels', $params); } - /** - * @param int|string $group_id - * @param int $label_id - * @param array $params - * - * @return mixed - */ - public function updateLabel($group_id, int $label_id, array $params) + public function updateLabel(int|string $group_id, int $label_id, array $params): mixed { return $this->put('groups/'.self::encodePath($group_id).'/labels/'.self::encodePath($label_id), $params); } - /** - * @param int|string $group_id - * @param int $label_id - * - * @return mixed - */ - public function removeLabel($group_id, int $label_id) + public function removeLabel(int|string $group_id, int $label_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/labels/'.self::encodePath($label_id)); } - /** - * @param int|string $group_id - * @param array $parameters - * - * @return mixed - */ - public function variables($group_id, array $parameters = []) + public function variables(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); return $this->get('groups/'.self::encodePath($group_id).'/variables', $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param string $key - * - * @return mixed - */ - public function variable($group_id, string $key) + public function variable(int|string $group_id, string $key): mixed { return $this->get('groups/'.self::encodePath($group_id).'/variables/'.self::encodePath($key)); } /** - * @param int|string $group_id - * @param string $key - * @param string $value - * @param bool|null $protected * @param array $parameters { * * @var string $masked true or false * @var string $variable_type env_var (default) or file * } - * - * @return mixed */ - public function addVariable($group_id, string $key, string $value, ?bool $protected = null, array $parameters = []) + public function addVariable(int|string $group_id, string $key, string $value, ?bool $protected = null, array $parameters = []): mixed { $payload = [ 'key' => $key, @@ -459,15 +504,7 @@ public function addVariable($group_id, string $key, string $value, ?bool $protec return $this->post('groups/'.self::encodePath($group_id).'/variables', $payload); } - /** - * @param int|string $group_id - * @param string $key - * @param string $value - * @param bool|null $protected - * - * @return mixed - */ - public function updateVariable($group_id, string $key, string $value, ?bool $protected = null) + public function updateVariable(int|string $group_id, string $key, string $value, ?bool $protected = null): mixed { $payload = [ 'value' => $value, @@ -480,19 +517,139 @@ public function updateVariable($group_id, string $key, string $value, ?bool $pro return $this->put('groups/'.self::encodePath($group_id).'/variables/'.self::encodePath($key), $payload); } + public function removeVariable(int|string $group_id, string $key): mixed + { + return $this->delete('groups/'.self::encodePath($group_id).'/variables/'.self::encodePath($key)); + } + /** - * @param int|string $group_id - * @param string $key + * @param array $parameters { * - * @return mixed + * @var int[] $iids return the request having the given iid + * @var string $state return all merge requests or just those that are opened, closed, or + * merged + * @var string $scope Return merge requests for the given scope: created-by-me, + * assigned-to-me or all (default is created-by-me) + * @var string $order_by return requests ordered by created_at or updated_at fields (default is created_at) + * @var string $sort return requests sorted in asc or desc order (default is desc) + * @var string $milestone return merge requests for a specific milestone + * @var string $view if simple, returns the iid, URL, title, description, and basic state of merge request + * @var string $labels return merge requests matching a comma separated list of labels + * @var \DateTimeInterface $created_after return merge requests created after the given time (inclusive) + * @var \DateTimeInterface $created_before return merge requests created before the given time (inclusive) + * } */ - public function removeVariable($group_id, string $key) + public function mergeRequests(int|string $group_id, array $parameters = []): mixed { - return $this->delete('groups/'.self::encodePath($group_id).'/variables/'.self::encodePath($key)); + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; + $resolver->setDefined('state') + ->setAllowedValues('state', [self::STATE_ALL, self::STATE_MERGED, self::STATE_OPENED, self::STATE_CLOSED]) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at', 'updated_at']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('milestone'); + $resolver->setDefined('view') + ->setAllowedValues('view', ['simple']) + ; + $resolver->setDefined('labels'); + $resolver->setDefined('with_labels_details') + ->setAllowedTypes('with_labels_details', 'bool') + ; + + $resolver->setDefined('created_after') + ->setAllowedTypes('created_after', \DateTimeInterface::class) + ->setNormalizer('created_after', $datetimeNormalizer) + ; + $resolver->setDefined('created_before') + ->setAllowedTypes('created_before', \DateTimeInterface::class) + ->setNormalizer('created_before', $datetimeNormalizer) + ; + + $resolver->setDefined('updated_after') + ->setAllowedTypes('updated_after', \DateTimeInterface::class) + ->setNormalizer('updated_after', $datetimeNormalizer) + ; + $resolver->setDefined('updated_before') + ->setAllowedTypes('updated_before', \DateTimeInterface::class) + ->setNormalizer('updated_before', $datetimeNormalizer) + ; + + $resolver->setDefined('scope') + ->setAllowedValues('scope', ['created_by_me', 'assigned_to_me', 'all']) + ; + $resolver->setDefined('author_id') + ->setAllowedTypes('author_id', 'integer'); + $resolver->setDefined('author_username'); + + $resolver->setDefined('assignee_id') + ->setAllowedTypes('assignee_id', 'integer'); + + $resolver->setDefined('approver_ids') + ->setAllowedTypes('approver_ids', 'array') + ->setAllowedValues('approver_ids', function (array $value) { + return \count($value) === \count(\array_filter($value, 'is_int')); + }) + ; + $resolver->setDefined('non_archived') + ->setAllowedTypes('non_archived', 'bool') + ; + $resolver->setDefined('reviewer_id') + ->setAllowedTypes('reviewer_id', 'integer'); + $resolver->setDefined('reviewer_username'); + $resolver->setDefined('my_reaction_emoji'); + + $resolver->setDefined('search'); + $resolver->setDefined('source_branch'); + $resolver->setDefined('target_branch'); + $resolver->setDefined('with_merge_status_recheck') + ->setAllowedTypes('with_merge_status_recheck', 'bool') + ; + $resolver->setDefined('approved_by_ids') + ->setAllowedTypes('approved_by_ids', 'array') + ->setAllowedValues('approved_by_ids', function (array $value) { + return \count($value) === \count(\array_filter($value, 'is_int')); + }) + ; + + return $this->get('groups/'.self::encodePath($group_id).'/merge_requests', $resolver->resolve($parameters)); + } + + /** + * @param array $parameters { + * + * @var string $state Return opened, upcoming, current (previously started), closed, or all iterations. + * Filtering by started state is deprecated starting with 14.1, please use current instead. + * @var string $search return only iterations with a title matching the provided string + * @var bool $include_ancestors Include iterations from parent group and its ancestors. Defaults to true. + * } + */ + public function iterations(int|string $group_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'upcoming', 'current', 'current (previously started)', 'closed', 'all']) + ; + $resolver->setDefined('include_ancestors') + ->setAllowedTypes('include_ancestors', 'bool') + ->setNormalizer('include_ancestors', $booleanNormalizer) + ->setDefault('include_ancestors', true) + ; + + return $this->get('groups/'.self::encodePath($group_id).'/iterations', $resolver->resolve($parameters)); } /** - * @param int|string $group_id * @param array $parameters { * * @var bool $exclude_subgroups if the parameter is included as true, packages from projects from subgroups @@ -508,10 +665,8 @@ public function removeVariable($group_id, string $key) * @var string $status filter the returned packages by status. one of default (default), * hidden, or processing. * } - * - * @return mixed */ - public function packages($group_id, array $parameters = []) + public function packages(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -543,10 +698,7 @@ public function packages($group_id, array $parameters = []) return $this->get('groups/'.self::encodePath($group_id).'/packages', $resolver->resolve($parameters)); } - /** - * @return OptionsResolver - */ - private function getGroupSearchResolver() + private function getGroupSearchResolver(): OptionsResolver { $resolver = $this->getSubgroupSearchResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -561,10 +713,7 @@ private function getGroupSearchResolver() return $resolver; } - /** - * @return OptionsResolver - */ - private function getSubgroupSearchResolver() + private function getSubgroupSearchResolver(): OptionsResolver { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -602,4 +751,107 @@ private function getSubgroupSearchResolver() return $resolver; } + + public function deployTokens(int|string $group_id, ?bool $active = null): mixed + { + return $this->get('groups/'.self::encodePath($group_id).'/deploy_tokens', (null !== $active) ? ['active' => $active] : []); + } + + /** + * @param array $parameters { + * + * @var string $name the name of the deploy token + * @var \DateTimeInterface $expires_at expiration date for the deploy token, does not expire if no value is provided + * @var string $username the username for the deploy token + * @var array $scopes the scopes, one or many of: read_repository, read_registry, write_registry, read_package_registry, write_package_registry + * } + */ + public function createDeployToken(int|string $group_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; + + $resolver->define('name') + ->required() + ; + + $resolver->define('scopes') + ->required() + ->allowedTypes('array') + ->allowedValues(function ($scopes) { + $allowed = ['read_repository', 'read_registry', 'write_registry', 'read_package_registry', 'write_package_registry']; + foreach ($scopes as $scope) { + if (!\in_array($scope, $allowed, true)) { + return false; + } + } + + return true; + }) + ; + $resolver->setDefined('username') + ->setAllowedTypes('username', 'string') + ; + + $resolver->setDefined('expires_at') + ->setAllowedTypes('expires_at', \DateTimeInterface::class) + ->setNormalizer('expires_at', $datetimeNormalizer) + ; + + return $this->post('groups/'.self::encodePath($group_id).'/deploy_tokens', $resolver->resolve($parameters)); + } + + public function deleteDeployToken(int|string $group_id, int $token_id): mixed + { + return $this->delete('groups/'.self::encodePath($group_id).'/deploy_tokens/'.self::encodePath($token_id)); + } + + /** + * @param array $parameters { + * + * @var string $scope The scope to search in + * @var string $search The search query + * @var string $state Filter by state. Issues and merge requests are supported; it is ignored for other scopes. + * @var bool $confidential Filter by confidentiality. Issues scope is supported; it is ignored for other scopes. + * @var string $order_by Allowed values are created_at only. If this is not set, the results are either sorted by created_at in descending order for basic search, or by the most relevant documents when using advanced search. + * @var string $sort Return projects sorted in asc or desc order (default is desc) + * } + * + * @throws UndefinedOptionsException If an option name is undefined + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules + */ + public function search(int|string $id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $resolver->setDefined('confidential') + ->setAllowedTypes('confidential', 'bool') + ->setNormalizer('confidential', $booleanNormalizer); + $scope = [ + 'issues', + 'merge_requests', + 'milestones', + 'projects', + 'users', + 'blobs', + 'commits', + 'notes', + 'wiki_blobs', + ]; + $resolver->setRequired('scope') + ->setAllowedValues('scope', $scope); + $resolver->setRequired('search'); + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at']); + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']); + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'closed']); + + return $this->get('groups/'.self::encodePath($id).'/search', $resolver->resolve($parameters)); + } } diff --git a/src/Api/GroupsBoards.php b/src/Api/GroupsBoards.php index 4a6b5232..a3fa6742 100644 --- a/src/Api/GroupsBoards.php +++ b/src/Api/GroupsBoards.php @@ -16,13 +16,7 @@ class GroupsBoards extends AbstractApi { - /** - * @param int|string|null $group_id - * @param array $parameters - * - * @return mixed - */ - public function all($group_id = null, array $parameters = []) + public function all(int|string|null $group_id = null, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -31,82 +25,37 @@ public function all($group_id = null, array $parameters = []) return $this->get($path, $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param int $board_id - * - * @return mixed - */ - public function show($group_id, int $board_id) + public function show(int|string $group_id, int $board_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id)); } - /** - * @param int|string $group_id - * @param array $params - * - * @return mixed - */ - public function create($group_id, array $params) + public function create(int|string $group_id, array $params): mixed { return $this->post('groups/'.self::encodePath($group_id).'/boards', $params); } - /** - * @param int|string $group_id - * @param int $board_id - * @param array $params - * - * @return mixed - */ - public function update($group_id, int $board_id, array $params) + public function update(int|string $group_id, int $board_id, array $params): mixed { return $this->put('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id), $params); } - /** - * @param int|string $group_id - * @param int $board_id - * - * @return mixed - */ - public function remove($group_id, int $board_id) + public function remove(int|string $group_id, int $board_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id)); } - /** - * @param int|string $group_id - * @param int $board_id - * - * @return mixed - */ - public function allLists($group_id, int $board_id) + public function allLists(int|string $group_id, int $board_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id).'/lists'); } - /** - * @param int|string $group_id - * @param int $board_id - * @param int $list_id - * - * @return mixed - */ - public function showList($group_id, int $board_id, int $list_id) + public function showList(int|string $group_id, int $board_id, int $list_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id)); } - /** - * @param int|string $group_id - * @param int $board_id - * @param int $label_id - * - * @return mixed - */ - public function createList($group_id, int $board_id, int $label_id) + public function createList(int|string $group_id, int $board_id, int $label_id): mixed { $params = [ 'label_id' => $label_id, @@ -115,15 +64,7 @@ public function createList($group_id, int $board_id, int $label_id) return $this->post('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id).'/lists', $params); } - /** - * @param int|string $group_id - * @param int $board_id - * @param int $list_id - * @param int $position - * - * @return mixed - */ - public function updateList($group_id, int $board_id, int $list_id, int $position) + public function updateList(int|string $group_id, int $board_id, int $list_id, int $position): mixed { $params = [ 'position' => $position, @@ -132,14 +73,7 @@ public function updateList($group_id, int $board_id, int $list_id, int $position return $this->put('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id), $params); } - /** - * @param int|string $group_id - * @param int $board_id - * @param int $list_id - * - * @return mixed - */ - public function deleteList($group_id, int $board_id, int $list_id) + public function deleteList(int|string $group_id, int $board_id, int $list_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id)); } diff --git a/src/Api/GroupsEpics.php b/src/Api/GroupsEpics.php index e66e9730..603aef6e 100644 --- a/src/Api/GroupsEpics.php +++ b/src/Api/GroupsEpics.php @@ -19,7 +19,12 @@ class GroupsEpics extends AbstractApi /** * @var string */ - public const STATE_ACTIVE = 'active'; + public const STATE_ALL = 'all'; + + /** + * @var string + */ + public const STATE_OPENED = 'opened'; /** * @var string @@ -27,17 +32,14 @@ class GroupsEpics extends AbstractApi public const STATE_CLOSED = 'closed'; /** - * @param int|string $group_id * @param array $parameters { * * @var int[] $iids return only the epics having the given iids * @var string $state return only active or closed epics * @var string $search Return only epics with a title or description matching the provided string. * } - * - * @return mixed */ - public function all($group_id, array $parameters = []) + public function all(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('iids') @@ -47,55 +49,35 @@ public function all($group_id, array $parameters = []) }) ; $resolver->setDefined('state') - ->setAllowedValues('state', [self::STATE_ACTIVE, self::STATE_CLOSED]) + ->setAllowedValues('state', [self::STATE_ALL, self::STATE_OPENED, self::STATE_CLOSED]) ; $resolver->setDefined('search'); return $this->get('groups/'.self::encodePath($group_id).'/epics', $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param int $epic_id - * - * @return mixed - */ - public function show($group_id, int $epic_id) + public function show(int|string $group_id, int $epic_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/epics/'.self::encodePath($epic_id)); } - /** - * @param int|string $group_id - * @param array $params - * - * @return mixed - */ - public function create($group_id, array $params) + public function create(int|string $group_id, array $params): mixed { return $this->post('groups/'.self::encodePath($group_id).'/epics', $params); } - /** - * @param int|string $group_id - * @param int $epic_id - * @param array $params - * - * @return mixed - */ - public function update($group_id, int $epic_id, array $params) + public function update(int|string $group_id, int $epic_id, array $params): mixed { return $this->put('groups/'.self::encodePath($group_id).'/epics/'.self::encodePath($epic_id), $params); } - /** - * @param int|string $group_id - * @param int $epic_id - * - * @return mixed - */ - public function remove($group_id, int $epic_id) + public function remove(int|string $group_id, int $epic_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/epics/'.self::encodePath($epic_id)); } + + public function issues(int|string $group_id, int $epic_iid): mixed + { + return $this->get('groups/'.self::encodePath($group_id).'/epics/'.self::encodePath($epic_iid).'/issues'); + } } diff --git a/src/Api/GroupsMilestones.php b/src/Api/GroupsMilestones.php index f870f78c..50fac667 100644 --- a/src/Api/GroupsMilestones.php +++ b/src/Api/GroupsMilestones.php @@ -14,6 +14,8 @@ namespace Gitlab\Api; +use Symfony\Component\OptionsResolver\Options; + class GroupsMilestones extends AbstractApi { /** @@ -27,19 +29,23 @@ class GroupsMilestones extends AbstractApi public const STATE_CLOSED = 'closed'; /** - * @param int|string $group_id * @param array $parameters { * * @var int[] $iids return only the milestones having the given iids * @var string $state return only active or closed milestones - * @var string $search Return only milestones with a title or description matching the provided string. + * @var string $search Return only milestones with a title or description matching the provided string + * @var \DateTimeInterface $updated_after Return only milestones updated on or after the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z) + * @var \DateTimeInterface $updated_before Return only milestones updated on or before the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z) * } - * - * @return mixed */ - public function all($group_id, array $parameters = []) + public function all(int|string $group_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + $utc = (new \DateTimeImmutable($value->format(\DateTimeImmutable::RFC3339_EXTENDED)))->setTimezone(new \DateTimeZone('UTC')); + + return $utc->format('Y-m-d\TH:i:s.v\Z'); + }; $resolver->setDefined('iids') ->setAllowedTypes('iids', 'array') ->setAllowedValues('iids', function (array $value) { @@ -51,72 +57,42 @@ public function all($group_id, array $parameters = []) ; $resolver->setDefined('search'); + $resolver->setDefined('updated_after') + ->setAllowedTypes('updated_after', \DateTimeInterface::class) + ->setNormalizer('updated_after', $datetimeNormalizer); + $resolver->setDefined('updated_before') + ->setAllowedTypes('updated_before', \DateTimeInterface::class) + ->setNormalizer('updated_before', $datetimeNormalizer); + return $this->get('groups/'.self::encodePath($group_id).'/milestones', $resolver->resolve($parameters)); } - /** - * @param int|string $group_id - * @param int $milestone_id - * - * @return mixed - */ - public function show($group_id, int $milestone_id) + public function show(int|string $group_id, int $milestone_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/milestones/'.self::encodePath($milestone_id)); } - /** - * @param int|string $group_id - * @param array $params - * - * @return mixed - */ - public function create($group_id, array $params) + public function create(int|string $group_id, array $params): mixed { return $this->post('groups/'.self::encodePath($group_id).'/milestones', $params); } - /** - * @param int|string $group_id - * @param int $milestone_id - * @param array $params - * - * @return mixed - */ - public function update($group_id, int $milestone_id, array $params) + public function update(int|string $group_id, int $milestone_id, array $params): mixed { return $this->put('groups/'.self::encodePath($group_id).'/milestones/'.self::encodePath($milestone_id), $params); } - /** - * @param int|string $group_id - * @param int $milestone_id - * - * @return mixed - */ - public function remove($group_id, int $milestone_id) + public function remove(int|string $group_id, int $milestone_id): mixed { return $this->delete('groups/'.self::encodePath($group_id).'/milestones/'.self::encodePath($milestone_id)); } - /** - * @param int|string $group_id - * @param int $milestone_id - * - * @return mixed - */ - public function issues($group_id, int $milestone_id) + public function issues(int|string $group_id, int $milestone_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/milestones/'.self::encodePath($milestone_id).'/issues'); } - /** - * @param int|string $group_id - * @param int $milestone_id - * - * @return mixed - */ - public function mergeRequests($group_id, int $milestone_id) + public function mergeRequests(int|string $group_id, int $milestone_id): mixed { return $this->get('groups/'.self::encodePath($group_id).'/milestones/'.self::encodePath($milestone_id).'/merge_requests'); } diff --git a/src/Api/IssueBoards.php b/src/Api/IssueBoards.php index d6325a52..369de96f 100644 --- a/src/Api/IssueBoards.php +++ b/src/Api/IssueBoards.php @@ -16,13 +16,7 @@ class IssueBoards extends AbstractApi { - /** - * @param int|string|null $project_id - * @param array $parameters - * - * @return mixed - */ - public function all($project_id = null, array $parameters = []) + public function all(int|string|null $project_id = null, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -31,82 +25,37 @@ public function all($project_id = null, array $parameters = []) return $this->get($path, $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $board_id - * - * @return mixed - */ - public function show($project_id, int $board_id) + public function show(int|string $project_id, int $board_id): mixed { return $this->get($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id))); } - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function create($project_id, array $params) + public function create(int|string $project_id, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'boards'), $params); } - /** - * @param int|string $project_id - * @param int $board_id - * @param array $params - * - * @return mixed - */ - public function update($project_id, int $board_id, array $params) + public function update(int|string $project_id, int $board_id, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id)), $params); } - /** - * @param int|string $project_id - * @param int $board_id - * - * @return mixed - */ - public function remove($project_id, int $board_id) + public function remove(int|string $project_id, int $board_id): mixed { return $this->delete($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id))); } - /** - * @param int|string $project_id - * @param int $board_id - * - * @return mixed - */ - public function allLists($project_id, int $board_id) + public function allLists(int|string $project_id, int $board_id): mixed { return $this->get($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id).'/lists')); } - /** - * @param int|string $project_id - * @param int $board_id - * @param int $list_id - * - * @return mixed - */ - public function showList($project_id, int $board_id, int $list_id) + public function showList(int|string $project_id, int $board_id, int $list_id): mixed { return $this->get($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id))); } - /** - * @param int|string $project_id - * @param int $board_id - * @param int $label_id - * - * @return mixed - */ - public function createList($project_id, int $board_id, int $label_id) + public function createList(int|string $project_id, int $board_id, int $label_id): mixed { $params = [ 'label_id' => $label_id, @@ -115,15 +64,7 @@ public function createList($project_id, int $board_id, int $label_id) return $this->post($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id).'/lists'), $params); } - /** - * @param int|string $project_id - * @param int $board_id - * @param int $list_id - * @param int $position - * - * @return mixed - */ - public function updateList($project_id, int $board_id, int $list_id, int $position) + public function updateList(int|string $project_id, int $board_id, int $list_id, int $position): mixed { $params = [ 'position' => $position, @@ -132,14 +73,7 @@ public function updateList($project_id, int $board_id, int $list_id, int $positi return $this->put($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id)), $params); } - /** - * @param int|string $project_id - * @param int $board_id - * @param int $list_id - * - * @return mixed - */ - public function deleteList($project_id, int $board_id, int $list_id) + public function deleteList(int|string $project_id, int $board_id, int $list_id): mixed { return $this->delete($this->getProjectPath($project_id, 'boards/'.self::encodePath($board_id).'/lists/'.self::encodePath($list_id))); } diff --git a/src/Api/IssueLinks.php b/src/Api/IssueLinks.php index c3cd68a5..d5c8399f 100644 --- a/src/Api/IssueLinks.php +++ b/src/Api/IssueLinks.php @@ -16,30 +16,18 @@ class IssueLinks extends AbstractApi { - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function all($project_id, int $issue_iid) + public function all(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/links'); } /** - * @param int|string $project_id - * @param int $issue_iid - * @param int|string $target_project_id - * @param int $target_issue_iid * @param array $parameters { * * @var string $link_type * } - * - * @return mixed */ - public function create($project_id, int $issue_iid, $target_project_id, int $target_issue_iid, array $parameters = []) + public function create(int|string $project_id, int $issue_iid, int|string $target_project_id, int $target_issue_iid, array $parameters = []): mixed { $parameters['target_project_id'] = $target_project_id; $parameters['target_issue_iid'] = $target_issue_iid; @@ -48,17 +36,12 @@ public function create($project_id, int $issue_iid, $target_project_id, int $tar } /** - * @param int|string $project_id - * @param int $issue_iid - * @param int|string $issue_link_id * @param array $parameters { * * @var string $link_type * } - * - * @return mixed */ - public function remove($project_id, int $issue_iid, $issue_link_id, array $parameters = []) + public function remove(int|string $project_id, int $issue_iid, int|string $issue_link_id, array $parameters = []): mixed { return $this->delete($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/links/'.self::encodePath($issue_link_id), $parameters); } diff --git a/src/Api/Issues.php b/src/Api/Issues.php index 7ce49cb9..10f74f26 100644 --- a/src/Api/Issues.php +++ b/src/Api/Issues.php @@ -30,7 +30,6 @@ class Issues extends AbstractApi public const STATE_CLOSED = 'closed'; /** - * @param int|string|null $project_id * @param array $parameters { * * @var string $state return all issues or just those that are opened or closed @@ -41,25 +40,22 @@ class Issues extends AbstractApi * @var int[] $iids return only the issues having the given iid * @var string $order_by return requests ordered by created_at or updated_at fields (default is created_at) * @var string $sort return requests sorted in asc or desc order (default is desc) + * @var bool $confidential filter confidential or public issues * @var string $search search issues against their title and description + * @var int $author_id filter issues assigned to the specified author user id + * @var int $assignee_id filter issues assigned to the specified assignee user id + * @var int $iteration_id filter issues assigned to the specified iteration id + * @var string $iteration_title filter issues assigned to the specified iteration title * } - * - * @return mixed */ - public function all($project_id = null, array $parameters = []) + public function all(int|string|null $project_id = null, array $parameters = []): mixed { $path = null === $project_id ? 'issues' : $this->getProjectPath($project_id, 'issues'); return $this->get($path, $this->createOptionsResolver()->resolve($parameters)); } - /** - * @param int|string $group_id - * @param array $parameters - * - * @return mixed - */ - public function group($group_id, array $parameters = []) + public function group(int|string $group_id, array $parameters = []): mixed { return $this->get( 'groups/'.self::encodePath($group_id).'/issues', @@ -67,273 +63,120 @@ public function group($group_id, array $parameters = []) ); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function show($project_id, int $issue_iid) + public function show(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid))); } - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function create($project_id, array $params) + public function create(int|string $project_id, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'issues'), $params); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param array $params - * - * @return mixed - */ - public function update($project_id, int $issue_iid, array $params) + public function update(int|string $project_id, int $issue_iid, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)), $params); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param array $params - * - * @return mixed - */ - public function reorder($project_id, int $issue_iid, array $params) + public function reorder(int|string $project_id, int $issue_iid, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/reorder', $params); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int|string $to_project_id - * - * @return mixed - */ - public function move($project_id, int $issue_iid, $to_project_id) + public function move(int|string $project_id, int $issue_iid, int|string $to_project_id): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/move', [ 'to_project_id' => $to_project_id, ]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function remove($project_id, int $issue_iid) + public function remove(int|string $project_id, int $issue_iid): mixed { return $this->delete($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid))); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function showNotes($project_id, int $issue_iid) + public function showNotes(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/notes')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int $note_id - * - * @return mixed - */ - public function showNote($project_id, int $issue_iid, int $note_id) + public function showNote(int|string $project_id, int $issue_iid, int $note_id): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $body - * @param array $params - * - * @return mixed - */ - public function addNote($project_id, int $issue_iid, string $body, array $params = []) + public function addNote(int|string $project_id, int $issue_iid, string $body, array $params = []): mixed { $params['body'] = $body; return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/notes'), $params); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int $note_id - * @param string $body - * @param array $params - * - * @return mixed - */ - public function updateNote($project_id, int $issue_iid, int $note_id, string $body, array $params = []) + public function updateNote(int|string $project_id, int $issue_iid, int $note_id, string $body, array $params = []): mixed { $params['body'] = $body; return $this->put($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/notes/'.self::encodePath($note_id)), $params); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int $note_id - * - * @return mixed - */ - public function removeNote($project_id, int $issue_iid, int $note_id) + public function removeNote(int|string $project_id, int $issue_iid, int $note_id): mixed { return $this->delete($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function showDiscussions($project_id, int $issue_iid) + public function showDiscussions(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/discussions'); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $discussion_id - * - * @return mixed - */ - public function showDiscussion($project_id, int $issue_iid, string $discussion_id) + public function showDiscussion(int|string $project_id, int $issue_iid, string $discussion_id): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/discussions/'.self::encodePath($discussion_id)); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $body - * - * @return mixed - */ - public function addDiscussion($project_id, int $issue_iid, string $body) + public function addDiscussion(int|string $project_id, int $issue_iid, string $body): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/discussions'), ['body' => $body]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $discussion_id - * @param string $body - * - * @return mixed - */ - public function addDiscussionNote($project_id, int $issue_iid, string $discussion_id, string $body) + public function addDiscussionNote(int|string $project_id, int $issue_iid, string $discussion_id, string $body): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/discussions/'.self::encodePath($discussion_id).'/notes'), ['body' => $body]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $discussion_id - * @param int $note_id - * @param string $body - * - * @return mixed - */ - public function updateDiscussionNote($project_id, int $issue_iid, string $discussion_id, int $note_id, string $body) + public function updateDiscussionNote(int|string $project_id, int $issue_iid, string $discussion_id, int $note_id, string $body): mixed { return $this->put($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/discussions/'.self::encodePath($discussion_id).'/notes/'.self::encodePath($note_id)), [ 'body' => $body, ]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $discussion_id - * @param int $note_id - * - * @return mixed - */ - public function removeDiscussionNote($project_id, int $issue_iid, string $discussion_id, int $note_id) + public function removeDiscussionNote(int|string $project_id, int $issue_iid, string $discussion_id, int $note_id): mixed { return $this->delete($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/discussions/'.self::encodePath($discussion_id).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $duration - * - * @return mixed - */ - public function setTimeEstimate($project_id, int $issue_iid, string $duration) + public function setTimeEstimate(int|string $project_id, int $issue_iid, string $duration): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/time_estimate'), ['duration' => $duration]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function resetTimeEstimate($project_id, int $issue_iid) + public function resetTimeEstimate(int|string $project_id, int $issue_iid): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/reset_time_estimate')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param string $duration - * - * @return mixed - */ - public function addSpentTime($project_id, int $issue_iid, string $duration) + public function addSpentTime(int|string $project_id, int $issue_iid, string $duration): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/add_spent_time'), ['duration' => $duration]); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function resetSpentTime($project_id, int $issue_iid) + public function resetSpentTime(int|string $project_id, int $issue_iid): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/reset_spent_time')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function getTimeStats($project_id, int $issue_iid) + public function getTimeStats(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/time_stats')); } @@ -346,10 +189,8 @@ public function getTimeStats($project_id, int $issue_iid) * * @param int|string $project_id The ID or URL-encoded path of the project owned by the authenticated user * @param int $issue_iid The internal ID of a project’s issue - * - * @return mixed */ - public function subscribe($project_id, int $issue_iid) + public function subscribe(int|string $project_id, int $issue_iid): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/subscribe')); } @@ -362,96 +203,47 @@ public function subscribe($project_id, int $issue_iid) * * @param int|string $project_id The ID or URL-encoded path of the project owned by the authenticated user * @param int $issue_iid The internal ID of a project’s issue - * - * @return mixed */ - public function unsubscribe($project_id, int $issue_iid) + public function unsubscribe(int|string $project_id, int $issue_iid): mixed { return $this->post($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/unsubscribe')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function awardEmoji($project_id, int $issue_iid) + public function awardEmoji(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/award_emoji')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int $award_id - * - * @return mixed - */ - public function removeAwardEmoji($project_id, int $issue_iid, int $award_id) + public function removeAwardEmoji(int|string $project_id, int $issue_iid, int $award_id): mixed { return $this->delete($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/award_emoji/'.self::encodePath($award_id))); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function closedByMergeRequests($project_id, int $issue_iid) + public function closedByMergeRequests(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/closed_by'); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function relatedMergeRequests($project_id, int $issue_iid) + public function relatedMergeRequests(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid).'/related_merge_requests')); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function showParticipants($project_id, int $issue_iid) + public function showParticipants(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/participants'); } - /** - * @param int|string $project_id - * @param int $issue_iid - * - * @return mixed - */ - public function showResourceLabelEvents($project_id, int $issue_iid) + public function showResourceLabelEvents(int|string $project_id, int $issue_iid): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/resource_label_events'); } - /** - * @param int|string $project_id - * @param int $issue_iid - * @param int $resource_label_event_id - * - * @return mixed - */ - public function showResourceLabelEvent($project_id, int $issue_iid, int $resource_label_event_id) + public function showResourceLabelEvent(int|string $project_id, int $issue_iid, int $resource_label_event_id): mixed { return $this->get($this->getProjectPath($project_id, 'issues/'.self::encodePath($issue_iid)).'/resource_label_events/'.self::encodePath($resource_label_event_id)); } - /** - * @return OptionsResolver - */ protected function createOptionsResolver(): OptionsResolver { $resolver = parent::createOptionsResolver(); @@ -464,6 +256,8 @@ protected function createOptionsResolver(): OptionsResolver ; $resolver->setDefined('labels'); $resolver->setDefined('milestone'); + $resolver->setDefined('milestone_id') + ->setAllowedTypes('milestone_id', 'integer'); $resolver->setDefined('with_labels_details') ->setAllowedTypes('with_labels_details', 'bool') ->setNormalizer('with_labels_details', $booleanNormalizer) @@ -483,14 +277,26 @@ protected function createOptionsResolver(): OptionsResolver $resolver->setDefined('sort') ->setAllowedValues('sort', ['asc', 'desc']) ; + $resolver->setDefined('confidential') + ->setAllowedValues('confidential', [false, true]) + ; $resolver->setDefined('search'); $resolver->setDefined('created_after'); $resolver->setDefined('created_before'); $resolver->setDefined('updated_after'); $resolver->setDefined('updated_before'); + $resolver->setDefined('author_id') + ->setAllowedTypes('author_id', 'integer') + ; $resolver->setDefined('assignee_id') ->setAllowedTypes('assignee_id', 'integer') ; + $resolver->setDefined('iteration_id') + ->setAllowedTypes('iteration_id', 'integer') + ; + $resolver->setDefined('iteration_title') + ->setAllowedTypes('iteration_title', 'string') + ; $resolver->setDefined('weight') ->setAllowedTypes('weight', 'integer') ; diff --git a/src/Api/IssuesStatistics.php b/src/Api/IssuesStatistics.php index 6b485e9c..33e459ef 100644 --- a/src/Api/IssuesStatistics.php +++ b/src/Api/IssuesStatistics.php @@ -19,41 +19,21 @@ class IssuesStatistics extends AbstractApi { - /** - * @param array $parameters - * - * @return mixed - */ - public function all(array $parameters) + public function all(array $parameters): mixed { return $this->get('issues_statistics', $this->createOptionsResolver()->resolve($parameters)); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function project($project_id, array $parameters) + public function project(int|string $project_id, array $parameters): mixed { return $this->get($this->getProjectPath($project_id, 'issues_statistics'), $this->createOptionsResolver()->resolve($parameters)); } - /** - * @param int|string $group_id - * @param array $parameters - * - * @return mixed - */ - public function group($group_id, array $parameters) + public function group(int|string $group_id, array $parameters): mixed { return $this->get('groups/'.self::encodePath($group_id).'/issues_statistics', $this->createOptionsResolver()->resolve($parameters)); } - /** - * @return OptionsResolver - */ protected function createOptionsResolver(): OptionsResolver { $resolver = new OptionsResolver(); diff --git a/src/Api/Jobs.php b/src/Api/Jobs.php index 9d122433..1850e535 100644 --- a/src/Api/Jobs.php +++ b/src/Api/Jobs.php @@ -60,16 +60,13 @@ class Jobs extends AbstractApi public const SCOPE_MANUAL = 'manual'; /** - * @param int|string $project_id * @param array $parameters { * * @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed, * success, canceled, skipped, manual; showing all jobs if none provided. * } - * - * @return mixed */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -77,17 +74,13 @@ public function all($project_id, array $parameters = []) } /** - * @param int|string $project_id - * @param int $pipeline_id * @param array $parameters { * * @var string|string[] $scope The scope of jobs to show, one or array of: created, pending, running, failed, * success, canceled, skipped, manual; showing all jobs if none provided. * } - * - * @return mixed */ - public function pipelineJobs($project_id, int $pipeline_id, array $parameters = []) + public function pipelineJobs(int|string $project_id, int $pipeline_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -98,17 +91,14 @@ public function pipelineJobs($project_id, int $pipeline_id, array $parameters = } /** - * @param int|string $project_id - * @param int $pipeline_id * @param array $parameters { * - * @var string|string[] $scope The scope of bridge jobs to show, one or array of: created, pending, running, failed, - * success, canceled, skipped, manual; showing all jobs if none provided. + * @var string|string[] $scope The scope of bridge jobs to show, one or array of: created, pending, running, failed, + * success, canceled, skipped, manual; showing all jobs if none provided + * @var bool $include_retried Include retried jobs in the response. Defaults to false. Introduced in GitLab 13.9. * } - * - * @return mixed */ - public function pipelineBridges($project_id, int $pipeline_id, array $parameters = []) + public function pipelineBridges(int|string $project_id, int $pipeline_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -118,126 +108,65 @@ public function pipelineBridges($project_id, int $pipeline_id, array $parameters ); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function show($project_id, int $job_id) + public function show(int|string $project_id, int $job_id): mixed { return $this->get('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id)); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return StreamInterface - */ - public function artifacts($project_id, int $job_id) + public function artifacts(int|string $project_id, int $job_id): StreamInterface { return $this->getAsResponse('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/artifacts')->getBody(); } - /** - * @param int|string $project_id - * @param string $ref_name - * @param string $job_name - * - * @return StreamInterface - */ - public function artifactsByRefName($project_id, string $ref_name, string $job_name) + public function artifactsByRefName(int|string $project_id, string $ref_name, string $job_name): StreamInterface { return $this->getAsResponse('projects/'.self::encodePath($project_id).'/jobs/artifacts/'.self::encodePath($ref_name).'/download', [ - 'job' => self::encodePath($job_name), + 'job' => $job_name, ])->getBody(); } - /** - * @param int|string $project_id - * @param string $ref_name - * @param string $job_name - * @param string $artifact_path - * - * @return StreamInterface - */ - public function artifactByRefName($project_id, string $ref_name, string $job_name, string $artifact_path) + public function artifactByRefName(int|string $project_id, string $ref_name, string $job_name, string $artifact_path): StreamInterface { return $this->getAsResponse('projects/'.self::encodePath($project_id).'/jobs/artifacts/'.self::encodePath($ref_name).'/raw/'.self::encodePath($artifact_path), [ - 'job' => self::encodePath($job_name), + 'job' => $job_name, ])->getBody(); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function trace($project_id, int $job_id) + public function artifactByJobId(int|string $project_id, int $job_id, string $artifact_path): StreamInterface + { + return $this->getAsResponse('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/artifacts/'.self::encodePath($artifact_path))->getBody(); + } + + public function trace(int|string $project_id, int $job_id): mixed { return $this->get('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/trace'); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function cancel($project_id, int $job_id) + public function cancel(int|string $project_id, int $job_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/cancel'); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function retry($project_id, int $job_id) + public function retry(int|string $project_id, int $job_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/retry'); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function erase($project_id, int $job_id) + public function erase(int|string $project_id, int $job_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/erase'); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function keepArtifacts($project_id, int $job_id) + public function keepArtifacts(int|string $project_id, int $job_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/artifacts/keep'); } - /** - * @param int|string $project_id - * @param int $job_id - * - * @return mixed - */ - public function play($project_id, int $job_id) + public function play(int|string $project_id, int $job_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/jobs/'.self::encodePath($job_id).'/play'); } - /** - * @return OptionsResolver - */ protected function createOptionsResolver(): OptionsResolver { $allowedScopeValues = [ @@ -263,6 +192,9 @@ protected function createOptionsResolver(): OptionsResolver }) ; + $resolver->setDefined('include_retried') + ->setAllowedTypes('include_retried', ['bool']); + return $resolver; } } diff --git a/src/Api/Keys.php b/src/Api/Keys.php index 59ad6ce4..05f4d4d5 100644 --- a/src/Api/Keys.php +++ b/src/Api/Keys.php @@ -16,12 +16,7 @@ class Keys extends AbstractApi { - /** - * @param int $id - * - * @return mixed - */ - public function show(int $id) + public function show(int $id): mixed { return $this->get('keys/'.self::encodePath($id)); } diff --git a/src/Api/MergeRequests.php b/src/Api/MergeRequests.php index 61b1ebd9..83d5b7d0 100644 --- a/src/Api/MergeRequests.php +++ b/src/Api/MergeRequests.php @@ -46,7 +46,6 @@ class MergeRequests extends AbstractApi public const STATE_LOCKED = 'locked'; /** - * @param int|string|null $project_id * @param array $parameters { * * @var int[] $iids return the request having the given iid @@ -61,18 +60,20 @@ class MergeRequests extends AbstractApi * @var string $labels return merge requests matching a comma separated list of labels * @var \DateTimeInterface $created_after return merge requests created after the given time (inclusive) * @var \DateTimeInterface $created_before return merge requests created before the given time (inclusive) + * @var int $reviewer_id return merge requests which have the user as a reviewer with the given user id + * @var bool $wip return only draft merge requests (true) or only non-draft merge requests (false) * } * * @throws UndefinedOptionsException if an option name is undefined * @throws InvalidOptionsException if an option doesn't fulfill the specified validation rules - * - * @return mixed */ - public function all($project_id = null, array $parameters = []) + public function all(int|string|null $project_id = null, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { - return $value->format('c'); + $utc = (new \DateTimeImmutable($value->format(\DateTimeImmutable::RFC3339_EXTENDED)))->setTimezone(new \DateTimeZone('UTC')); + + return $utc->format('Y-m-d\TH:i:s.v\Z'); }; $resolver->setDefined('iids') ->setAllowedTypes('iids', 'array') @@ -136,6 +137,13 @@ public function all($project_id = null, array $parameters = []) return \count($value) === \count(\array_filter($value, 'is_int')); }) ; + $resolver->setDefined('reviewer_id') + ->setAllowedTypes('reviewer_id', 'integer'); + $resolver->setDefined('wip') + ->setAllowedTypes('wip', 'boolean') + ->addNormalizer('wip', static function ($resolver, $wip) { + return $wip ? 'yes' : 'no'; + }); $path = null === $project_id ? 'merge_requests' : $this->getProjectPath($project_id, 'merge_requests'); @@ -143,17 +151,13 @@ public function all($project_id = null, array $parameters = []) } /** - * @param int|string $project_id - * @param int $mr_iid * @param array $parameters { * * @var bool $include_diverged_commits_count Return the commits behind the target branch * @var bool $include_rebase_in_progress Return whether a rebase operation is in progress * } - * - * @return mixed */ - public function show($project_id, int $mr_iid, array $parameters = []) + public function show(int|string $project_id, int $mr_iid, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('include_diverged_commits_count') @@ -167,20 +171,14 @@ public function show($project_id, int $mr_iid, array $parameters = []) } /** - * @param int|string $project_id - * @param string $source - * @param string $target - * @param string $title * @param array $parameters { * * @var int $assignee_id the assignee id * @var int|string $target_project_id the target project id * @var string $description the description * } - * - * @return mixed */ - public function create($project_id, string $source, string $target, string $title, array $parameters = []) + public function create(int|string $project_id, string $source, string $target, string $title, array $parameters = []): mixed { $baseParams = [ 'source_branch' => $source, @@ -194,282 +192,128 @@ public function create($project_id, string $source, string $target, string $titl ); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param array $parameters - * - * @return mixed - */ - public function update($project_id, int $mr_iid, array $parameters) + public function update(int|string $project_id, int $mr_iid, array $parameters): mixed { return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid)), $parameters); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param array $parameters - * - * @return mixed - */ - public function merge($project_id, int $mr_iid, array $parameters = []) + public function merge(int|string $project_id, int $mr_iid, array $parameters = []): mixed { return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/merge'), $parameters); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function showNotes($project_id, int $mr_iid) + public function showNotes(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/notes')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $note_id - * - * @return mixed - */ - public function showNote($project_id, int $mr_iid, int $note_id) + public function showNote(int|string $project_id, int $mr_iid, int $note_id): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $body - * @param array $params - * - * @return mixed - */ - public function addNote($project_id, int $mr_iid, string $body, array $params = []) + public function addNote(int|string $project_id, int $mr_iid, string $body, array $params = []): mixed { $params['body'] = $body; return $this->post($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/notes'), $params); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $note_id - * @param string $body - * - * @return mixed - */ - public function updateNote($project_id, int $mr_iid, int $note_id, string $body) + public function updateNote(int|string $project_id, int $mr_iid, int $note_id, string $body): mixed { return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/notes/'.self::encodePath($note_id)), [ 'body' => $body, ]); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $note_id - * - * @return mixed - */ - public function removeNote($project_id, int $mr_iid, int $note_id) + public function removeNote(int|string $project_id, int $mr_iid, int $note_id): mixed { return $this->delete($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function showDiscussions($project_id, int $mr_iid) + public function showDiscussions(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid)).'/discussions'); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $discussion_id - * - * @return mixed - */ - public function showDiscussion($project_id, int $mr_iid, string $discussion_id) + public function showDiscussion(int|string $project_id, int $mr_iid, string $discussion_id): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid)).'/discussions/'.self::encodePath($discussion_id)); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param array $params - * - * @return mixed - */ - public function addDiscussion($project_id, int $mr_iid, array $params) + public function addDiscussion(int|string $project_id, int $mr_iid, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/discussions'), $params); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $discussion_id - * @param bool $resolved - * - * @return mixed - */ - public function resolveDiscussion($project_id, int $mr_iid, string $discussion_id, bool $resolved = true) + public function resolveDiscussion(int|string $project_id, int $mr_iid, string $discussion_id, bool $resolved = true): mixed { return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/discussions/'.self::encodePath($discussion_id)), [ 'resolved' => $resolved, ]); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $discussion_id - * @param string $body - * - * @return mixed - */ - public function addDiscussionNote($project_id, int $mr_iid, string $discussion_id, string $body) + public function addDiscussionNote(int|string $project_id, int $mr_iid, string $discussion_id, string $body): mixed { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/discussions/'.self::encodePath($discussion_id).'/notes'), ['body' => $body]); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $discussion_id - * @param int $note_id - * @param array $params - * - * @return mixed - */ - public function updateDiscussionNote($project_id, int $mr_iid, string $discussion_id, int $note_id, array $params) + public function updateDiscussionNote(int|string $project_id, int $mr_iid, string $discussion_id, int $note_id, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/discussions/'.self::encodePath($discussion_id).'/notes/'.self::encodePath($note_id)), $params); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $discussion_id - * @param int $note_id - * - * @return mixed - */ - public function removeDiscussionNote($project_id, int $mr_iid, string $discussion_id, int $note_id) + public function removeDiscussionNote(int|string $project_id, int $mr_iid, string $discussion_id, int $note_id): mixed { return $this->delete($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/discussions/'.self::encodePath($discussion_id).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function changes($project_id, int $mr_iid) + public function showParticipants(int|string $project_id, int $mr_iid): mixed + { + return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid)).'/participants'); + } + + public function changes(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/changes')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function commits($project_id, int $mr_iid) + public function commits(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/commits')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function closesIssues($project_id, int $mr_iid) + public function closesIssues(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/closes_issues')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function approvals($project_id, int $mr_iid) + public function approvals(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/approvals')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function approve($project_id, int $mr_iid) + public function approve(int|string $project_id, int $mr_iid): mixed { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/approve')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function unapprove($project_id, int $mr_iid) + public function unapprove(int|string $project_id, int $mr_iid): mixed { return $this->post($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/unapprove')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function awardEmoji($project_id, int $mr_iid) + public function awardEmoji(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/award_emoji')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $award_id - * - * @return mixed - */ - public function removeAwardEmoji($project_id, int $mr_iid, int $award_id) + public function removeAwardEmoji(int|string $project_id, int $mr_iid, int $award_id): mixed { return $this->delete($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/award_emoji/'.self::encodePath($award_id))); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param array $params - * - * @return mixed - */ - public function rebase($project_id, int $mr_iid, array $params = []) + public function rebase(int|string $project_id, int $mr_iid, array $params = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('skip_ci') @@ -478,38 +322,20 @@ public function rebase($project_id, int $mr_iid, array $params = []) return $this->put($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid)).'/rebase', $resolver->resolve($params)); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function approvalState($project_id, int $mr_iid) + public function approvalState(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/approval_state')); } - /** - * @param int|string $project_id - * @param int $mr_iid - * - * @return mixed - */ - public function levelRules($project_id, int $mr_iid) + public function levelRules(int|string $project_id, int $mr_iid): mixed { return $this->get($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/approval_rules')); } /** - * @param int|string $project_id - * @param int $mr_iid - * @param string $name - * @param int $approvals_required * @param array $parameters - * - * @return mixed */ - public function createLevelRule($project_id, int $mr_iid, string $name, int $approvals_required, array $parameters = []) + public function createLevelRule(int|string $project_id, int $mr_iid, string $name, int $approvals_required, array $parameters = []): mixed { $baseParam = [ 'name' => $name, @@ -523,16 +349,9 @@ public function createLevelRule($project_id, int $mr_iid, string $name, int $app } /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $approval_rule_id - * @param string $name - * @param int $approvals_required * @param array $parameters - * - * @return mixed */ - public function updateLevelRule($project_id, int $mr_iid, int $approval_rule_id, string $name, int $approvals_required, array $parameters = []) + public function updateLevelRule(int|string $project_id, int $mr_iid, int $approval_rule_id, string $name, int $approvals_required, array $parameters = []): mixed { $baseParam = [ 'name' => $name, @@ -545,14 +364,7 @@ public function updateLevelRule($project_id, int $mr_iid, int $approval_rule_id, ); } - /** - * @param int|string $project_id - * @param int $mr_iid - * @param int $approval_rule_id - * - * @return mixed - */ - public function deleteLevelRule($project_id, int $mr_iid, int $approval_rule_id) + public function deleteLevelRule(int|string $project_id, int $mr_iid, int $approval_rule_id): mixed { return $this->delete($this->getProjectPath($project_id, 'merge_requests/'.self::encodePath($mr_iid).'/approval_rules/'.self::encodePath($approval_rule_id))); } diff --git a/src/Api/Milestones.php b/src/Api/Milestones.php index 8aba4ab9..ee076150 100644 --- a/src/Api/Milestones.php +++ b/src/Api/Milestones.php @@ -27,17 +27,14 @@ class Milestones extends AbstractApi public const STATE_CLOSED = 'closed'; /** - * @param int|string $project_id * @param array $parameters { * * @var int[] $iids return only the milestones having the given iids * @var string $state return only active or closed milestones * @var string $search Return only milestones with a title or description matching the provided string. * } - * - * @return mixed */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('iids') @@ -54,59 +51,33 @@ public function all($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'milestones'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $milestone_id - * - * @return mixed - */ - public function show($project_id, int $milestone_id) + public function show(int|string $project_id, int $milestone_id): mixed { return $this->get($this->getProjectPath($project_id, 'milestones/'.self::encodePath($milestone_id))); } - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function create($project_id, array $params) + public function create(int|string $project_id, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'milestones'), $params); } - /** - * @param int|string $project_id - * @param int $milestone_id - * @param array $params - * - * @return mixed - */ - public function update($project_id, int $milestone_id, array $params) + public function update(int|string $project_id, int $milestone_id, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'milestones/'.self::encodePath($milestone_id)), $params); } - /** - * @param int|string $project_id - * @param int $milestone_id - * - * @return mixed - */ - public function remove($project_id, int $milestone_id) + public function remove(int|string $project_id, int $milestone_id): mixed { return $this->delete($this->getProjectPath($project_id, 'milestones/'.self::encodePath($milestone_id))); } - /** - * @param int|string $project_id - * @param int $milestone_id - * - * @return mixed - */ - public function issues($project_id, int $milestone_id) + public function issues(int|string $project_id, int $milestone_id): mixed { return $this->get($this->getProjectPath($project_id, 'milestones/'.self::encodePath($milestone_id).'/issues')); } + + public function mergeRequests(int|string $project_id, int $milestone_id): mixed + { + return $this->get($this->getProjectPath($project_id, 'milestones/'.self::encodePath($milestone_id).'/merge_requests')); + } } diff --git a/src/Api/Packages.php b/src/Api/Packages.php index 0a386dc2..4698905f 100644 --- a/src/Api/Packages.php +++ b/src/Api/Packages.php @@ -19,7 +19,6 @@ class Packages extends AbstractApi { /** - * @param int|string $project_id * @param array $parameters { * * @var string $order_by the field to use as order. one of created_at (default), name, @@ -33,10 +32,8 @@ class Packages extends AbstractApi * @var string $status filter the returned packages by status. one of default (default), * hidden, or processing. * } - * - * @return mixed */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -63,60 +60,42 @@ public function all($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'packages'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $package_id - * - * @return mixed - */ - public function show($project_id, int $package_id) + public function show(int|string $project_id, int $package_id): mixed { return $this->get($this->getPackagePath($project_id, $package_id)); } - /** - * @param int|string $project_id - * @param int $package_id - * - * @return mixed - */ - public function allFiles($project_id, int $package_id) + public function allFiles(int|string $project_id, int $package_id): mixed { return $this->get($this->getPackagePath($project_id, $package_id).'/package_files'); } - /** - * @param int|string $project_id - * @param int $package_id - * - * @return mixed - */ - public function remove($project_id, int $package_id) + public function remove(int|string $project_id, int $package_id): mixed { return $this->delete($this->getPackagePath($project_id, $package_id)); } - /** - * @param int|string $project_id - * @param int $package_id - * @param int $package_file_id - * - * @return mixed - */ - public function removeFile($project_id, int $package_id, int $package_file_id) + public function removeFile(int|string $project_id, int $package_id, int $package_file_id): mixed { return $this->delete( $this->getPackagePath($project_id, $package_id).'/package_files/'.self::encodePath($package_file_id) ); } - /** - * @param int|string $project_id - * @param int $package_id - * - * @return string - */ - private function getPackagePath($project_id, int $package_id): string + public function addGenericFile(int|string $project_id, string $package_name, string $package_version, string $file, string $status = 'default'): mixed + { + return $this->putFile( + $this->getProjectPath( + $project_id, + 'packages/generic/'.self::encodePath($package_name).'/'.self::encodePath($package_version).'/'.self::encodePath(\basename($file)) + ), + $file, + [], + ['status' => $status] + ); + } + + private function getPackagePath(int|string $project_id, int $package_id): string { return $this->getProjectPath($project_id, 'packages/'.self::encodePath($package_id)); } diff --git a/src/Api/ProjectNamespaces.php b/src/Api/ProjectNamespaces.php index ac29800d..d35228ba 100644 --- a/src/Api/ProjectNamespaces.php +++ b/src/Api/ProjectNamespaces.php @@ -21,10 +21,8 @@ class ProjectNamespaces extends AbstractApi * * @var string $search Returns a list of namespaces the user is authorized to see based on the search criteria. * } - * - * @return mixed */ - public function all(array $parameters = []) + public function all(array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('search'); @@ -32,12 +30,7 @@ public function all(array $parameters = []) return $this->get('namespaces', $resolver->resolve($parameters)); } - /** - * @param int|string $namespace_id - * - * @return mixed - */ - public function show($namespace_id) + public function show(int|string $namespace_id): mixed { return $this->get('namespaces/'.self::encodePath($namespace_id)); } diff --git a/src/Api/Projects.php b/src/Api/Projects.php index fe067dd6..32aa168a 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -53,12 +53,9 @@ class Projects extends AbstractApi * } * * @throws UndefinedOptionsException If an option name is undefined - * @throws InvalidOptionsException If an option doesn't fulfill the - * specified validation rules - * - * @return mixed + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules */ - public function all(array $parameters = []) + public function all(array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -154,16 +151,13 @@ public function all(array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var bool $statistics include project statistics * @var bool $with_custom_attributes Include project custom attributes. * } - * - * @return mixed */ - public function show($project_id, array $parameters = []) + public function show(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): bool { @@ -181,117 +175,63 @@ public function show($project_id, array $parameters = []) return $this->get('projects/'.self::encodePath($project_id), $resolver->resolve($parameters)); } - /** - * @param string $name - * @param array $parameters - * - * @return mixed - */ - public function create(string $name, array $parameters = []) + public function create(string $name, array $parameters = []): mixed { $parameters['name'] = $name; return $this->post('projects', $parameters); } - /** - * @param int $user_id - * @param string $name - * @param array $parameters - * - * @return mixed - */ - public function createForUser(int $user_id, string $name, array $parameters = []) + public function createForUser(int $user_id, string $name, array $parameters = []): mixed { $parameters['name'] = $name; return $this->post('projects/user/'.self::encodePath($user_id), $parameters); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function update($project_id, array $parameters) + public function update(int|string $project_id, array $parameters): mixed { return $this->put('projects/'.self::encodePath($project_id), $parameters); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function remove($project_id) + public function remove(int|string $project_id): mixed { return $this->delete('projects/'.self::encodePath($project_id)); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function archive($project_id) + public function archive(int|string $project_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/archive'); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function unarchive($project_id) + public function unarchive(int|string $project_id): mixed { return $this->post('projects/'.self::encodePath($project_id).'/unarchive'); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function triggers($project_id) + public function triggers(int|string $project_id): mixed { return $this->get('projects/'.self::encodePath($project_id).'/triggers'); } - /** - * @param int|string $project_id - * @param int $trigger_id - * - * @return mixed - */ - public function trigger($project_id, int $trigger_id) + public function trigger(int|string $project_id, int $trigger_id): mixed { return $this->get($this->getProjectPath($project_id, 'triggers/'.self::encodePath($trigger_id))); } - /** - * @param int|string $project_id - * @param string $description - * - * @return mixed - */ - public function createTrigger($project_id, string $description) + public function createTrigger(int|string $project_id, string $description): mixed { return $this->post($this->getProjectPath($project_id, 'triggers'), [ 'description' => $description, ]); } - /** - * @param int|string $project_id - * @param string $ref - * @param string $token - * @param array $variables - * - * @return mixed - */ - public function triggerPipeline($project_id, string $ref, string $token, array $variables = []) + public function removeTrigger(int|string $project_id, int $trigger_id): mixed + { + return $this->delete($this->getProjectPath($project_id, 'triggers/'.self::encodePath($trigger_id))); + } + + public function triggerPipeline(int|string $project_id, string $ref, string $token, array $variables = []): mixed { return $this->post($this->getProjectPath($project_id, 'trigger/pipeline'), [ 'ref' => $ref, @@ -300,24 +240,12 @@ public function triggerPipeline($project_id, string $ref, string $token, array $ ]); } - /** - * @param int $project_id - * @param int $runner_id - * - * @return mixed - */ - public function disableRunner(int $project_id, int $runner_id) + public function disableRunner(int $project_id, int $runner_id): mixed { return $this->delete('projects/'.self::encodePath($project_id).'/runners/'.self::encodePath($runner_id)); } - /** - * @param int $project_id - * @param int $runner_id - * - * @return mixed - */ - public function enableRunner(int $project_id, int $runner_id) + public function enableRunner(int $project_id, int $runner_id): mixed { $parameters = [ 'runner_id' => $runner_id, @@ -327,7 +255,6 @@ public function enableRunner(int $project_id, int $runner_id) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $scope the scope of pipelines, one of: running, pending, finished, branches, tags @@ -337,13 +264,12 @@ public function enableRunner(int $project_id, int $runner_id) * @var bool $yaml_errors returns pipelines with invalid configurations * @var string $name the name of the user who triggered pipelines * @var string $username the username of the user who triggered pipelines - * @var string $order_by order pipelines by id, status, ref, or user_id (default: id) - * @var string $order Sort pipelines in asc or desc order (default: desc). + * @var string $order_by order pipelines by id, status, ref, updated_at, or user_id (default: id) + * @var string $order sort pipelines in asc or desc order (default: desc) + * @var string $source the source of the pipeline * } - * - * @return mixed */ - public function pipelines($project_id, array $parameters = []) + public function pipelines(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -376,102 +302,80 @@ public function pipelines($project_id, array $parameters = []) ->setNormalizer('updated_before', $datetimeNormalizer) ; $resolver->setDefined('order_by') - ->setAllowedValues('order_by', ['id', 'status', 'ref', 'user_id']) + ->setAllowedValues('order_by', ['id', 'status', 'ref', 'updated_at', 'user_id']) ; $resolver->setDefined('sort') ->setAllowedValues('sort', ['asc', 'desc']) ; + $resolver->setDefined('source') + ->setAllowedValues('source', ['push', 'web', 'trigger', 'schedule', 'api', 'external', 'pipeline', 'chat', 'webide', 'merge_request_event', 'external_pull_request_event', 'parent_pipeline', 'ondemand_dast_scan', 'ondemand_dast_validation']) + ; return $this->get($this->getProjectPath($project_id, 'pipelines'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $pipeline_id - * - * @return mixed - */ - public function pipeline($project_id, int $pipeline_id) + public function pipeline(int|string $project_id, int $pipeline_id): mixed { return $this->get($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id))); } - /** - * @param int|string $project_id - * @param int $pipeline_id - * - * @return mixed - */ - public function pipelineVariables($project_id, int $pipeline_id) + public function pipelineJobs(int|string $project_id, int $pipeline_id): mixed + { + return $this->get($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id).'/jobs')); + } + + public function pipelineVariables(int|string $project_id, int $pipeline_id): mixed { return $this->get($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id).'/variables')); } + public function pipelineTestReport(int|string $project_id, int $pipeline_id): mixed + { + return $this->get($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id).'/test_report')); + } + + public function pipelineTestReportSummary(int|string $project_id, int $pipeline_id): mixed + { + return $this->get($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id).'/test_report_summary')); + } + /** - * @param int|string $project_id - * @param string $commit_ref * @param array|null $variables { * * @var string $key The name of the variable * @var mixed $value The value of the variable * @var string $variable_type env_var (default) or file * } - * - * @return mixed */ - public function createPipeline($project_id, string $commit_ref, array $variables = null) + public function createPipeline(int|string $project_id, string $commit_ref, ?array $variables = null): mixed { - $parameters = [ - 'ref' => $commit_ref, - ]; + $parameters = []; if (null !== $variables) { $parameters['variables'] = $variables; } - return $this->post($this->getProjectPath($project_id, 'pipeline'), $parameters); + return $this->post($this->getProjectPath($project_id, 'pipeline'), $parameters, [], [], [ + 'ref' => $commit_ref, + ]); } - /** - * @param int|string $project_id - * @param int $pipeline_id - * - * @return mixed - */ - public function retryPipeline($project_id, int $pipeline_id) + public function retryPipeline(int|string $project_id, int $pipeline_id): mixed { return $this->post($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id)).'/retry'); } - /** - * @param int|string $project_id - * @param int $pipeline_id - * - * @return mixed - */ - public function cancelPipeline($project_id, int $pipeline_id) + public function cancelPipeline(int|string $project_id, int $pipeline_id): mixed { return $this->post($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id)).'/cancel'); } - /** - * @param int|string $project_id - * @param int $pipeline_id - * - * @return mixed - */ - public function deletePipeline($project_id, int $pipeline_id) + public function deletePipeline(int|string $project_id, int $pipeline_id): mixed { return $this->delete($this->getProjectPath($project_id, 'pipelines/'.self::encodePath($pipeline_id))); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function allMembers($project_id, array $parameters = []) + public function allMembers(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('query'); @@ -486,15 +390,12 @@ public function allMembers($project_id, array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $query The query you want to search members for. * } - * - * @return mixed */ - public function members($project_id, array $parameters = []) + public function members(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -511,88 +412,54 @@ public function members($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'members'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $user_id - * - * @return mixed - */ - public function member($project_id, int $user_id) + public function member(int|string $project_id, int $user_id): mixed { return $this->get($this->getProjectPath($project_id, 'members/'.self::encodePath($user_id))); } - /** - * @param int|string $project_id - * @param int $user_id - * - * @return mixed - */ - public function allMember($project_id, int $user_id) + public function allMember(int|string $project_id, int $user_id): mixed { return $this->get($this->getProjectPath($project_id, 'members/all/'.self::encodePath($user_id))); } - /** - * @param int|string $project_id - * @param int $user_id - * @param int $access_level - * - * @return mixed - */ - public function addMember($project_id, int $user_id, int $access_level) + public function addMember(int|string $project_id, int $user_id, int $access_level, ?string $expires_at = null): mixed { - return $this->post($this->getProjectPath($project_id, 'members'), [ + $params = [ 'user_id' => $user_id, 'access_level' => $access_level, - ]); + ]; + if (null !== $expires_at) { + $params['expires_at'] = $expires_at; + } + + return $this->post($this->getProjectPath($project_id, 'members'), $params); } - /** - * @param int|string $project_id - * @param int $user_id - * @param int $access_level - * - * @return mixed - */ - public function saveMember($project_id, int $user_id, int $access_level) + public function saveMember(int|string $project_id, int $user_id, int $access_level, ?string $expires_at = null): mixed { - return $this->put($this->getProjectPath($project_id, 'members/'.self::encodePath($user_id)), [ + $params = [ 'access_level' => $access_level, - ]); + ]; + if (null !== $expires_at) { + $params['expires_at'] = $expires_at; + } + + return $this->put($this->getProjectPath($project_id, 'members/'.self::encodePath($user_id)), $params); } - /** - * @param int|string $project_id - * @param int $user_id - * - * @return mixed - */ - public function removeMember($project_id, int $user_id) + public function removeMember(int|string $project_id, int $user_id): mixed { return $this->delete($this->getProjectPath($project_id, 'members/'.self::encodePath($user_id))); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function hooks($project_id, array $parameters = []) + public function hooks(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); return $this->get($this->getProjectPath($project_id, 'hooks'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $hook_id - * - * @return mixed - */ - public function hook($project_id, int $hook_id) + public function hook(int|string $project_id, int $hook_id): mixed { return $this->get($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id))); } @@ -601,13 +468,8 @@ public function hook($project_id, int $hook_id) * Get project users. * * See https://docs.gitlab.com/ee/api/projects.html#get-project-users for more info. - * - * @param int|string $project_id - * @param array $parameters - * - * @return mixed */ - public function users($project_id, array $parameters = []) + public function users(int|string $project_id, array $parameters = []): mixed { return $this->get($this->getProjectPath($project_id, 'users'), $parameters); } @@ -616,13 +478,8 @@ public function users($project_id, array $parameters = []) * Get project issues. * * See https://docs.gitlab.com/ee/api/issues.html#list-project-issues for more info. - * - * @param int|string $project_id - * @param array $parameters - * - * @return mixed */ - public function issues($project_id, array $parameters = []) + public function issues(int|string $project_id, array $parameters = []): mixed { return $this->get($this->getProjectPath($project_id, 'issues'), $parameters); } @@ -631,16 +488,40 @@ public function issues($project_id, array $parameters = []) * Get projects board list. * * See https://docs.gitlab.com/ee/api/boards.html for more info. - * - * @param int|string $project_id - * - * @return mixed */ - public function boards($project_id) + public function boards(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'boards')); } + /** + * @param array $parameters { + * + * @var string $state Return opened, upcoming, current (previously started), closed, or all iterations. + * Filtering by started state is deprecated starting with 14.1, please use current instead. + * @var string $search return only iterations with a title matching the provided string + * @var bool $include_ancestors Include iterations from parent group and its ancestors. Defaults to true. + * } + */ + public function iterations(int|string $project_id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'upcoming', 'current', 'current (previously started)', 'closed', 'all']) + ; + $resolver->setDefined('include_ancestors') + ->setAllowedTypes('include_ancestors', 'bool') + ->setNormalizer('include_ancestors', $booleanNormalizer) + ->setDefault('include_ancestors', true) + ; + + return $this->get('projects/'.self::encodePath($project_id).'/iterations', $resolver->resolve($parameters)); + } + /** * Gets a list of all discussion items for a single commit. * @@ -649,25 +530,13 @@ public function boards($project_id) * - https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab/repository/commits/695c29abcf7dc2eabde8d59869abcea0923ce8fa/discussions * * @see https://docs.gitlab.com/ee/api/discussions.html#list-project-commit-discussion-items - * - * @param int|string $project_id - * @param string $commit_id - * - * @return mixed */ - public function getRepositoryCommitDiscussions($project_id, string $commit_id) + public function getRepositoryCommitDiscussions(int|string $project_id, string $commit_id): mixed { return $this->get($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($commit_id)).'/discussions'); } - /** - * @param int|string $project_id - * @param string $url - * @param array $parameters - * - * @return mixed - */ - public function addHook($project_id, string $url, array $parameters = []) + public function addHook(int|string $project_id, string $url, array $parameters = []): mixed { if (0 === \count($parameters)) { $parameters = ['push_events' => true]; @@ -678,70 +547,32 @@ public function addHook($project_id, string $url, array $parameters = []) return $this->post($this->getProjectPath($project_id, 'hooks'), $parameters); } - /** - * @param int|string $project_id - * @param int $hook_id - * @param array $parameters - * - * @return mixed - */ - public function updateHook($project_id, int $hook_id, array $parameters) + public function updateHook(int|string $project_id, int $hook_id, array $parameters): mixed { return $this->put($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id)), $parameters); } - /** - * @param int|string $project_id - * @param int $hook_id - * - * @return mixed - */ - public function removeHook($project_id, int $hook_id) + public function removeHook(int|string $project_id, int $hook_id): mixed { return $this->delete($this->getProjectPath($project_id, 'hooks/'.self::encodePath($hook_id))); } - /** - * @param int|string $project_id - * @param mixed $namespace - * - * @return mixed - */ - public function transfer($project_id, $namespace) + public function transfer(int|string $project_id, mixed $namespace): mixed { return $this->put($this->getProjectPath($project_id, 'transfer'), ['namespace' => $namespace]); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function deployKeys($project_id) + public function deployKeys(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'deploy_keys')); } - /** - * @param int|string $project_id - * @param int $key_id - * - * @return mixed - */ - public function deployKey($project_id, int $key_id) + public function deployKey(int|string $project_id, int $key_id): mixed { return $this->get($this->getProjectPath($project_id, 'deploy_keys/'.self::encodePath($key_id))); } - /** - * @param int|string $project_id - * @param string $title - * @param string $key - * @param bool $canPush - * - * @return mixed - */ - public function addDeployKey($project_id, string $title, string $key, bool $canPush = false) + public function addDeployKey(int|string $project_id, string $title, string $key, bool $canPush = false): mixed { return $this->post($this->getProjectPath($project_id, 'deploy_keys'), [ 'title' => $title, @@ -750,30 +581,73 @@ public function addDeployKey($project_id, string $title, string $key, bool $canP ]); } - /** - * @param int|string $project_id - * @param int $key_id - * - * @return mixed - */ - public function deleteDeployKey($project_id, int $key_id) + public function deleteDeployKey(int|string $project_id, int $key_id): mixed { return $this->delete($this->getProjectPath($project_id, 'deploy_keys/'.self::encodePath($key_id))); } + public function enableDeployKey(int|string $project_id, int $key_id): mixed + { + return $this->post($this->getProjectPath($project_id, 'deploy_keys/'.self::encodePath($key_id).'/enable')); + } + + public function deployTokens(int|string $project_id, ?bool $active = null): mixed + { + return $this->get($this->getProjectPath($project_id, 'deploy_tokens'), (null !== $active) ? ['active' => $active] : []); + } + /** - * @param int|string $project_id - * @param int $key_id + * @param array $parameters { * - * @return mixed + * @var string $name the name of the deploy token + * @var \DateTimeInterface $expires_at expiration date for the deploy token, does not expire if no value is provided + * @var string $username the username for the deploy token + * @var array $scopes the scopes, one or many of: read_repository, read_registry, write_registry, read_package_registry, write_package_registry + * } */ - public function enableDeployKey($project_id, int $key_id) + public function createDeployToken(int|string $project_id, array $parameters = []): mixed { - return $this->post($this->getProjectPath($project_id, 'deploy_keys/'.self::encodePath($key_id).'/enable')); + $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; + + $resolver->define('name') + ->required() + ; + + $resolver->define('scopes') + ->required() + ->allowedTypes('array') + ->allowedValues(function ($scopes) { + $allowed = ['read_repository', 'read_registry', 'write_registry', 'read_package_registry', 'write_package_registry']; + foreach ($scopes as $scope) { + if (!\in_array($scope, $allowed, true)) { + return false; + } + } + + return true; + }) + ; + $resolver->setDefined('username') + ->setAllowedTypes('username', 'string') + ; + + $resolver->setDefined('expires_at') + ->setAllowedTypes('expires_at', \DateTimeInterface::class) + ->setNormalizer('expires_at', $datetimeNormalizer) + ; + + return $this->post($this->getProjectPath($project_id, 'deploy_tokens'), $resolver->resolve($parameters)); + } + + public function deleteDeployToken(int|string $project_id, int $token_id): mixed + { + return $this->delete($this->getProjectPath($project_id, 'deploy_tokens/'.self::encodePath($token_id))); } /** - * @param int|string $project_id * @param array $parameters { * * @var string $action include only events of a particular action type @@ -782,10 +656,8 @@ public function enableDeployKey($project_id, int $key_id) * @var \DateTimeInterface $after include only events created after a particular date * @var string $sort Sort events in asc or desc order by created_at (default is desc) * } - * - * @return mixed */ - public function events($project_id, array $parameters = []) + public function events(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { @@ -793,7 +665,7 @@ public function events($project_id, array $parameters = []) }; $resolver->setDefined('action') - ->setAllowedValues('action', ['created', 'updated', 'closed', 'reopened', 'pushed', 'commented', 'merged', 'joined', 'left', 'destroyed', 'expired']) + ->setAllowedValues('action', ['created', 'updated', 'closed', 'reopened', 'pushed', 'commented', 'merged', 'joined', 'left', 'destroyed', 'expired', 'approved']) ; $resolver->setDefined('target_type') ->setAllowedValues('target_type', ['issue', 'milestone', 'merge_request', 'note', 'project', 'snippet', 'user']) @@ -813,89 +685,158 @@ public function events($project_id, array $parameters = []) } /** - * @param int|string $project_id - * @param array $parameters + * @param array $parameters { * - * @return mixed + * @var bool $with_counts Whether or not to include issue and merge request counts. Defaults to false. + * @var bool $include_ancestor_groups Include ancestor groups. Defaults to true. + * @var string $search Keyword to filter labels by. + * } */ - public function labels($project_id, array $parameters = []) + public function labels(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); + $resolver->setDefined('with_counts') + ->setAllowedTypes('with_counts', 'bool'); + + $resolver->setDefined('include_ancestor_groups') + ->setAllowedTypes('include_ancestor_groups', 'bool'); + + $resolver->setDefined('search') + ->setAllowedTypes('search', 'string'); + return $this->get($this->getProjectPath($project_id, 'labels'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function addLabel($project_id, array $parameters) + public function addLabel(int|string $project_id, array $parameters): mixed { return $this->post($this->getProjectPath($project_id, 'labels'), $parameters); } - /** - * @param int|string $project_id - * @param int $label_id - * @param array $parameters - * - * @return mixed - */ - public function updateLabel($project_id, int $label_id, array $parameters) + public function updateLabel(int|string $project_id, int $label_id, array $parameters): mixed { return $this->put($this->getProjectPath($project_id, 'labels/'.self::encodePath($label_id)), $parameters); } - /** - * @param int|string $project_id - * @param int $label_id - * - * @return mixed - */ - public function removeLabel($project_id, int $label_id) + public function removeLabel(int|string $project_id, int $label_id): mixed { return $this->delete($this->getProjectPath($project_id, 'labels/'.self::encodePath($label_id))); } /** * Get languages used in a project with percentage value. - * - * @param int|string $project_id - * - * @return mixed */ - public function languages($project_id) + public function languages(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'languages')); } /** - * @param int|string $project_id - * @param array $parameters + * @param array $parameters { * - * @return mixed + * @var bool $archived Limit by archived status + * @var string $visibility Limit by visibility public, internal, or private + * @var string $order_by Return projects ordered by id, name, path, created_at, updated_at, + * last_activity_at, repository_size, storage_size, packages_size or + * wiki_size fields (default is created_at) + * @var string $sort Return projects sorted in asc or desc order (default is desc) + * @var string $search Return list of projects matching the search criteria + * @var bool $simple Return only the ID, URL, name, and path of each project + * @var bool $owned Limit by projects owned by the current user + * @var bool $membership Limit by projects that the current user is a member of + * @var bool $starred Limit by projects starred by the current user + * @var bool $statistics Include project statistics + * @var bool $with_issues_enabled Limit by enabled issues feature + * @var bool $with_merge_requests_enabled Limit by enabled merge requests feature + * @var int $min_access_level Limit by current user minimal access level + * @var \DateTimeInterface $updated_before limit results to projects last updated before the specified time + * @var \DateTimeInterface $updated_after limit results to projects last updated after the specified time + * @var bool $with_custom_attributes Include custom attributes in response + * } */ - public function forks($project_id, array $parameters = []) + public function forks(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; + $resolver->setDefined('archived') + ->setAllowedTypes('archived', 'bool') + ->setNormalizer('archived', $booleanNormalizer) + ; + $resolver->setDefined('visibility') + ->setAllowedValues('visibility', ['public', 'internal', 'private']) + ; + $orderBy = [ + 'id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at', + 'repository_size', 'storage_size', 'packages_size', 'wiki_size', + ]; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', $orderBy) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('search'); + $resolver->setDefined('simple') + ->setAllowedTypes('simple', 'bool') + ->setNormalizer('simple', $booleanNormalizer) + ; + $resolver->setDefined('owned') + ->setAllowedTypes('owned', 'bool') + ->setNormalizer('owned', $booleanNormalizer) + ; + $resolver->setDefined('membership') + ->setAllowedTypes('membership', 'bool') + ->setNormalizer('membership', $booleanNormalizer) + ; + $resolver->setDefined('starred') + ->setAllowedTypes('starred', 'bool') + ->setNormalizer('starred', $booleanNormalizer) + ; + $resolver->setDefined('statistics') + ->setAllowedTypes('statistics', 'bool') + ->setNormalizer('statistics', $booleanNormalizer) + ; + $resolver->setDefined('with_issues_enabled') + ->setAllowedTypes('with_issues_enabled', 'bool') + ->setNormalizer('with_issues_enabled', $booleanNormalizer) + ; + $resolver->setDefined('with_merge_requests_enabled') + ->setAllowedTypes('with_merge_requests_enabled', 'bool') + ->setNormalizer('with_merge_requests_enabled', $booleanNormalizer) + ; + $resolver->setDefined('min_access_level') + ->setAllowedValues('min_access_level', [null, 10, 20, 30, 40, 50]) + ; + $resolver->setDefined('updated_before') + ->setAllowedTypes('updated_before', \DateTimeInterface::class) + ->setNormalizer('updated_before', $datetimeNormalizer) + ; + $resolver->setDefined('updated_after') + ->setAllowedTypes('updated_after', \DateTimeInterface::class) + ->setNormalizer('updated_after', $datetimeNormalizer) + ; + $resolver->setDefined('with_custom_attributes') + ->setAllowedTypes('with_custom_attributes', 'bool') + ->setNormalizer('with_custom_attributes', $booleanNormalizer) + ; return $this->get($this->getProjectPath($project_id, 'forks'), $resolver->resolve($parameters)); } /** - * @param int|string $project_id * @param array $parameters { * * @var string $namespace The ID or path of the namespace that the project will be forked to * @var string $path The path of the forked project (optional) * @var string $name The name of the forked project (optional) * } - * - * @return mixed */ - public function fork($project_id, array $parameters = []) + public function fork(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setDefined(['namespace', 'path', 'name']); @@ -905,88 +846,49 @@ public function fork($project_id, array $parameters = []) return $this->post($this->getProjectPath($project_id, 'fork'), $resolved); } - /** - * @param int|string $project_id - * @param int|string $forked_project_id - * - * @return mixed - */ - public function createForkRelation($project_id, $forked_project_id) + public function createForkRelation(int|string $project_id, int|string $forked_project_id): mixed { return $this->post($this->getProjectPath($project_id, 'fork/'.self::encodePath($forked_project_id))); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function removeForkRelation($project_id) + public function removeForkRelation(int|string $project_id): mixed { return $this->delete($this->getProjectPath($project_id, 'fork')); } - /** - * @param int|string $project_id - * @param string $service_name - * @param array $parameters - * - * @return mixed - */ - public function setService($project_id, string $service_name, array $parameters = []) + public function setService(int|string $project_id, string $service_name, array $parameters = []): mixed { return $this->put($this->getProjectPath($project_id, 'services/'.self::encodePath($service_name)), $parameters); } - /** - * @param int|string $project_id - * @param string $service_name - * - * @return mixed - */ - public function removeService($project_id, string $service_name) + public function removeService(int|string $project_id, string $service_name): mixed { return $this->delete($this->getProjectPath($project_id, 'services/'.self::encodePath($service_name))); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function variables($project_id, array $parameters = []) + public function variables(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); return $this->get($this->getProjectPath($project_id, 'variables'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $key - * - * @return mixed - */ - public function variable($project_id, string $key) + public function variable(int|string $project_id, string $key, array $parameters = []): mixed { - return $this->get($this->getProjectPath($project_id, 'variables/'.self::encodePath($key))); + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('filter') + ->setAllowedTypes('filter', 'array'); + + return $this->get($this->getProjectPath($project_id, 'variables/'.self::encodePath($key)), $resolver->resolve($parameters)); } /** - * @param int|string $project_id - * @param string $key - * @param string $value - * @param bool|null $protected - * @param string|null $environment_scope * @param array $parameters { * * @var string $variable_type env_var (default) or file * } - * - * @return mixed */ - public function addVariable($project_id, string $key, string $value, ?bool $protected = null, ?string $environment_scope = null, array $parameters = []) + public function addVariable(int|string $project_id, string $key, string $value, ?bool $protected = null, ?string $environment_scope = null, array $parameters = []): mixed { $payload = [ 'key' => $key, @@ -1007,19 +909,12 @@ public function addVariable($project_id, string $key, string $value, ?bool $prot } /** - * @param int|string $project_id - * @param string $key - * @param string $value - * @param bool|null $protected - * @param string|null $environment_scope * @param array $parameters { * * @var string $variable_type env_var (default) or file *} - * - * @return mixed */ - public function updateVariable($project_id, string $key, string $value, ?bool $protected = null, ?string $environment_scope = null, array $parameters = []) + public function updateVariable(int|string $project_id, string $key, string $value, ?bool $protected = null, ?string $environment_scope = null, array $parameters = []): mixed { $payload = [ 'value' => $value, @@ -1039,69 +934,91 @@ public function updateVariable($project_id, string $key, string $value, ?bool $p } /** - * @param int|string $project_id - * @param string $key + * @param array $parameters { * - * @return mixed + * @var array $filter { + * @var string $environment_scope Use filter[environment_scope] to select the variable with the matching environment_scope attribute. + * } + * } */ - public function removeVariable($project_id, string $key) + public function removeVariable(int|string $project_id, string $key, array $parameters = []): mixed { - return $this->delete($this->getProjectPath($project_id, 'variables/'.self::encodePath($key))); + $resolver = new OptionsResolver(); + $resolver->setDefined('filter') + ->setAllowedTypes('filter', 'array'); + + return $this->delete($this->getProjectPath($project_id, 'variables/'.self::encodePath($key)), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $file - * - * @return mixed - */ - public function uploadFile($project_id, string $file) + public function uploadFile(int|string $project_id, string $file): mixed { return $this->post($this->getProjectPath($project_id, 'uploads'), [], [], ['file' => $file]); } - /** - * @param int|string $project_id - * @param string $file - * - * @return mixed - */ - public function uploadAvatar($project_id, string $file) + public function uploadAvatar(int|string $project_id, string $file): mixed { - return $this->put($this->getProjectPath($project_id, ''), [], [], ['avatar' => $file]); + return $this->put('projects/'.self::encodePath($project_id), [], [], ['avatar' => $file]); } /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed + * @see https://docs.gitlab.com/ee/api/deployments.html#list-project-deployments */ - public function deployments($project_id, array $parameters = []) + public function deployments(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); + $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { + return $value->format('c'); + }; + + $resolver->setDefined('order_by') + ->setAllowedTypes('order_by', 'string') + ->setAllowedValues('order_by', ['id', 'iid', 'created_at', 'updated_at', 'finished_at', 'ref']) + ; + + $resolver->setDefined('sort') + ->setAllowedTypes('sort', 'string') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + + $resolver->setDefined('updated_after') + ->setAllowedTypes('updated_after', \DateTimeInterface::class) + ->setNormalizer('updated_after', $datetimeNormalizer) + ; + + $resolver->setDefined('updated_before') + ->setAllowedTypes('updated_before', \DateTimeInterface::class) + ->setNormalizer('updated_before', $datetimeNormalizer) + ; + + $resolver->setDefined('finished_after') + ->setAllowedTypes('finished_after', \DateTimeInterface::class) + ->setNormalizer('finished_after', $datetimeNormalizer) + ; + + $resolver->setDefined('finished_before') + ->setAllowedTypes('finished_before', \DateTimeInterface::class) + ->setNormalizer('finished_before', $datetimeNormalizer) + ; + + $resolver->setDefined('environment') + ->setAllowedTypes('environment', 'string') + ; + + $resolver->setDefined('status') + ->setAllowedTypes('status', 'string') + ->setAllowedValues('status', ['created', 'running', 'success', 'failed', 'canceled', 'blocked']) + ; + return $this->get($this->getProjectPath($project_id, 'deployments'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int $deployment_id - * - * @return mixed - */ - public function deployment($project_id, int $deployment_id) + public function deployment(int|string $project_id, int $deployment_id): mixed { return $this->get($this->getProjectPath($project_id, 'deployments/'.self::encodePath($deployment_id))); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function addShare($project_id, array $parameters = []) + public function addShare(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -1114,7 +1031,7 @@ public function addShare($project_id, array $parameters = []) $resolver->setRequired('group_access') ->setAllowedTypes('group_access', 'int') - ->setAllowedValues('group_access', [0, 10, 20, 30, 40, 50]); + ->setAllowedValues('group_access', self::ACCESS_LEVELS); $resolver->setDefined('expires_at') ->setAllowedTypes('expires_at', \DateTimeInterface::class) @@ -1124,191 +1041,111 @@ public function addShare($project_id, array $parameters = []) return $this->post($this->getProjectPath($project_id, 'share'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param int|string $group_id - * - * @return mixed - */ - public function removeShare($project_id, $group_id) + public function removeShare(int|string $project_id, int|string $group_id): mixed { return $this->delete($this->getProjectPath($project_id, 'share/'.$group_id)); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function badges($project_id) + public function badges(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'badges')); } - /** - * @param int|string $project_id - * @param int $badge_id - * - * @return mixed - */ - public function badge($project_id, int $badge_id) + public function badge(int|string $project_id, int $badge_id): mixed { return $this->get($this->getProjectPath($project_id, 'badges/'.self::encodePath($badge_id))); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function addBadge($project_id, array $parameters = []) + public function addBadge(int|string $project_id, array $parameters = []): mixed { return $this->post($this->getProjectPath($project_id, 'badges'), $parameters); } - /** - * @param int|string $project_id - * @param int $badge_id - * - * @return mixed - */ - public function removeBadge($project_id, int $badge_id) + public function removeBadge(int|string $project_id, int $badge_id): mixed { return $this->delete($this->getProjectPath($project_id, 'badges/'.self::encodePath($badge_id))); } - /** - * @param int|string $project_id - * @param int $badge_id - * @param array $parameters - * - * @return mixed - */ - public function updateBadge($project_id, int $badge_id, array $parameters = []) + public function updateBadge(int|string $project_id, int $badge_id, array $parameters = []): mixed { return $this->put($this->getProjectPath($project_id, 'badges/'.self::encodePath($badge_id)), $parameters); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function protectedBranches($project_id, array $parameters = []) + public function protectedBranches(int|string $project_id, array $parameters = []): mixed { return $this->get('projects/'.self::encodePath($project_id).'/protected_branches'); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function addProtectedBranch($project_id, array $parameters = []) + public function addProtectedBranch(int|string $project_id, array $parameters = []): mixed { return $this->post($this->getProjectPath($project_id, 'protected_branches'), $parameters); } - /** - * @param int|string $project_id - * @param string $branch_name - * - * @return mixed - */ - public function deleteProtectedBranch($project_id, string $branch_name) + public function deleteProtectedBranch(int|string $project_id, string $branch_name): mixed { return $this->delete($this->getProjectPath($project_id, 'protected_branches/'.self::encodePath($branch_name))); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function approvalsConfiguration($project_id) + public function updateProtectedBranch(int|string $project_id, string $branch_name, array $parameters = []): mixed + { + return $this->patch($this->getProjectPath($project_id, 'protected_branches/'.self::encodePath($branch_name)), $parameters); + } + + public function approvalsConfiguration(int|string $project_id): mixed { return $this->get('projects/'.self::encodePath($project_id).'/approvals'); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function approvalsRules($project_id) + public function updateApprovalsConfiguration(int|string $project_id, array $parameters = []): mixed + { + return $this->post('projects/'.self::encodePath($project_id).'/approvals', $parameters); + } + + public function approvalsRules(int|string $project_id): mixed { return $this->get('projects/'.self::encodePath($project_id).'/approval_rules'); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function createApprovalsRule($project_id, array $parameters = []) + public function createApprovalsRule(int|string $project_id, array $parameters = []): mixed { return $this->post('projects/'.self::encodePath($project_id).'/approval_rules/', $parameters); } - /** - * @param int|string $project_id - * @param int $approval_rule_id - * @param array $parameters - * - * @return mixed - */ - public function updateApprovalsRule($project_id, int $approval_rule_id, array $parameters = []) + public function updateApprovalsRule(int|string $project_id, int $approval_rule_id, array $parameters = []): mixed { return $this->put('projects/'.self::encodePath($project_id).'/approval_rules/'.self::encodePath($approval_rule_id), $parameters); } - /** - * @param int|string $project_id - * @param int $approval_rule_id - * - * @return mixed - */ - public function deleteApprovalsRule($project_id, int $approval_rule_id) + public function deleteApprovalsRule(int|string $project_id, int $approval_rule_id): mixed { return $this->delete('projects/'.self::encodePath($project_id).'/approval_rules/'.self::encodePath($approval_rule_id)); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function deleteAllMergedBranches($project_id) + public function deleteAllMergedBranches(int|string $project_id): mixed { return $this->delete($this->getProjectPath($project_id, 'repository/merged_branches')); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function projectAccessTokens($project_id) + public function projectAccessTokens(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'access_tokens')); } + public function projectAccessToken(int|string $project_id, int|string $token_id): mixed + { + return $this->get($this->getProjectPath($project_id, 'access_tokens/'.self::encodePath($token_id))); + } + /** - * @param int|string $project_id * @param array $parameters { * * @var string $name the name of the project access token * @var array $scopes the scopes, one or many of: api, read_api, read_registry, write_registry, read_repository, write_repository + * @var int $access_level the access level: 10 (Guest), 20 (Reporter), 30 (Developer), 40 (Maintainer), 50 (Owner) * @var \DateTimeInterface $expires_at the token expires at midnight UTC on that date * } - * - * @return mixed */ - public function createProjectAccessToken($project_id, array $parameters = []) + public function createProjectAccessToken(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { @@ -1334,6 +1171,11 @@ public function createProjectAccessToken($project_id, array $parameters = []) }) ; + $resolver->setDefined('access_level') + ->setAllowedTypes('access_level', 'int') + ->setAllowedValues('access_level', [10, 20, 30, 40, 50]) + ; + $resolver->setDefined('expires_at') ->setAllowedTypes('expires_at', \DateTimeInterface::class) ->setNormalizer('expires_at', $datetimeNormalizer) @@ -1342,14 +1184,100 @@ public function createProjectAccessToken($project_id, array $parameters = []) return $this->post($this->getProjectPath($project_id, 'access_tokens'), $resolver->resolve($parameters)); } + public function deleteProjectAccessToken(int|string $project_id, int|string $token_id): mixed + { + return $this->delete($this->getProjectPath($project_id, 'access_tokens/'.$token_id)); + } + + public function protectedTags(int|string $project_id): mixed + { + return $this->get('projects/'.self::encodePath($project_id).'/protected_tags'); + } + + public function protectedTag(int|string $project_id, string $tag_name): mixed + { + return $this->get('projects/'.self::encodePath($project_id).'/protected_tags/'.self::encodePath($tag_name)); + } + + public function addProtectedTag(int|string $project_id, array $parameters = []): mixed + { + $resolver = new OptionsResolver(); + $resolver->setDefined('name') + ->setAllowedTypes('name', 'string') + ->setRequired('name') + ; + $resolver->setDefined('create_access_level') + ->setAllowedTypes('create_access_level', 'int') + ->setAllowedValues('create_access_level', [0, 30, 40]) + ; + $resolver->setDefined('allowed_to_create') + ->setAllowedTypes('allowed_to_create', 'array') + ->setAllowedValues('allowed_to_create', function (array $value) { + $keys = \array_keys((array) \call_user_func_array('array_merge', $value)); + $diff = \array_diff($keys, ['user_id', 'group_id', 'access_level']); + $values = \array_map(function ($item) { + return \array_values($item)[0] ?? ''; + }, $value); + $integer = \count($values) === \count(\array_filter($values, 'is_int')); + + return \count($value) > 0 && 0 === \count($diff) && $integer; + }) + ; + + return $this->post($this->getProjectPath($project_id, 'protected_tags'), $resolver->resolve($parameters)); + } + + public function deleteProtectedTag(int|string $project_id, string $tag_name): mixed + { + return $this->delete($this->getProjectPath($project_id, 'protected_tags/'.self::encodePath($tag_name))); + } + /** - * @param int|string $project_id - * @param int|string $token_id + * @param array $parameters { + * + * @var string $scope The scope to search in + * @var string $search The search query + * @var string $state Filter by state. Issues and merge requests are supported; it is ignored for other scopes. + * @var string $ref The name of a repository branch or tag to search on. The project’s default branch is used by default. Applicable only for scopes blobs, commits, and wiki_blobs. + * @var bool $confidential Filter by confidentiality. Issues scope is supported; it is ignored for other scopes. + * @var string $order_by Allowed values are created_at only. If this is not set, the results are either sorted by created_at in descending order for basic search, or by the most relevant documents when using advanced search. + * @var string $sort Return projects sorted in asc or desc order (default is desc) + * } * - * @return mixed + * @throws UndefinedOptionsException If an option name is undefined + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules */ - public function deleteProjectAccessToken($project_id, $token_id) + public function search(int|string $id, array $parameters = []): mixed { - return $this->delete($this->getProjectPath($project_id, 'access_tokens/'.$token_id)); + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $resolver->setDefined('confidential') + ->setAllowedTypes('confidential', 'bool') + ->setNormalizer('confidential', $booleanNormalizer); + $scope = [ + 'blobs', + 'commits', + 'issues', + 'merge_requests', + 'milestones', + 'notes', + 'users', + 'wiki_blobs', + ]; + $resolver->setRequired('scope') + ->setAllowedValues('scope', $scope); + $resolver->setRequired('search'); + $resolver->setDefined('ref') + ->setAllowedTypes('ref', 'string'); + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at']); + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']); + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'closed']); + + return $this->get('projects/'.self::encodePath($id).'/search', $resolver->resolve($parameters)); } } diff --git a/src/Api/Repositories.php b/src/Api/Repositories.php index 6915d92d..eded16b9 100644 --- a/src/Api/Repositories.php +++ b/src/Api/Repositories.php @@ -30,15 +30,12 @@ class Repositories extends AbstractApi public const TYPE_TAG = 'tag'; /** - * @param int|string $project_id * @param array $parameters { * * @var string $search * } - * - * @return mixed */ - public function branches($project_id, array $parameters = []) + public function branches(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('search') @@ -47,25 +44,12 @@ public function branches($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'repository/branches'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $branch - * - * @return mixed - */ - public function branch($project_id, string $branch) + public function branch(int|string $project_id, string $branch): mixed { return $this->get($this->getProjectPath($project_id, 'repository/branches/'.self::encodePath($branch))); } - /** - * @param int|string $project_id - * @param string $branch - * @param string $ref - * - * @return mixed - */ - public function createBranch($project_id, string $branch, string $ref) + public function createBranch(int|string $project_id, string $branch, string $ref): mixed { return $this->post($this->getProjectPath($project_id, 'repository/branches'), [ 'branch' => $branch, @@ -73,26 +57,12 @@ public function createBranch($project_id, string $branch, string $ref) ]); } - /** - * @param int|string $project_id - * @param string $branch - * - * @return mixed - */ - public function deleteBranch($project_id, string $branch) + public function deleteBranch(int|string $project_id, string $branch): mixed { return $this->delete($this->getProjectPath($project_id, 'repository/branches/'.self::encodePath($branch))); } - /** - * @param int|string $project_id - * @param string $branch - * @param bool $devPush - * @param bool $devMerge - * - * @return mixed - */ - public function protectBranch($project_id, string $branch, bool $devPush = false, bool $devMerge = false) + public function protectBranch(int|string $project_id, string $branch, bool $devPush = false, bool $devMerge = false): mixed { return $this->put($this->getProjectPath($project_id, 'repository/branches/'.self::encodePath($branch).'/protect'), [ 'developers_can_push' => $devPush, @@ -100,24 +70,12 @@ public function protectBranch($project_id, string $branch, bool $devPush = false ]); } - /** - * @param int|string $project_id - * @param string $branch - * - * @return mixed - */ - public function unprotectBranch($project_id, string $branch) + public function unprotectBranch(int|string $project_id, string $branch): mixed { return $this->put($this->getProjectPath($project_id, 'repository/branches/'.self::encodePath($branch).'/unprotect')); } - /** - * @param int|string $project_id - * @param array $parameters - * - * @return mixed - */ - public function tags($project_id, array $parameters = []) + public function tags(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('search') @@ -126,15 +84,7 @@ public function tags($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'repository/tags'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $name - * @param string $ref - * @param string|null $message - * - * @return mixed - */ - public function createTag($project_id, string $name, string $ref, ?string $message = null) + public function createTag(int|string $project_id, string $name, string $ref, ?string $message = null): mixed { return $this->post($this->getProjectPath($project_id, 'repository/tags'), [ 'tag_name' => $name, @@ -143,44 +93,27 @@ public function createTag($project_id, string $name, string $ref, ?string $messa ]); } - /** - * @param int|string $project_id - * @param string $tag_name - * @param string $description - * - * @return mixed - */ - public function createRelease($project_id, string $tag_name, string $description) + public function createRelease(int|string $project_id, string $tag_name, string $description, ?string $name = null): mixed { - return $this->post($this->getProjectPath($project_id, 'releases'), [ + return $this->post($this->getProjectPath($project_id, 'releases'), \array_filter([ 'id' => $project_id, 'tag_name' => $tag_name, 'description' => $description, - ]); + 'name' => $name, + ], fn ($v) => null !== $v)); } - /** - * @param int|string $project_id - * @param string $tag_name - * @param string $description - * - * @return mixed - */ - public function updateRelease($project_id, string $tag_name, string $description) + public function updateRelease(int|string $project_id, string $tag_name, string $description, ?string $name = null): mixed { - return $this->put($this->getProjectPath($project_id, 'releases/'.self::encodePath($tag_name)), [ + return $this->put($this->getProjectPath($project_id, 'releases/'.self::encodePath($tag_name)), \array_filter([ 'id' => $project_id, 'tag_name' => $tag_name, 'description' => $description, - ]); + 'name' => $name, + ], fn ($v) => null !== $v)); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function releases($project_id) + public function releases(int|string $project_id): mixed { $resolver = $this->createOptionsResolver(); @@ -190,17 +123,14 @@ public function releases($project_id) /** * @see https://docs.gitlab.com/ee/api/commits.html#list-repository-commits * - * @param int|string $project_id * @param array $parameters { * * @var string $ref_name the name of a repository branch or tag or if not given the default branch * @var \DateTimeInterface $since only commits after or on this date will be returned * @var \DateTimeInterface $until Only commits before or on this date will be returned. * } - * - * @return mixed */ - public function commits($project_id, array $parameters = []) + public function commits(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $options, \DateTimeInterface $value): string { @@ -212,6 +142,7 @@ public function commits($project_id, array $parameters = []) $resolver->setDefined('path'); $resolver->setDefined('ref_name'); + $resolver->setDefined('author'); $resolver->setDefined('since') ->setAllowedTypes('since', \DateTimeInterface::class) ->setNormalizer('since', $datetimeNormalizer) @@ -239,25 +170,12 @@ public function commits($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'repository/commits'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $sha - * - * @return mixed - */ - public function commit($project_id, string $sha) + public function commit(int|string $project_id, string $sha): mixed { return $this->get($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha))); } - /** - * @param int|string $project_id - * @param string $sha - * @param array $parameters - * - * @return mixed - */ - public function commitRefs($project_id, string $sha, array $parameters = []) + public function commitRefs(int|string $project_id, string $sha, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -268,7 +186,6 @@ public function commitRefs($project_id, string $sha, array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $branch Name of the branch to commit into. To create a new branch, also provide start_branch. @@ -284,10 +201,8 @@ public function commitRefs($project_id, string $sha, array $parameters = []) * @var string $author_email specify the commit author's email address * @var string $author_name Specify the commit author's name. * } - * - * @return mixed */ - public function createCommit($project_id, array $parameters = []) + public function createCommit(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setDefined('branch') @@ -307,7 +222,7 @@ public function createCommit($project_id, array $parameters = []) $actionsOptionsResolver = new OptionsResolver(); $actionsOptionsResolver->setDefined('action') ->setRequired('action') - ->setAllowedValues('action', ['create', 'delete', 'move', 'update']) + ->setAllowedValues('action', ['create', 'delete', 'move', 'update', 'chmod']) ; $actionsOptionsResolver->setDefined('file_path') ->setRequired('file_path') @@ -317,6 +232,9 @@ public function createCommit($project_id, array $parameters = []) $actionsOptionsResolver->setDefined('encoding') ->setAllowedValues('encoding', ['text', 'base64']) ; + $actionsOptionsResolver->setDefined('execute_filemode') + ->setAllowedValues('execute_filemode', [true, false]) + ; return \array_map(function ($action) use ($actionsOptionsResolver) { return $actionsOptionsResolver->resolve($action); @@ -329,28 +247,14 @@ public function createCommit($project_id, array $parameters = []) return $this->post($this->getProjectPath($project_id, 'repository/commits'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $branch - * @param string $sha - * - * @return mixed - */ - public function revertCommit($project_id, string $branch, string $sha) + public function revertCommit(int|string $project_id, string $branch, string $sha): mixed { return $this->post($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha).'/revert'), [ 'branch' => $branch, ]); } - /** - * @param int|string $project_id - * @param string $sha - * @param array $parameters - * - * @return mixed - */ - public function commitComments($project_id, string $sha, array $parameters = []) + public function commitComments(int|string $project_id, string $sha, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); @@ -360,58 +264,26 @@ public function commitComments($project_id, string $sha, array $parameters = []) ); } - /** - * @param int|string $project_id - * @param string $sha - * @param string $note - * @param array $params - * - * @return mixed - */ - public function createCommitComment($project_id, string $sha, string $note, array $params = []) + public function createCommitComment(int|string $project_id, string $sha, string $note, array $params = []): mixed { $params['note'] = $note; return $this->post($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha).'/comments'), $params); } - /** - * @param int|string $project_id - * @param string $sha - * @param array $params - * - * @return mixed - */ - public function getCommitBuildStatus($project_id, string $sha, array $params = []) + public function getCommitBuildStatus(int|string $project_id, string $sha, array $params = []): mixed { return $this->get($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha).'/statuses'), $params); } - /** - * @param int|string $project_id - * @param string $sha - * @param string $state - * @param array $params - * - * @return mixed - */ - public function postCommitBuildStatus($project_id, string $sha, string $state, array $params = []) + public function postCommitBuildStatus(int|string $project_id, string $sha, string $state, array $params = []): mixed { $params['state'] = $state; return $this->post($this->getProjectPath($project_id, 'statuses/'.self::encodePath($sha)), $params); } - /** - * @param int|string $project_id - * @param string $fromShaOrMaster - * @param string $toShaOrMaster - * @param bool $straight - * @param string|null $fromProjectId - * - * @return mixed - */ - public function compare($project_id, string $fromShaOrMaster, string $toShaOrMaster, bool $straight = false, string $fromProjectId = null) + public function compare(int|string $project_id, string $fromShaOrMaster, string $toShaOrMaster, bool $straight = false, ?string $fromProjectId = null): mixed { $params = [ 'from' => $fromShaOrMaster, @@ -426,69 +298,35 @@ public function compare($project_id, string $fromShaOrMaster, string $toShaOrMas return $this->get($this->getProjectPath($project_id, 'repository/compare'), $params); } - /** - * @param int|string $project_id - * @param string $sha - * - * @return mixed - */ - public function diff($project_id, string $sha) + public function diff(int|string $project_id, string $sha): mixed { return $this->get($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha).'/diff')); } - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function tree($project_id, array $params = []) + public function tree(int|string $project_id, array $params = []): mixed { return $this->get($this->getProjectPath($project_id, 'repository/tree'), $params); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function contributors($project_id) + public function contributors(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'repository/contributors')); } /** - * @param int|string $project_id - * @param array $params * @param string $format Options: "tar.gz", "zip", "tar.bz2" and "tar" - * - * @return mixed */ - public function archive($project_id, array $params = [], string $format = 'tar.gz') + public function archive(int|string $project_id, array $params = [], string $format = 'tar.gz'): mixed { return $this->get($this->getProjectPath($project_id, 'repository/archive.'.$format), $params); } - /** - * @param int|string $project_id - * @param array $refs - * - * @return mixed - */ - public function mergeBase($project_id, array $refs) + public function mergeBase(int|string $project_id, array $refs): mixed { return $this->get($this->getProjectPath($project_id, 'repository/merge_base'), ['refs' => $refs]); } - /** - * @param int|string $project_id - * @param string $sha - * @param array $params - * - * @return mixed - */ - public function cherryPick($project_id, string $sha, array $params = []) + public function cherryPick(int|string $project_id, string $sha, array $params = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -505,9 +343,6 @@ public function cherryPick($project_id, string $sha, array $params = []) return $this->post($this->getProjectPath($project_id, 'repository/commits/'.self::encodePath($sha).'/cherry_pick'), $params); } - /** - * @return OptionsResolver - */ protected function createOptionsResolver(): OptionsResolver { $allowedTypeValues = [ diff --git a/src/Api/RepositoryFiles.php b/src/Api/RepositoryFiles.php index be94b4ee..80f303ad 100644 --- a/src/Api/RepositoryFiles.php +++ b/src/Api/RepositoryFiles.php @@ -18,28 +18,14 @@ class RepositoryFiles extends AbstractApi { - /** - * @param int|string $project_id - * @param string $file_path - * @param string $ref - * - * @return mixed - */ - public function getFile($project_id, string $file_path, string $ref) + public function getFile(int|string $project_id, string $file_path, string $ref): mixed { return $this->get($this->getProjectPath($project_id, 'repository/files/'.self::encodePath($file_path)), [ 'ref' => $ref, ]); } - /** - * @param int|string $project_id - * @param string $file_path - * @param string $ref - * - * @return mixed - */ - public function getRawFile($project_id, string $file_path, string $ref) + public function getRawFile(int|string $project_id, string $file_path, string $ref): mixed { return $this->get($this->getProjectPath($project_id, 'repository/files/'.self::encodePath($file_path).'/raw'), [ 'ref' => $ref, @@ -47,7 +33,6 @@ public function getRawFile($project_id, string $file_path, string $ref) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. @@ -59,10 +44,8 @@ public function getRawFile($project_id, string $file_path, string $ref) * @var string $content file content * @var string $commit_message Commit message. * } - * - * @return mixed */ - public function createFile($project_id, array $parameters = []) + public function createFile(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setRequired('file_path'); @@ -82,7 +65,6 @@ public function createFile($project_id, array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. @@ -95,10 +77,8 @@ public function createFile($project_id, array $parameters = []) * @var string $commit_message commit message * @var string $last_commit_id last known file commit id * } - * - * @return mixed */ - public function updateFile($project_id, array $parameters = []) + public function updateFile(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setRequired('file_path'); @@ -119,7 +99,6 @@ public function updateFile($project_id, array $parameters = []) } /** - * @param int|string $project_id * @param array $parameters { * * @var string $file_path Url encoded full path to new file. Ex. lib%2Fclass%2Erb. @@ -129,10 +108,8 @@ public function updateFile($project_id, array $parameters = []) * @var string $author_name specify the commit author's name * @var string $commit_message Commit message. * } - * - * @return mixed */ - public function deleteFile($project_id, array $parameters = []) + public function deleteFile(int|string $project_id, array $parameters = []): mixed { $resolver = new OptionsResolver(); $resolver->setRequired('file_path'); diff --git a/src/Api/ResourceIterationEvents.php b/src/Api/ResourceIterationEvents.php new file mode 100644 index 00000000..f18edb75 --- /dev/null +++ b/src/Api/ResourceIterationEvents.php @@ -0,0 +1,33 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class ResourceIterationEvents extends AbstractApi +{ + public function all(int|string $project_id, int $issue_iid): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_iteration_events'; + + return $this->get($this->getProjectPath($project_id, $path)); + } + + public function show(int|string $project_id, int $issue_iid, int $resource_iteration_event_id): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_iteration_events/'; + $path .= self::encodePath($resource_iteration_event_id); + + return $this->get($this->getProjectPath($project_id, $path)); + } +} diff --git a/src/Api/ResourceLabelEvents.php b/src/Api/ResourceLabelEvents.php new file mode 100644 index 00000000..9ccf6567 --- /dev/null +++ b/src/Api/ResourceLabelEvents.php @@ -0,0 +1,33 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class ResourceLabelEvents extends AbstractApi +{ + public function all(int|string $project_id, int $issue_iid): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_label_events'; + + return $this->get($this->getProjectPath($project_id, $path)); + } + + public function show(int|string $project_id, int $issue_iid, int $resource_label_event_id): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_label_events/'; + $path .= self::encodePath($resource_label_event_id); + + return $this->get($this->getProjectPath($project_id, $path)); + } +} diff --git a/src/Api/ResourceMilestoneEvents.php b/src/Api/ResourceMilestoneEvents.php new file mode 100644 index 00000000..be4adb47 --- /dev/null +++ b/src/Api/ResourceMilestoneEvents.php @@ -0,0 +1,33 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class ResourceMilestoneEvents extends AbstractApi +{ + public function all(int|string $project_id, int $issue_iid): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_milestone_events'; + + return $this->get($this->getProjectPath($project_id, $path)); + } + + public function show(int|string $project_id, int $issue_iid, int $resource_milestone_event_id): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_milestone_events/'; + $path .= self::encodePath($resource_milestone_event_id); + + return $this->get($this->getProjectPath($project_id, $path)); + } +} diff --git a/src/Api/ResourceStateEvents.php b/src/Api/ResourceStateEvents.php new file mode 100644 index 00000000..be03a6d5 --- /dev/null +++ b/src/Api/ResourceStateEvents.php @@ -0,0 +1,33 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class ResourceStateEvents extends AbstractApi +{ + public function all(int|string $project_id, int $issue_iid): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_state_events'; + + return $this->get($this->getProjectPath($project_id, $path)); + } + + public function show(int|string $project_id, int $issue_iid, int $resource_label_event_id): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_state_events/'; + $path .= self::encodePath($resource_label_event_id); + + return $this->get($this->getProjectPath($project_id, $path)); + } +} diff --git a/src/Api/ResourceWeightEvents.php b/src/Api/ResourceWeightEvents.php new file mode 100644 index 00000000..53a7b162 --- /dev/null +++ b/src/Api/ResourceWeightEvents.php @@ -0,0 +1,33 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +class ResourceWeightEvents extends AbstractApi +{ + public function all(int|string $project_id, int $issue_iid): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_weight_events'; + + return $this->get($this->getProjectPath($project_id, $path)); + } + + public function show(int|string $project_id, int $issue_iid, int $resource_label_event_id): mixed + { + $path = 'issues/'.self::encodePath($issue_iid).'/resource_weight_events/'; + $path .= self::encodePath($resource_label_event_id); + + return $this->get($this->getProjectPath($project_id, $path)); + } +} diff --git a/src/Api/Schedules.php b/src/Api/Schedules.php index 9be61928..44b61964 100644 --- a/src/Api/Schedules.php +++ b/src/Api/Schedules.php @@ -16,101 +16,59 @@ class Schedules extends AbstractApi { - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function create($project_id, array $params) + public function create(int|string $project_id, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'pipeline_schedules'), $params); } - /** - * @param int|string $project_id - * @param int $schedule_id - * - * @return mixed - */ - public function show($project_id, int $schedule_id) + public function show(int|string $project_id, int $schedule_id): mixed { return $this->get($this->getProjectPath($project_id, 'pipeline_schedules/'.self::encodePath($schedule_id))); } - /** - * @param int|string $project_id - * - * @return mixed - */ - public function showAll($project_id) + public function showAll(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'pipeline_schedules')); } - /** - * @param int|string $project_id - * @param int $schedule_id - * @param array $params - * - * @return mixed - */ - public function update($project_id, int $schedule_id, array $params) + public function update(int|string $project_id, int $schedule_id, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'pipeline_schedules/'.self::encodePath($schedule_id)), $params); } - /** - * @param int|string $project_id - * @param int $schedule_id - * - * @return mixed - */ - public function remove($project_id, int $schedule_id) + public function remove(int|string $project_id, int $schedule_id): mixed { return $this->delete($this->getProjectPath($project_id, 'pipeline_schedules/'.self::encodePath($schedule_id))); } - /** - * @param int|string $project_id - * @param int $schedule_id - * @param array $params - * - * @return mixed - */ - public function addVariable($project_id, int $schedule_id, array $params) + public function addVariable(int|string $project_id, int $schedule_id, array $params): mixed { $path = 'pipeline_schedules/'.self::encodePath($schedule_id).'/variables'; return $this->post($this->getProjectPath($project_id, $path), $params); } - /** - * @param int|string $project_id - * @param int $schedule_id - * @param string $variable_key - * @param array $params - * - * @return mixed - */ - public function updateVariable($project_id, int $schedule_id, string $variable_key, array $params) + public function updateVariable(int|string $project_id, int $schedule_id, string $variable_key, array $params): mixed { $path = 'pipeline_schedules/'.self::encodePath($schedule_id).'/variables/'.self::encodePath($variable_key); return $this->put($this->getProjectPath($project_id, $path), $params); } - /** - * @param int|string $project_id - * @param int $schedule_id - * @param string $variable_key - * - * @return mixed - */ - public function removeVariable($project_id, int $schedule_id, string $variable_key) + public function removeVariable(int|string $project_id, int $schedule_id, string $variable_key): mixed { $path = 'pipeline_schedules/'.self::encodePath($schedule_id).'/variables/'.self::encodePath($variable_key); return $this->delete($this->getProjectPath($project_id, $path)); } + + public function takeOwnership(int|string $project_id, int $schedule_id): mixed + { + return $this->post($this->getProjectPath($project_id, 'pipeline_schedules/'.self::encodePath($schedule_id)).'/take_ownership'); + } + + public function play(int|string $project_id, int $schedule_id): mixed + { + return $this->post($this->getProjectPath($project_id, 'pipeline_schedules/'.self::encodePath($schedule_id)).'/play'); + } } diff --git a/src/Api/Search.php b/src/Api/Search.php new file mode 100644 index 00000000..a7685bd6 --- /dev/null +++ b/src/Api/Search.php @@ -0,0 +1,70 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Api; + +use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; +use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; +use Symfony\Component\OptionsResolver\Options; + +class Search extends AbstractApi +{ + /** + * @param array $parameters { + * + * @var string $scope The scope to search in + * @var string $search The search query + * @var string $state Filter by state. Issues and merge requests are supported; it is ignored for other scopes. + * @var bool $confidential Filter by confidentiality. Issues scope is supported; it is ignored for other scopes. + * @var string $order_by Allowed values are created_at only. If this is not set, the results are either sorted by created_at in descending order for basic search, or by the most relevant documents when using advanced search. + * @var string $sort Return projects sorted in asc or desc order (default is desc) + * } + * + * @throws UndefinedOptionsException If an option name is undefined + * @throws InvalidOptionsException If an option doesn't fulfill the specified validation rules + */ + public function all(array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $resolver->setDefined('confidential') + ->setAllowedTypes('confidential', 'bool') + ->setNormalizer('confidential', $booleanNormalizer); + $scope = [ + 'projects', + 'issues', + 'merge_requests', + 'milestones', + 'snippet_titles', + 'wiki_blobs', + 'commits', + 'blobs', + 'notes', + 'users', + ]; + $resolver->setRequired('scope') + ->setAllowedValues('scope', $scope); + $resolver->setRequired('search'); + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['created_at']); + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']); + $resolver->setDefined('state') + ->setAllowedValues('state', ['opened', 'closed']); + + return $this->get('search', $resolver->resolve($parameters)); + } +} diff --git a/src/Api/Snippets.php b/src/Api/Snippets.php index ed36b19f..d62e174e 100644 --- a/src/Api/Snippets.php +++ b/src/Api/Snippets.php @@ -16,37 +16,17 @@ class Snippets extends AbstractApi { - /** - * @param int|string $project_id - * - * @return mixed - */ - public function all($project_id) + public function all(int|string $project_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets')); } - /** - * @param int|string $project_id - * @param int $snippet_id - * - * @return mixed - */ - public function show($project_id, int $snippet_id) + public function show(int|string $project_id, int $snippet_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id))); } - /** - * @param int|string $project_id - * @param string $title - * @param string $filename - * @param string $code - * @param string $visibility - * - * @return mixed - */ - public function create($project_id, string $title, string $filename, string $code, string $visibility) + public function create(int|string $project_id, string $title, string $filename, string $code, string $visibility): mixed { return $this->post($this->getProjectPath($project_id, 'snippets'), [ 'title' => $title, @@ -56,124 +36,56 @@ public function create($project_id, string $title, string $filename, string $cod ]); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param array $params - * - * @return mixed - */ - public function update($project_id, int $snippet_id, array $params) + public function update(int|string $project_id, int $snippet_id, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id)), $params); } - /** - * @param int|string $project_id - * @param int $snippet_id - * - * @return mixed - */ - public function content($project_id, int $snippet_id) + public function content(int|string $project_id, int $snippet_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/raw')); } - /** - * @param int|string $project_id - * @param int $snippet_id - * - * @return mixed - */ - public function remove($project_id, int $snippet_id) + public function remove(int|string $project_id, int $snippet_id): mixed { return $this->delete($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id))); } - /** - * @param int|string $project_id - * @param int $snippet_id - * - * @return mixed - */ - public function showNotes($project_id, int $snippet_id) + public function showNotes(int|string $project_id, int $snippet_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/notes')); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param int $note_id - * - * @return mixed - */ - public function showNote($project_id, int $snippet_id, int $note_id) + public function showNote(int|string $project_id, int $snippet_id, int $note_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param string $body - * @param array $params - * - * @return mixed - */ - public function addNote($project_id, int $snippet_id, string $body, array $params = []) + public function addNote(int|string $project_id, int $snippet_id, string $body, array $params = []): mixed { $params['body'] = $body; return $this->post($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/notes'), $params); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param int $note_id - * @param string $body - * - * @return mixed - */ - public function updateNote($project_id, int $snippet_id, int $note_id, string $body) + public function updateNote(int|string $project_id, int $snippet_id, int $note_id, string $body): mixed { return $this->put($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/notes/'.self::encodePath($note_id)), [ 'body' => $body, ]); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param int $note_id - * - * @return mixed - */ - public function removeNote($project_id, int $snippet_id, int $note_id) + public function removeNote(int|string $project_id, int $snippet_id, int $note_id): mixed { return $this->delete($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/notes/'.self::encodePath($note_id))); } - /** - * @param int|string $project_id - * @param int $snippet_id - * - * @return mixed - */ - public function awardEmoji($project_id, int $snippet_id) + public function awardEmoji(int|string $project_id, int $snippet_id): mixed { return $this->get($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/award_emoji')); } - /** - * @param int|string $project_id - * @param int $snippet_id - * @param int $award_id - * - * @return mixed - */ - public function removeAwardEmoji($project_id, int $snippet_id, int $award_id) + public function removeAwardEmoji(int|string $project_id, int $snippet_id, int $award_id): mixed { return $this->delete($this->getProjectPath($project_id, 'snippets/'.self::encodePath($snippet_id).'/award_emoji/'.self::encodePath($award_id))); } diff --git a/src/Api/SystemHooks.php b/src/Api/SystemHooks.php index 24e9fc03..f068429d 100644 --- a/src/Api/SystemHooks.php +++ b/src/Api/SystemHooks.php @@ -14,45 +14,81 @@ namespace Gitlab\Api; +use Symfony\Component\OptionsResolver\Options; +use Symfony\Component\OptionsResolver\OptionsResolver; + class SystemHooks extends AbstractApi { - /** - * @return mixed - */ - public function all() + public function all(): mixed { return $this->get('hooks'); } /** - * @param string $url + * @param array $parameters { * - * @return mixed + * @var string $token secret token to validate received payloads + * @var bool $push_events when true, the hook fires on push events + * @var bool $tag_push_events when true, the hook fires on new tags being pushed + * @var bool $merge_requests_events trigger hook on merge requests events + * @var bool $repository_update_events trigger hook on repository update events + * @var bool $enable_ssl_verification do SSL verification when triggering the hook + * } */ - public function create(string $url) + public function create(string $url, array $parameters = []): mixed { - return $this->post('hooks', [ - 'url' => $url, - ]); + $parameters = $this->createOptionsResolver()->resolve($parameters); + + $parameters['url'] = $url; + + return $this->post('hooks', $parameters); } - /** - * @param int $id - * - * @return mixed - */ - public function test(int $id) + public function test(int $id): mixed { return $this->get('hooks/'.self::encodePath($id)); } - /** - * @param int $id - * - * @return mixed - */ - public function remove(int $id) + public function remove(int $id): mixed { return $this->delete('hooks/'.self::encodePath($id)); } + + protected function createOptionsResolver(): OptionsResolver + { + $resolver = new OptionsResolver(); + + $resolver->setDefined('token'); + + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + + $resolver->setDefined('push_events') + ->setAllowedTypes('push_events', 'bool') + ->setNormalizer('push_events', $booleanNormalizer) + ; + + $resolver->setDefined('tag_push_events') + ->setAllowedTypes('tag_push_events', 'bool') + ->setNormalizer('tag_push_events', $booleanNormalizer) + ; + + $resolver->setDefined('merge_requests_events') + ->setAllowedTypes('merge_requests_events', 'bool') + ->setNormalizer('merge_requests_events', $booleanNormalizer) + ; + + $resolver->setDefined('repository_update_events') + ->setAllowedTypes('repository_update_events', 'bool') + ->setNormalizer('repository_update_events', $booleanNormalizer) + ; + + $resolver->setDefined('enable_ssl_verification') + ->setAllowedTypes('enable_ssl_verification', 'bool') + ->setNormalizer('enable_ssl_verification', $booleanNormalizer) + ; + + return $resolver; + } } diff --git a/src/Api/Tags.php b/src/Api/Tags.php index eed1c58f..8085d763 100644 --- a/src/Api/Tags.php +++ b/src/Api/Tags.php @@ -17,22 +17,19 @@ class Tags extends AbstractApi { /** - * @param int|string $project_id * @param array $parameters { * - * @var string $order_by Return tags ordered by `name` or `updated` fields. Default is `updated`. + * @var string $order_by Return tags ordered by `name`, `updated` or `version` fields. Default is `updated`. * @var string $sort Return tags sorted in asc or desc order. Default is desc. * @var string $search Return list of tags matching the search criteria. You can use `^term` and `term$` to * find tags that begin and end with term respectively. * } - * - * @return mixed */ - public function all($project_id, array $parameters = []) + public function all(int|string $project_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('order_by') - ->setAllowedValues('order_by', ['name', 'updated']); + ->setAllowedValues('order_by', ['name', 'updated', 'version']); $resolver->setDefined('sort') ->setAllowedValues('sort', ['asc', 'desc']); $resolver->setDefined('search'); @@ -40,59 +37,27 @@ public function all($project_id, array $parameters = []) return $this->get($this->getProjectPath($project_id, 'repository/tags'), $resolver->resolve($parameters)); } - /** - * @param int|string $project_id - * @param string $tag_name - * - * @return mixed - */ - public function show($project_id, string $tag_name) + public function show(int|string $project_id, string $tag_name): mixed { return $this->get($this->getProjectPath($project_id, 'repository/tags/'.self::encodePath($tag_name))); } - /** - * @param int|string $project_id - * @param array $params - * - * @return mixed - */ - public function create($project_id, array $params = []) + public function create(int|string $project_id, array $params = []): mixed { return $this->post($this->getProjectPath($project_id, 'repository/tags'), $params); } - /** - * @param int|string $project_id - * @param string $tag_name - * - * @return mixed - */ - public function remove($project_id, string $tag_name) + public function remove(int|string $project_id, string $tag_name): mixed { return $this->delete($this->getProjectPath($project_id, 'repository/tags/'.self::encodePath($tag_name))); } - /** - * @param int|string $project_id - * @param string $tag_name - * @param array $params - * - * @return mixed - */ - public function createRelease($project_id, string $tag_name, array $params = []) + public function createRelease(int|string $project_id, string $tag_name, array $params = []): mixed { return $this->post($this->getProjectPath($project_id, 'repository/tags/'.self::encodePath($tag_name).'/release'), $params); } - /** - * @param int|string $project_id - * @param string $tag_name - * @param array $params - * - * @return mixed - */ - public function updateRelease($project_id, string $tag_name, array $params = []) + public function updateRelease(int|string $project_id, string $tag_name, array $params = []): mixed { return $this->put($this->getProjectPath($project_id, 'repository/tags/'.self::encodePath($tag_name).'/release'), $params); } diff --git a/src/Api/Users.php b/src/Api/Users.php index a1cbff80..01fd1ff3 100644 --- a/src/Api/Users.php +++ b/src/Api/Users.php @@ -31,10 +31,8 @@ class Users extends AbstractApi * @var bool $active Return only active users. It does not support filtering inactive users. * @var bool $blocked Return only blocked users. It does not support filtering non-blocked users. * } - * - * @return mixed */ - public function all(array $parameters = []) + public function all(array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { @@ -68,26 +66,18 @@ public function all(array $parameters = []) return $this->get('users', $resolver->resolve($parameters)); } - /** - * @param int $id - * - * @return mixed - */ - public function show(int $id) + public function show(int $id): mixed { return $this->get('users/'.self::encodePath($id)); } /** - * @param int $id * @param array $parameters { * * @var string $type Filter memberships by type. Can be either Project or Namespace * } - * - * @return mixed */ - public function usersMemberships(int $id, array $parameters = []) + public function usersMemberships(int $id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $resolver->setDefined('type') @@ -98,7 +88,6 @@ public function usersMemberships(int $id, array $parameters = []) } /** - * @param int $id * @param array $parameters { * * @var bool $archived limit by archived status @@ -116,10 +105,8 @@ public function usersMemberships(int $id, array $parameters = []) * @var bool $with_merge_requests_enabled limit by enabled merge requests feature * @var int $min_access_level Limit by current user minimal access level * } - * - * @return mixed */ - public function usersProjects(int $id, array $parameters = []) + public function usersProjects(int $id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $booleanNormalizer = function (Options $resolver, $value): string { @@ -175,21 +162,90 @@ public function usersProjects(int $id, array $parameters = []) } /** - * @return mixed + * @param array $parameters { + * + * @var bool $archived limit by archived status + * @var string $visibility limit by visibility public, internal, or private + * @var string $order_by Return projects ordered by id, name, path, created_at, updated_at, + * or last_activity_at fields (default is created_at) + * @var string $sort Return projects sorted in asc or desc order (default is desc) + * @var string $search return list of projects matching the search criteria + * @var bool $simple return only the ID, URL, name, and path of each project + * @var bool $owned limit by projects owned by the current user + * @var bool $membership limit by projects that the current user is a member of + * @var bool $starred limit by projects starred by the current user + * @var bool $statistics include project statistics + * @var bool $with_issues_enabled limit by enabled issues feature + * @var bool $with_merge_requests_enabled limit by enabled merge requests feature + * @var int $min_access_level Limit by current user minimal access level + * @var bool $with_custom_attributes Include custom attributes in response (administrator only) + * } */ - public function user() + public function usersStarredProjects(int $id, array $parameters = []): mixed + { + $resolver = $this->createOptionsResolver(); + $booleanNormalizer = function (Options $resolver, $value): string { + return $value ? 'true' : 'false'; + }; + $resolver->setDefined('archived') + ->setAllowedTypes('archived', 'bool') + ->setNormalizer('archived', $booleanNormalizer) + ; + $resolver->setDefined('visibility') + ->setAllowedValues('visibility', ['public', 'internal', 'private']) + ; + $resolver->setDefined('order_by') + ->setAllowedValues('order_by', ['id', 'name', 'path', 'created_at', 'updated_at', 'last_activity_at']) + ; + $resolver->setDefined('sort') + ->setAllowedValues('sort', ['asc', 'desc']) + ; + $resolver->setDefined('search'); + $resolver->setDefined('simple') + ->setAllowedTypes('simple', 'bool') + ->setNormalizer('simple', $booleanNormalizer) + ; + $resolver->setDefined('owned') + ->setAllowedTypes('owned', 'bool') + ->setNormalizer('owned', $booleanNormalizer) + ; + $resolver->setDefined('membership') + ->setAllowedTypes('membership', 'bool') + ->setNormalizer('membership', $booleanNormalizer) + ; + $resolver->setDefined('starred') + ->setAllowedTypes('starred', 'bool') + ->setNormalizer('starred', $booleanNormalizer) + ; + $resolver->setDefined('statistics') + ->setAllowedTypes('statistics', 'bool') + ->setNormalizer('statistics', $booleanNormalizer) + ; + $resolver->setDefined('with_issues_enabled') + ->setAllowedTypes('with_issues_enabled', 'bool') + ->setNormalizer('with_issues_enabled', $booleanNormalizer) + ; + $resolver->setDefined('with_merge_requests_enabled') + ->setAllowedTypes('with_merge_requests_enabled', 'bool') + ->setNormalizer('with_merge_requests_enabled', $booleanNormalizer) + ; + $resolver->setDefined('min_access_level') + ->setAllowedValues('min_access_level', [null, 10, 20, 30, 40, 50]) + ; + $resolver->setDefined('with_custom_attributes') + ->setAllowedTypes('with_custom_attributes', 'bool') + ->setNormalizer('with_custom_attributes', $booleanNormalizer) + ; + + return $this->get('users/'.self::encodePath($id).'/starred_projects', $resolver->resolve($parameters)); + } + + public function user(): mixed { return $this->get('user'); } - /** - * @param string $email - * @param string $password - * @param array $params - * - * @return mixed - */ - public function create(string $email, string $password, array $params = []) + public function create(string $email, string $password, array $params = []): mixed { $params['email'] = $email; $params['password'] = $password; @@ -197,106 +253,59 @@ public function create(string $email, string $password, array $params = []) return $this->post('users', $params); } - /** - * @param int $id - * @param array $params - * @param array $files - * - * @return mixed - */ - public function update(int $id, array $params, array $files = []) + public function update(int $id, array $params, array $files = []): mixed { return $this->put('users/'.self::encodePath($id), $params, [], $files); } /** - * @param int $id * @param array $params { * * @var bool $hard_delete If true, contributions that would usually be moved to the ghost user are * deleted instead, as well as groups owned solely by this user. * } - * - * @return mixed */ - public function remove(int $id, array $params = []) + public function remove(int $id, array $params = []): mixed { return $this->delete('users/'.self::encodePath($id), $params); } - /** - * @param int $id - * - * @return mixed - */ - public function block(int $id) + public function block(int $id): mixed { return $this->post('users/'.self::encodePath($id).'/block'); } - /** - * @param int $id - * - * @return mixed - */ - public function unblock(int $id) + public function unblock(int $id): mixed { return $this->post('users/'.self::encodePath($id).'/unblock'); } - /** - * @param int $id - * - * @return mixed - */ - public function activate(int $id) + public function activate(int $id): mixed { return $this->post('users/'.self::encodePath($id).'/activate'); } - /** - * @param int $id - * - * @return mixed - */ - public function deactivate(int $id) + public function deactivate(int $id): mixed { return $this->post('users/'.self::encodePath($id).'/deactivate'); } - /** - * @return mixed - */ - public function me() + public function me(): mixed { return $this->get('user'); } - /** - * @return mixed - */ - public function keys() + public function keys(): mixed { return $this->get('user/keys'); } - /** - * @param int $id - * - * @return mixed - */ - public function key(int $id) + public function key(int $id): mixed { return $this->get('user/keys/'.self::encodePath($id)); } - /** - * @param string $title - * @param string $key - * - * @return mixed - */ - public function createKey(string $title, string $key) + public function createKey(string $title, string $key): mixed { return $this->post('user/keys', [ 'title' => $title, @@ -304,45 +313,22 @@ public function createKey(string $title, string $key) ]); } - /** - * @param int $id - * - * @return mixed - */ - public function removeKey(int $id) + public function removeKey(int $id): mixed { return $this->delete('user/keys/'.self::encodePath($id)); } - /** - * @param int $user_id - * - * @return mixed - */ - public function userKeys(int $user_id) + public function userKeys(int $user_id): mixed { return $this->get('users/'.self::encodePath($user_id).'/keys'); } - /** - * @param int $user_id - * @param int $key_id - * - * @return mixed - */ - public function userKey(int $user_id, int $key_id) + public function userKey(int $user_id, int $key_id): mixed { return $this->get('users/'.self::encodePath($user_id).'/keys/'.self::encodePath($key_id)); } - /** - * @param int $user_id - * @param string $title - * @param string $key - * - * @return mixed - */ - public function createKeyForUser(int $user_id, string $title, string $key) + public function createKeyForUser(int $user_id, string $title, string $key): mixed { return $this->post('users/'.self::encodePath($user_id).'/keys', [ 'title' => $title, @@ -350,53 +336,27 @@ public function createKeyForUser(int $user_id, string $title, string $key) ]); } - /** - * @param int $user_id - * @param int $key_id - * - * @return mixed - */ - public function removeUserKey(int $user_id, int $key_id) + public function removeUserKey(int $user_id, int $key_id): mixed { return $this->delete('users/'.self::encodePath($user_id).'/keys/'.self::encodePath($key_id)); } - /** - * @return mixed - */ - public function emails() + public function emails(): mixed { return $this->get('user/emails'); } - /** - * @param int $id - * - * @return mixed - */ - public function email(int $id) + public function email(int $id): mixed { return $this->get('user/emails/'.self::encodePath($id)); } - /** - * @param int $user_id - * - * @return mixed - */ - public function userEmails(int $user_id) + public function userEmails(int $user_id): mixed { return $this->get('users/'.self::encodePath($user_id).'/emails'); } - /** - * @param int $user_id - * @param string $email - * @param bool $skip_confirmation - * - * @return mixed - */ - public function createEmailForUser(int $user_id, string $email, bool $skip_confirmation = false) + public function createEmailForUser(int $user_id, string $email, bool $skip_confirmation = false): mixed { return $this->post('users/'.self::encodePath($user_id).'/emails', [ 'email' => $email, @@ -404,24 +364,12 @@ public function createEmailForUser(int $user_id, string $email, bool $skip_confi ]); } - /** - * @param int $user_id - * @param int $email_id - * - * @return mixed - */ - public function removeUserEmail(int $user_id, int $email_id) + public function removeUserEmail(int $user_id, int $email_id): mixed { return $this->delete('users/'.self::encodePath($user_id).'/emails/'.self::encodePath($email_id)); } - /** - * @param int $user_id - * @param array $params - * - * @return mixed - */ - public function userImpersonationTokens(int $user_id, array $params = []) + public function userImpersonationTokens(int $user_id, array $params = []): mixed { $resolver = $this->createOptionsResolver(); @@ -432,26 +380,12 @@ public function userImpersonationTokens(int $user_id, array $params = []) return $this->get('users/'.self::encodePath($user_id).'/impersonation_tokens', $resolver->resolve($params)); } - /** - * @param int $user_id - * @param int $impersonation_token_id - * - * @return mixed - */ - public function userImpersonationToken(int $user_id, int $impersonation_token_id) + public function userImpersonationToken(int $user_id, int $impersonation_token_id): mixed { return $this->get('users/'.self::encodePath($user_id).'/impersonation_tokens/'.self::encodePath($impersonation_token_id)); } - /** - * @param int $user_id - * @param string $name - * @param array $scopes - * @param string|null $expires_at - * - * @return mixed - */ - public function createImpersonationToken(int $user_id, string $name, array $scopes, ?string $expires_at = null) + public function createImpersonationToken(int $user_id, string $name, array $scopes, ?string $expires_at = null): mixed { return $this->post('users/'.self::encodePath($user_id).'/impersonation_tokens', [ 'name' => $name, @@ -460,19 +394,12 @@ public function createImpersonationToken(int $user_id, string $name, array $scop ]); } - /** - * @param int $user_id - * @param int $impersonation_token_id - * - * @return mixed - */ - public function removeImpersonationToken(int $user_id, int $impersonation_token_id) + public function removeImpersonationToken(int $user_id, int $impersonation_token_id): mixed { return $this->delete('users/'.self::encodePath($user_id).'/impersonation_tokens/'.self::encodePath($impersonation_token_id)); } /** - * @param int $user_id * @param array $parameters { * * @var string $action include only events of a particular action type @@ -481,10 +408,8 @@ public function removeImpersonationToken(int $user_id, int $impersonation_token_ * @var \DateTimeInterface $after include only events created after a particular date * @var string $sort Sort events in asc or desc order by created_at (default is desc) * } - * - * @return mixed */ - public function events(int $user_id, array $parameters = []) + public function events(int $user_id, array $parameters = []): mixed { $resolver = $this->createOptionsResolver(); $datetimeNormalizer = function (Options $resolver, \DateTimeInterface $value): string { @@ -510,4 +435,12 @@ public function events(int $user_id, array $parameters = []) return $this->get('users/'.self::encodePath($user_id).'/events', $resolver->resolve($parameters)); } + + /** + * Deletes a user’s authentication identity using the provider name associated with that identity. + */ + public function removeUserIdentity(int $user_id, string $provider): mixed + { + return $this->delete('users/'.self::encodePath($user_id).'/identities/'.self::encodePath($provider)); + } } diff --git a/src/Api/Version.php b/src/Api/Version.php index 9c6477e9..8976a320 100644 --- a/src/Api/Version.php +++ b/src/Api/Version.php @@ -16,10 +16,7 @@ class Version extends AbstractApi { - /** - * @return mixed - */ - public function show() + public function show(): mixed { return $this->get('version'); } diff --git a/src/Api/Wiki.php b/src/Api/Wiki.php index bc99e5ba..fbb05551 100644 --- a/src/Api/Wiki.php +++ b/src/Api/Wiki.php @@ -17,56 +17,42 @@ class Wiki extends AbstractApi { /** - * @param int|string $project_id - * @param array $params - * - * @return mixed + * @param array $params */ - public function create($project_id, array $params) + public function create(int|string $project_id, array $params): mixed { return $this->post($this->getProjectPath($project_id, 'wikis'), $params); } - /** - * @param int|string $project_id - * @param string $wiki_slug - * - * @return mixed - */ - public function show($project_id, string $wiki_slug) + public function show(int|string $project_id, string $wiki_slug): mixed { return $this->get($this->getProjectPath($project_id, 'wikis/'.self::encodePath($wiki_slug))); } /** - * @param int|string $project_id + * @param array $params { * - * @return mixed + * @var bool $with_content Include pages' content + * } */ - public function showAll($project_id) + public function showAll(int|string $project_id, array $params): mixed { - return $this->get($this->getProjectPath($project_id, 'wikis')); + $resolver = $this->createOptionsResolver(); + $resolver->setDefined('with_content') + ->setAllowedTypes('with_content', 'bool'); + + return $this->get($this->getProjectPath($project_id, 'wikis'), $resolver->resolve($params)); } /** - * @param int|string $project_id - * @param string $wiki_slug - * @param array $params - * - * @return mixed + * @param array $params */ - public function update($project_id, string $wiki_slug, array $params) + public function update(int|string $project_id, string $wiki_slug, array $params): mixed { return $this->put($this->getProjectPath($project_id, 'wikis/'.self::encodePath($wiki_slug)), $params); } - /** - * @param int|string $project_id - * @param string $wiki_slug - * - * @return mixed - */ - public function remove($project_id, string $wiki_slug) + public function remove(int|string $project_id, string $wiki_slug): mixed { return $this->delete($this->getProjectPath($project_id, 'wikis/'.self::encodePath($wiki_slug))); } diff --git a/src/Client.php b/src/Client.php index 7689fee8..ee4ff8a7 100644 --- a/src/Client.php +++ b/src/Client.php @@ -17,6 +17,7 @@ use Gitlab\Api\DeployKeys; use Gitlab\Api\Deployments; use Gitlab\Api\Environments; +use Gitlab\Api\Events; use Gitlab\Api\Groups; use Gitlab\Api\GroupsBoards; use Gitlab\Api\GroupsEpics; @@ -33,7 +34,13 @@ use Gitlab\Api\Projects; use Gitlab\Api\Repositories; use Gitlab\Api\RepositoryFiles; +use Gitlab\Api\ResourceIterationEvents; +use Gitlab\Api\ResourceLabelEvents; +use Gitlab\Api\ResourceMilestoneEvents; +use Gitlab\Api\ResourceStateEvents; +use Gitlab\Api\ResourceWeightEvents; use Gitlab\Api\Schedules; +use Gitlab\Api\Search; use Gitlab\Api\Snippets; use Gitlab\Api\SystemHooks; use Gitlab\Api\Tags; @@ -67,6 +74,13 @@ class Client */ public const AUTH_HTTP_TOKEN = 'http_token'; + /** + * The job token authentication method. + * + * @var string + */ + public const AUTH_HTTP_JOB_TOKEN = 'http_job_token'; + /** * The OAuth 2 token authentication method. * @@ -86,30 +100,12 @@ class Client * * @var string */ - private const USER_AGENT = 'gitlab-php-api-client/11.7'; + private const USER_AGENT = 'gitlab-php-api-client/12.0'; - /** - * The HTTP client builder. - * - * @var Builder - */ - private $httpClientBuilder; - - /** - * The response history plugin. - * - * @var History - */ - private $responseHistory; + private readonly Builder $httpClientBuilder; + private readonly History $responseHistory; - /** - * Instantiate a new Gitlab client. - * - * @param Builder|null $httpClientBuilder - * - * @return void - */ - public function __construct(Builder $httpClientBuilder = null) + public function __construct(?Builder $httpClientBuilder = null) { $this->httpClientBuilder = $builder = $httpClientBuilder ?? new Builder(); $this->responseHistory = new History(); @@ -126,10 +122,6 @@ public function __construct(Builder $httpClientBuilder = null) /** * Create a Gitlab\Client using an HTTP client. - * - * @param ClientInterface $httpClient - * - * @return Client */ public static function createWithHttpClient(ClientInterface $httpClient): self { @@ -138,209 +130,166 @@ public static function createWithHttpClient(ClientInterface $httpClient): self return new self($builder); } - /** - * @return DeployKeys - */ public function deployKeys(): DeployKeys { return new DeployKeys($this); } - /** - * @return Deployments - */ public function deployments(): Deployments { return new Deployments($this); } - /** - * @return Environments - */ public function environments(): Environments { return new Environments($this); } - /** - * @return Groups - */ + public function events(): Events + { + return new Events($this); + } + public function groups(): Groups { return new Groups($this); } - /** - * @return GroupsBoards - */ public function groupsBoards(): GroupsBoards { return new GroupsBoards($this); } - /** - * @return GroupsEpics - */ public function groupsEpics(): GroupsEpics { return new GroupsEpics($this); } - /** - * @return GroupsMilestones - */ public function groupsMilestones(): GroupsMilestones { return new GroupsMilestones($this); } - /** - * @return IssueBoards - */ public function issueBoards(): IssueBoards { return new IssueBoards($this); } - /** - * @return IssueLinks - */ public function issueLinks(): IssueLinks { return new IssueLinks($this); } - /** - * @return Issues - */ public function issues(): Issues { return new Issues($this); } - /** - * @return IssuesStatistics - */ + public function resourceIterationEvents(): ResourceIterationEvents + { + return new ResourceIterationEvents($this); + } + + public function resourceLabelEvents(): ResourceLabelEvents + { + return new ResourceLabelEvents($this); + } + + public function resourceMilestoneEvents(): ResourceMilestoneEvents + { + return new ResourceMilestoneEvents($this); + } + + public function resourceStateEvents(): ResourceStateEvents + { + return new ResourceStateEvents($this); + } + + public function resourceWeightEvents(): ResourceWeightEvents + { + return new ResourceWeightEvents($this); + } + public function issuesStatistics(): IssuesStatistics { return new IssuesStatistics($this); } - /** - * @return Jobs - */ public function jobs(): Jobs { return new Jobs($this); } - /** - * @return Keys - */ public function keys(): Keys { return new Keys($this); } - /** - * @return MergeRequests - */ public function mergeRequests(): MergeRequests { return new MergeRequests($this); } - /** - * @return Milestones - */ public function milestones(): Milestones { return new Milestones($this); } - /** - * @return ProjectNamespaces - */ public function namespaces(): ProjectNamespaces { return new ProjectNamespaces($this); } - /** - * @return Projects - */ public function projects(): Projects { return new Projects($this); } - /** - * @return Repositories - */ public function repositories(): Repositories { return new Repositories($this); } - /** - * @return RepositoryFiles - */ public function repositoryFiles(): RepositoryFiles { return new RepositoryFiles($this); } - /** - * @return Schedules - */ + public function search(): Search + { + return new Search($this); + } + public function schedules(): Schedules { return new Schedules($this); } - /** - * @return Snippets - */ public function snippets(): Snippets { return new Snippets($this); } - /** - * @return SystemHooks - */ public function systemHooks(): SystemHooks { return new SystemHooks($this); } - /** - * @return Tags - */ public function tags(): Tags { return new Tags($this); } - /** - * @return Users - */ public function users(): Users { return new Users($this); } - /** - * @return Version - */ public function version(): Version { return new Version($this); } - /** - * @return Wiki - */ public function wiki(): Wiki { return new Wiki($this); @@ -351,21 +300,13 @@ public function wiki(): Wiki * * @param string $token Gitlab private token * @param string $authMethod One of the AUTH_* class constants - * @param string|null $sudo - * - * @return void */ - public function authenticate(string $token, string $authMethod, string $sudo = null): void + public function authenticate(string $token, string $authMethod, ?string $sudo = null): void { $this->getHttpClientBuilder()->removePlugin(Authentication::class); $this->getHttpClientBuilder()->addPlugin(new Authentication($authMethod, $token, $sudo)); } - /** - * @param string $url - * - * @return void - */ public function setUrl(string $url): void { $uri = $this->getHttpClientBuilder()->getUriFactory()->createUri($url); @@ -376,8 +317,6 @@ public function setUrl(string $url): void /** * Get the last response. - * - * @return ResponseInterface|null */ public function getLastResponse(): ?ResponseInterface { @@ -386,8 +325,6 @@ public function getLastResponse(): ?ResponseInterface /** * Get the HTTP client. - * - * @return HttpMethodsClientInterface */ public function getHttpClient(): HttpMethodsClientInterface { @@ -396,8 +333,6 @@ public function getHttpClient(): HttpMethodsClientInterface /** * Get the stream factory. - * - * @return StreamFactoryInterface */ public function getStreamFactory(): StreamFactoryInterface { @@ -406,8 +341,6 @@ public function getStreamFactory(): StreamFactoryInterface /** * Get the HTTP client builder. - * - * @return Builder */ protected function getHttpClientBuilder(): Builder { diff --git a/src/HttpClient/Builder.php b/src/HttpClient/Builder.php index 594b92cd..e94248f5 100644 --- a/src/HttpClient/Builder.php +++ b/src/HttpClient/Builder.php @@ -38,82 +38,36 @@ */ final class Builder { - /** - * The object that sends HTTP messages. - * - * @var ClientInterface - */ - private $httpClient; - - /** - * The HTTP request factory. - * - * @var RequestFactoryInterface - */ - private $requestFactory; - - /** - * The HTTP stream factory. - * - * @var StreamFactoryInterface - */ - private $streamFactory; - - /** - * The URI factory. - * - * @var UriFactoryInterface - */ - private $uriFactory; + private readonly ClientInterface $httpClient; + private readonly RequestFactoryInterface $requestFactory; + private readonly StreamFactoryInterface $streamFactory; + private readonly UriFactoryInterface $uriFactory; /** - * The currently registered plugins. - * * @var Plugin[] */ - private $plugins = []; + private array $plugins = []; - /** - * The cache plugin to use. - * - * This plugin is specially treated because it has to be the very last plugin. - * - * @var CachePlugin|null - */ - private $cachePlugin; + private ?CachePlugin $cachePlugin; - /** - * A HTTP client with all our plugins. - * - * @var HttpMethodsClientInterface|null - */ - private $pluginClient; + private ?HttpMethodsClientInterface $pluginClient; - /** - * Create a new http client builder instance. - * - * @param ClientInterface|null $httpClient - * @param RequestFactoryInterface|null $requestFactory - * @param StreamFactoryInterface|null $streamFactory - * @param UriFactoryInterface|null $uriFactory - * - * @return void - */ public function __construct( - ClientInterface $httpClient = null, - RequestFactoryInterface $requestFactory = null, - StreamFactoryInterface $streamFactory = null, - UriFactoryInterface $uriFactory = null + ?ClientInterface $httpClient = null, + ?RequestFactoryInterface $requestFactory = null, + ?StreamFactoryInterface $streamFactory = null, + ?UriFactoryInterface $uriFactory = null ) { $this->httpClient = $httpClient ?? Psr18ClientDiscovery::find(); $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory(); $this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory(); $this->uriFactory = $uriFactory ?? Psr17FactoryDiscovery::findUriFactory(); + + $this->plugins = []; + $this->cachePlugin = null; + $this->pluginClient = null; } - /** - * @return HttpMethodsClientInterface - */ public function getHttpClient(): HttpMethodsClientInterface { if (null === $this->pluginClient) { @@ -134,8 +88,6 @@ public function getHttpClient(): HttpMethodsClientInterface /** * Get the request factory. - * - * @return RequestFactoryInterface */ public function getRequestFactory(): RequestFactoryInterface { @@ -144,8 +96,6 @@ public function getRequestFactory(): RequestFactoryInterface /** * Get the stream factory. - * - * @return StreamFactoryInterface */ public function getStreamFactory(): StreamFactoryInterface { @@ -154,8 +104,6 @@ public function getStreamFactory(): StreamFactoryInterface /** * Get the URI factory. - * - * @return UriFactoryInterface */ public function getUriFactory(): UriFactoryInterface { @@ -164,10 +112,6 @@ public function getUriFactory(): UriFactoryInterface /** * Add a new plugin to the end of the plugin chain. - * - * @param Plugin $plugin - * - * @return void */ public function addPlugin(Plugin $plugin): void { @@ -177,10 +121,6 @@ public function addPlugin(Plugin $plugin): void /** * Remove a plugin by its fully qualified class name (FQCN). - * - * @param string $fqcn - * - * @return void */ public function removePlugin(string $fqcn): void { @@ -194,11 +134,6 @@ public function removePlugin(string $fqcn): void /** * Add a cache plugin to cache responses locally. - * - * @param CacheItemPoolInterface $cachePool - * @param array $config - * - * @return void */ public function addCache(CacheItemPoolInterface $cachePool, array $config = []): void { @@ -212,8 +147,6 @@ public function addCache(CacheItemPoolInterface $cachePool, array $config = []): /** * Remove the cache plugin. - * - * @return void */ public function removeCache(): void { diff --git a/src/HttpClient/Message/ResponseMediator.php b/src/HttpClient/Message/ResponseMediator.php index f0560335..ef66fae6 100644 --- a/src/HttpClient/Message/ResponseMediator.php +++ b/src/HttpClient/Message/ResponseMediator.php @@ -53,12 +53,8 @@ final class ResponseMediator /** * Return the response body as a string or JSON array if content type is JSON. - * - * @param ResponseInterface $response - * - * @return array|string */ - public static function getContent(ResponseInterface $response) + public static function getContent(ResponseInterface $response): array|string { $body = (string) $response->getBody(); @@ -72,8 +68,6 @@ public static function getContent(ResponseInterface $response) /** * Extract pagination URIs from Link header. * - * @param ResponseInterface $response - * * @return array */ public static function getPagination(ResponseInterface $response): array @@ -99,11 +93,6 @@ public static function getPagination(ResponseInterface $response): array /** * Get the value for a single header. - * - * @param ResponseInterface $response - * @param string $name - * - * @return string|null */ private static function getHeader(ResponseInterface $response, string $name): ?string { @@ -114,10 +103,6 @@ private static function getHeader(ResponseInterface $response, string $name): ?s /** * Get the error message from the response if present. - * - * @param ResponseInterface $response - * - * @return string|null */ public static function getErrorMessage(ResponseInterface $response): ?string { @@ -162,11 +147,6 @@ public static function getErrorMessage(ResponseInterface $response): ?string return null; } - /** - * @param array $message - * - * @return string - */ private static function getMessageAsString(array $message): string { $format = '"%s" %s'; diff --git a/src/HttpClient/Plugin/Authentication.php b/src/HttpClient/Plugin/Authentication.php index 92fc8019..148a523f 100644 --- a/src/HttpClient/Plugin/Authentication.php +++ b/src/HttpClient/Plugin/Authentication.php @@ -19,6 +19,7 @@ use Http\Client\Common\Plugin; use Http\Promise\Promise; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; /** * Add authentication to the request. @@ -33,16 +34,9 @@ final class Authentication implements Plugin /** * @var array */ - private $headers; + private readonly array $headers; - /** - * @param string $method - * @param string $token - * @param string|null $sudo - * - * @return void - */ - public function __construct(string $method, string $token, string $sudo = null) + public function __construct(string $method, string $token, ?string $sudo = null) { $this->headers = self::buildHeaders($method, $token, $sudo); } @@ -50,11 +44,7 @@ public function __construct(string $method, string $token, string $sudo = null) /** * Handle the request and return the response coming from the next callable. * - * @param RequestInterface $request - * @param callable $next - * @param callable $first - * - * @return Promise + * @return Promise */ public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise { @@ -68,15 +58,11 @@ public function handleRequest(RequestInterface $request, callable $next, callabl /** * Build the headers to be attached to the request. * - * @param string $method - * @param string $token - * @param string|null $sudo - * * @throws RuntimeException * * @return array */ - private static function buildHeaders(string $method, string $token, string $sudo = null): array + private static function buildHeaders(string $method, string $token, ?string $sudo = null): array { $headers = []; @@ -84,6 +70,10 @@ private static function buildHeaders(string $method, string $token, string $sudo case Client::AUTH_HTTP_TOKEN: $headers['PRIVATE-TOKEN'] = $token; + break; + case Client::AUTH_HTTP_JOB_TOKEN: + $headers['JOB-TOKEN'] = $token; + break; case Client::AUTH_OAUTH_TOKEN: $headers['Authorization'] = \sprintf('Bearer %s', $token); diff --git a/src/HttpClient/Plugin/ExceptionThrower.php b/src/HttpClient/Plugin/ExceptionThrower.php index ac9d1889..d8d76caa 100644 --- a/src/HttpClient/Plugin/ExceptionThrower.php +++ b/src/HttpClient/Plugin/ExceptionThrower.php @@ -38,11 +38,7 @@ final class ExceptionThrower implements Plugin /** * Handle the request and return the response coming from the next callable. * - * @param RequestInterface $request - * @param callable $next - * @param callable $first - * - * @return Promise + * @return Promise */ public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise { @@ -60,9 +56,6 @@ public function handleRequest(RequestInterface $request, callable $next, callabl /** * Create an exception from a status code and error message. * - * @param int $status - * @param string $message - * * @return ErrorException|RuntimeException */ private static function createException(int $status, string $message): ExceptionInterface diff --git a/src/HttpClient/Plugin/History.php b/src/HttpClient/Plugin/History.php index 37a58d89..5e41ca93 100644 --- a/src/HttpClient/Plugin/History.php +++ b/src/HttpClient/Plugin/History.php @@ -28,13 +28,15 @@ */ final class History implements Journal { - /** - * @var ResponseInterface|null - */ - private $lastResponse; + private ?ResponseInterface $lastResponse; + + public function __construct() + { + $this->lastResponse = null; + } /** - * @return ResponseInterface|null + * Get the last response. */ public function getLastResponse(): ?ResponseInterface { @@ -43,11 +45,6 @@ public function getLastResponse(): ?ResponseInterface /** * Record a successful call. - * - * @param RequestInterface $request - * @param ResponseInterface $response - * - * @return void */ public function addSuccess(RequestInterface $request, ResponseInterface $response): void { @@ -56,11 +53,6 @@ public function addSuccess(RequestInterface $request, ResponseInterface $respons /** * Record a failed call. - * - * @param RequestInterface $request - * @param ClientExceptionInterface $exception - * - * @return void */ public function addFailure(RequestInterface $request, ClientExceptionInterface $exception): void { diff --git a/src/HttpClient/Util/JsonArray.php b/src/HttpClient/Util/JsonArray.php index 4cc5a321..59a9c49f 100644 --- a/src/HttpClient/Util/JsonArray.php +++ b/src/HttpClient/Util/JsonArray.php @@ -24,11 +24,7 @@ final class JsonArray /** * Decode a JSON string into a PHP array. * - * @param string $json - * * @throws RuntimeException - * - * @return array */ public static function decode(string $json): array { @@ -49,11 +45,7 @@ public static function decode(string $json): array /** * Encode a PHP array into a JSON string. * - * @param array $value - * * @throws RuntimeException - * - * @return string */ public static function encode(array $value): string { diff --git a/src/HttpClient/Util/QueryStringBuilder.php b/src/HttpClient/Util/QueryStringBuilder.php index d762afa5..462f5ff4 100644 --- a/src/HttpClient/Util/QueryStringBuilder.php +++ b/src/HttpClient/Util/QueryStringBuilder.php @@ -24,10 +24,6 @@ final class QueryStringBuilder * * Indexed arrays are encoded using empty squared brackets ([]) unlike * `http_build_query`. - * - * @param array $query - * - * @return string */ public static function build(array $query): string { @@ -38,13 +34,8 @@ public static function build(array $query): string /** * Encode a value. - * - * @param mixed $query - * @param scalar $prefix - * - * @return string */ - private static function encode($query, $prefix): string + private static function encode(mixed $query, int|string $prefix): string { if (!\is_array($query)) { return self::rawurlencode($prefix).'='.self::rawurlencode($query); @@ -61,10 +52,6 @@ private static function encode($query, $prefix): string /** * Tell if the given array is a list. - * - * @param array $query - * - * @return bool */ private static function isList(array $query): bool { @@ -77,12 +64,8 @@ private static function isList(array $query): bool /** * Encode a value like rawurlencode, but return "0" when false is given. - * - * @param mixed $value - * - * @return string */ - private static function rawurlencode($value): string + private static function rawurlencode(mixed $value): string { if (false === $value) { return '0'; diff --git a/src/ResultPager.php b/src/ResultPager.php index 55bac330..d2ab7ba2 100644 --- a/src/ResultPager.php +++ b/src/ResultPager.php @@ -37,36 +37,16 @@ final class ResultPager implements ResultPagerInterface */ private const PER_PAGE = 50; - /** - * The client to use for pagination. - * - * @var Client - */ - private $client; + private readonly Client $client; - /** - * The number of entries to request per page. - * - * @var int - */ - private $perPage; + private readonly int $perPage; /** - * The pagination result from the API. - * * @var array */ - private $pagination; + private array $pagination; - /** - * Create a new result pager instance. - * - * @param Client $client - * @param int|null $perPage - * - * @return void - */ - public function __construct(Client $client, int $perPage = null) + public function __construct(Client $client, ?int $perPage = null) { if (null !== $perPage && ($perPage < 1 || $perPage > 100)) { throw new ValueError(\sprintf('%s::__construct(): Argument #2 ($perPage) must be between 1 and 100, or null', self::class)); @@ -80,13 +60,7 @@ public function __construct(Client $client, int $perPage = null) /** * Fetch a single result from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return array */ public function fetch(AbstractApi $api, string $method, array $parameters = []): array { @@ -104,13 +78,7 @@ public function fetch(AbstractApi $api, string $method, array $parameters = []): /** * Fetch all results from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return array */ public function fetchAll(AbstractApi $api, string $method, array $parameters = []): array { @@ -120,13 +88,7 @@ public function fetchAll(AbstractApi $api, string $method, array $parameters = [ /** * Lazily fetch all results from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return \Generator */ public function fetchAllLazy(AbstractApi $api, string $method, array $parameters = []): Generator { @@ -145,8 +107,6 @@ public function fetchAllLazy(AbstractApi $api, string $method, array $parameters /** * Check to determine the availability of a next page. - * - * @return bool */ public function hasNext(): bool { @@ -157,8 +117,6 @@ public function hasNext(): bool * Fetch the next page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchNext(): array { @@ -167,8 +125,6 @@ public function fetchNext(): array /** * Check to determine the availability of a previous page. - * - * @return bool */ public function hasPrevious(): bool { @@ -179,8 +135,6 @@ public function hasPrevious(): bool * Fetch the previous page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchPrevious(): array { @@ -191,8 +145,6 @@ public function fetchPrevious(): array * Fetch the first page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchFirst(): array { @@ -203,8 +155,6 @@ public function fetchFirst(): array * Fetch the last page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchLast(): array { @@ -213,8 +163,6 @@ public function fetchLast(): array /** * Refresh the pagination property. - * - * @return void */ private function postFetch(): void { @@ -224,11 +172,7 @@ private function postFetch(): void } /** - * @param string $key - * * @throws \Http\Client\Exception - * - * @return array */ private function get(string $key): array { @@ -251,14 +195,9 @@ private function get(string $key): array return $content; } - /** - * @param \Gitlab\Api\AbstractApi $api - * @param int $perPage - * - * @return \Gitlab\Api\AbstractApi - */ private static function bindPerPage(AbstractApi $api, int $perPage): AbstractApi { + /** @var Closure(AbstractApi): AbstractApi */ $closure = Closure::bind(static function (AbstractApi $api) use ($perPage): AbstractApi { $clone = clone $api; @@ -267,7 +206,6 @@ private static function bindPerPage(AbstractApi $api, int $perPage): AbstractApi return $clone; }, null, AbstractApi::class); - /** @var AbstractApi */ return $closure($api); } } diff --git a/src/ResultPagerInterface.php b/src/ResultPagerInterface.php index f88782cc..445455e0 100644 --- a/src/ResultPagerInterface.php +++ b/src/ResultPagerInterface.php @@ -29,46 +29,26 @@ interface ResultPagerInterface /** * Fetch a single result from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return array */ public function fetch(AbstractApi $api, string $method, array $parameters = []): array; /** * Fetch all results from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return array */ public function fetchAll(AbstractApi $api, string $method, array $parameters = []): array; /** * Lazily fetch all results from an api call. * - * @param AbstractApi $api - * @param string $method - * @param array $parameters - * * @throws \Http\Client\Exception - * - * @return \Generator */ public function fetchAllLazy(AbstractApi $api, string $method, array $parameters = []): Generator; /** * Check to determine the availability of a next page. - * - * @return bool */ public function hasNext(): bool; @@ -76,15 +56,11 @@ public function hasNext(): bool; * Fetch the next page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchNext(): array; /** * Check to determine the availability of a previous page. - * - * @return bool */ public function hasPrevious(): bool; @@ -92,8 +68,6 @@ public function hasPrevious(): bool; * Fetch the previous page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchPrevious(): array; @@ -101,8 +75,6 @@ public function fetchPrevious(): array; * Fetch the first page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchFirst(): array; @@ -110,8 +82,6 @@ public function fetchFirst(): array; * Fetch the last page. * * @throws \Http\Client\Exception - * - * @return array */ public function fetchLast(): array; } diff --git a/tests/Api/DeployKeysTest.php b/tests/Api/DeployKeysTest.php index c8a05f86..bbe1648b 100644 --- a/tests/Api/DeployKeysTest.php +++ b/tests/Api/DeployKeysTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\DeployKeys; +use PHPUnit\Framework\Attributes\Test; class DeployKeysTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllDeployKeys(): void { $expectedArray = $this->getMultipleDeployKeysData(); @@ -29,13 +28,13 @@ public function shouldGetAllDeployKeys(): void $api->expects($this->once()) ->method('get') ->with('deploy_keys', ['page' => 2, 'per_page' => 5]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(['page' => 2, 'per_page' => 5])); } - protected function getMultipleDeployKeysData() + protected function getMultipleDeployKeysData(): array { return [ [ @@ -53,7 +52,7 @@ protected function getMultipleDeployKeysData() ]; } - protected function getApiClass() + protected function getApiClass(): string { return DeployKeys::class; } diff --git a/tests/Api/DeploymentsTest.php b/tests/Api/DeploymentsTest.php index 0f84792a..d6859206 100644 --- a/tests/Api/DeploymentsTest.php +++ b/tests/Api/DeploymentsTest.php @@ -15,12 +15,12 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Deployments; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\MockObject\MockObject; class DeploymentsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllDeployments(): void { $expectedArray = $this->getMultipleDeploymentsData(); @@ -30,9 +30,7 @@ public function shouldGetAllDeployments(): void $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowDeployment(): void { $expectedArray = [ @@ -106,11 +104,11 @@ public function shouldShowDeployment(): void $api->expects($this->once()) ->method('get') ->with('projects/1/deployments/42') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1, 42)); } - private function getMultipleDeploymentsData() + private function getMultipleDeploymentsData(): array { return [ [ @@ -244,20 +242,18 @@ private function getMultipleDeploymentsData() ]; } - protected function getMultipleDeploymentsRequestMock(string $path, array $expectedArray, array $expectedParameters) + protected function getMultipleDeploymentsRequestMock(string $path, array $expectedArray, array $expectedParameters): MockObject { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with($path, $expectedParameters) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); return $api; } - /** - * @test - */ + #[Test] public function shouldGetAllDeploymentsSortedByCreatedAt(): void { $expectedArray = $this->getMultipleDeploymentsData(); @@ -274,8 +270,57 @@ public function shouldGetAllDeploymentsSortedByCreatedAt(): void ); } - protected function getApiClass() + protected function getApiClass(): string { return Deployments::class; } + + #[Test] + public function shouldAllowDeploymentFilterByStatus(): void + { + $expectedArray = $this->getMultipleDeploymentsData(); + + $api = $this->getMultipleDeploymentsRequestMock( + 'projects/1/deployments', + $expectedArray, + ['status' => 'success'] + ); + + $this->assertEquals( + $expectedArray, + $api->all(1, ['status' => 'success']) + ); + } + + #[Test] + public function shouldAllowFilterByEnvironment(): void + { + $expectedArray = $this->getMultipleDeploymentsData(); + + $api = $this->getMultipleDeploymentsRequestMock( + 'projects/1/deployments', + $expectedArray, + ['environment' => 'production'] + ); + + $this->assertEquals( + $expectedArray, + $api->all(1, ['environment' => 'production']) + ); + } + + #[Test] + public function shouldAllowEmptyArrayIfAllExcludedByFilter(): void + { + $expectedArray = $this->getMultipleDeploymentsData(); + + $api = $this->getMultipleDeploymentsRequestMock( + 'projects/1/deployments', + [], + ['environment' => 'test'] + ); + + $this->assertEquals([], $api->all(1, ['environment' => 'test']) + ); + } } diff --git a/tests/Api/EnvironmentsTest.php b/tests/Api/EnvironmentsTest.php index b21cb443..5af2c4ad 100644 --- a/tests/Api/EnvironmentsTest.php +++ b/tests/Api/EnvironmentsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Environments; +use PHPUnit\Framework\Attributes\Test; class EnvironmentsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllEnvironments(): void { $expectedArray = [ @@ -42,11 +41,11 @@ public function shouldGetAllEnvironments(): void $api->expects($this->once()) ->method('get') ->with('projects/1/environments') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->all(1)); } - /** @test */ + #[Test] public function shouldFilterEnvironmentByName(): void { $expected = [ @@ -61,13 +60,11 @@ public function shouldFilterEnvironmentByName(): void $api->expects($this->once()) ->method('get') ->with('projects/1/environments') - ->will($this->returnValue($expected)); + ->willReturn($expected); $this->assertEquals($expected, $api->all(1, ['name' => 'review/fix-bar'])); } - /** - * @test - */ + #[Test] public function shouldGetSingleEnvironment(): void { $expected = [ @@ -140,13 +137,11 @@ public function shouldGetSingleEnvironment(): void $api->expects($this->once()) ->method('get') ->with('projects/1/environments/1') - ->will($this->returnValue($expected)); + ->willReturn($expected); $this->assertEquals($expected, $api->show(1, 1)); } - /** - * @test - */ + #[Test] public function shouldCreateEnvironment(): void { $expectedArray = [ @@ -155,26 +150,26 @@ public function shouldCreateEnvironment(): void 'name' => 'review/fix-baz', 'slug' => 'review-fix-baz-dfjre5', 'external_url' => 'https://review-fix-baz-dfjre5.example.gitlab.com/', + 'tier' => 'production', ], ]; $params = [ 'name' => 'review/fix-baz', 'external_url' => 'https://review-fix-baz-dfjre5.example.gitlab.com/', + 'tier' => 'production', ]; $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') ->with('projects/1/environments', $params) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->create(1, $params)); } - /** - * @test - */ + #[Test] public function shouldRemoveEnvironment(): void { $expectedBool = true; @@ -183,13 +178,11 @@ public function shouldRemoveEnvironment(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/environments/3') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 3)); } - /** - * @test - */ + #[Test] public function shouldStopEnvironment(): void { $expectedBool = true; @@ -198,11 +191,11 @@ public function shouldStopEnvironment(): void $api->expects($this->once()) ->method('post') ->with('projects/1/environments/3/stop') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->stop(1, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return Environments::class; } diff --git a/tests/Api/EventsTest.php b/tests/Api/EventsTest.php new file mode 100644 index 00000000..fb39b9c8 --- /dev/null +++ b/tests/Api/EventsTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\Events; +use PHPUnit\Framework\Attributes\Test; + +class EventsTest extends TestCase +{ + protected function getApiClass(): string + { + return Events::class; + } + + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + ['id' => 1, 'target_type' => 'Issue'], + ['id' => 2, 'target_type' => null], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('events', []) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->all()); + } + + #[Test] + public function shouldGetEventsAfter(): void + { + $expectedArray = [ + ['id' => 1, 'target_type' => 'Issue'], + ['id' => 2, 'target_type' => null], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('events', ['after' => '1970-01-01']) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->all(['after' => new \DateTime('1970-01-01')])); + } +} diff --git a/tests/Api/GroupBoardsTest.php b/tests/Api/GroupBoardsTest.php index c9dc7f02..4ebf53bf 100644 --- a/tests/Api/GroupBoardsTest.php +++ b/tests/Api/GroupBoardsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\GroupsBoards; +use PHPUnit\Framework\Attributes\Test; class GroupBoardsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllBoards(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllBoards(): void $api->expects($this->once()) ->method('get') ->with('boards', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldShowIssueBoard(): void { $expectedArray = ['id' => 2, 'name' => 'Another issue board']; @@ -49,15 +46,13 @@ public function shouldShowIssueBoard(): void $api->expects($this->once()) ->method('get') ->with('groups/1/boards/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateIssueBoard(): void { $expectedArray = ['id' => 3, 'name' => 'A new issue board']; @@ -66,15 +61,13 @@ public function shouldCreateIssueBoard(): void $api->expects($this->once()) ->method('post') ->with('groups/1/boards', ['name' => 'A new issue board']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['name' => 'A new issue board'])); } - /** - * @test - */ + #[Test] public function shouldUpdateIssueBoard(): void { $expectedArray = ['id' => 2, 'name' => 'A renamed issue board']; @@ -83,15 +76,13 @@ public function shouldUpdateIssueBoard(): void $api->expects($this->once()) ->method('put') ->with('groups/1/boards/2', ['name' => 'A renamed issue board', 'labels' => 'foo']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 2, ['name' => 'A renamed issue board', 'labels' => 'foo'])); } - /** - * @test - */ + #[Test] public function shouldRemoveIssueBoard(): void { $expectedBool = true; @@ -100,15 +91,12 @@ public function shouldRemoveIssueBoard(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/boards/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetAllLists(): void { $expectedArray = [ @@ -135,15 +123,13 @@ public function shouldGetAllLists(): void $api->expects($this->once()) ->method('get') ->with('groups/1/boards/2/lists') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->allLists(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetList(): void { $expectedArray = [ @@ -162,15 +148,13 @@ public function shouldGetList(): void $api->expects($this->once()) ->method('get') ->with('groups/1/boards/2/lists/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showList(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldCreateList(): void { $expectedArray = [ @@ -189,15 +173,13 @@ public function shouldCreateList(): void $api->expects($this->once()) ->method('post') ->with('groups/1/boards/2/lists', ['label_id' => 4]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createList(1, 2, 4)); } - /** - * @test - */ + #[Test] public function shouldUpdateList(): void { $expectedArray = [ @@ -216,15 +198,13 @@ public function shouldUpdateList(): void $api->expects($this->once()) ->method('put') ->with('groups/5/boards/2/lists/3', ['position' => 1]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateList(5, 2, 3, 1)); } - /** - * @test - */ + #[Test] public function shouldDeleteList(): void { $expectedBool = true; @@ -233,13 +213,12 @@ public function shouldDeleteList(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/boards/2/lists/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteList(1, 2, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return GroupsBoards::class; } diff --git a/tests/Api/GroupsEpicsTest.php b/tests/Api/GroupsEpicsTest.php index acb97fd6..8ba51f1b 100644 --- a/tests/Api/GroupsEpicsTest.php +++ b/tests/Api/GroupsEpicsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\GroupsEpics; +use PHPUnit\Framework\Attributes\Test; class GroupsEpicsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllEpics(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllEpics(): void $api->expects($this->once()) ->method('get') ->with('groups/1/epics') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowEpic(): void { $expectedArray = ['id' => 1, 'name' => 'A epic']; @@ -49,15 +46,13 @@ public function shouldShowEpic(): void $api->expects($this->once()) ->method('get') ->with('groups/1/epics/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateEpic(): void { $expectedArray = ['id' => 3, 'title' => 'A new epic']; @@ -66,15 +61,13 @@ public function shouldCreateEpic(): void $api->expects($this->once()) ->method('post') ->with('groups/1/epics', ['description' => 'Some text', 'title' => 'A new epic']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['description' => 'Some text', 'title' => 'A new epic'])); } - /** - * @test - */ + #[Test] public function shouldUpdateEpic(): void { $expectedArray = ['id' => 3, 'title' => 'Updated epic']; @@ -83,15 +76,13 @@ public function shouldUpdateEpic(): void $api->expects($this->once()) ->method('put') ->with('groups/1/epics/3', ['title' => 'Updated epic', 'description' => 'Updated description', 'state_event' => 'close']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 3, ['title' => 'Updated epic', 'description' => 'Updated description', 'state_event' => 'close'])); } - /** - * @test - */ + #[Test] public function shouldRemoveEpic(): void { $expectedBool = true; @@ -100,13 +91,30 @@ public function shouldRemoveEpic(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/epics/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - protected function getApiClass() + #[Test] + public function shouldGetEpicsIssues(): void + { + $expectedArray = [ + ['id' => 1, 'title' => 'An issue'], + ['id' => 2, 'title' => 'Another issue'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/epics/2/issues') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->issues(1, 2)); + } + + protected function getApiClass(): string { return GroupsEpics::class; } diff --git a/tests/Api/GroupsMilestonesTest.php b/tests/Api/GroupsMilestonesTest.php index 3dc5d7a7..96376117 100644 --- a/tests/Api/GroupsMilestonesTest.php +++ b/tests/Api/GroupsMilestonesTest.php @@ -15,12 +15,12 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\GroupsMilestones; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; class GroupsMilestonesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllMilestones(): void { $expectedArray = [ @@ -32,15 +32,100 @@ public function shouldGetAllMilestones(): void $api->expects($this->once()) ->method('get') ->with('groups/1/milestones') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] + public function shouldGetAllMilestonesWithParameterOneIidsValue(): void + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['iids' => [456]]) + ; + + $api->all(1, ['iids' => [456]]); + } + + #[Test] + public function shouldGetAllMilestonesWithParameterTwoIidsValues(): void + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['iids' => [456, 789]]) + ; + + $api->all(1, ['iids' => [456, 789]]); + } + + public static function getAllMilestonesWithParameterStateDataProvider(): array + { + return [ + GroupsMilestones::STATE_ACTIVE => [GroupsMilestones::STATE_ACTIVE], + GroupsMilestones::STATE_CLOSED => [GroupsMilestones::STATE_CLOSED], + ]; + } + + #[Test] + #[DataProvider('getAllMilestonesWithParameterStateDataProvider')] + public function shouldGetAllMilestonesWithParameterState(string $state): void + { + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['state' => $state]) + ; + + $api->all(1, ['state' => $state]); + } + + #[Test] + public function shouldGetAllMilestonesWithParameterSearch(): void + { + $searchValue = 'abc'; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['search' => $searchValue]) + ; + + $api->all(1, ['search' => $searchValue]); + } + + #[Test] + public function shouldGetAllMilestonesWithParameterUpdatedBefore(): void + { + $updatedBefore = new \DateTimeImmutable('2023-11-25T08:00:00Z'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['updated_before' => '2023-11-25T08:00:00.000Z']) + ; + + $api->all(1, ['updated_before' => $updatedBefore]); + } + + #[Test] + public function shouldGetAllMilestonesWithParameterUpdatedAfter(): void + { + $updatedAfter = new \DateTimeImmutable('2023-11-25T08:00:00Z'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/milestones', ['updated_after' => '2023-11-25T08:00:00.000Z']) + ; + + $api->all(1, ['updated_after' => $updatedAfter]); + } + + #[Test] public function shouldShowMilestone(): void { $expectedArray = ['id' => 1, 'name' => 'A milestone']; @@ -49,15 +134,13 @@ public function shouldShowMilestone(): void $api->expects($this->once()) ->method('get') ->with('groups/1/milestones/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateMilestone(): void { $expectedArray = ['id' => 3, 'title' => 'A new milestone']; @@ -66,15 +149,13 @@ public function shouldCreateMilestone(): void $api->expects($this->once()) ->method('post') ->with('groups/1/milestones', ['description' => 'Some text', 'title' => 'A new milestone']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['description' => 'Some text', 'title' => 'A new milestone'])); } - /** - * @test - */ + #[Test] public function shouldUpdateMilestone(): void { $expectedArray = ['id' => 3, 'title' => 'Updated milestone']; @@ -83,15 +164,13 @@ public function shouldUpdateMilestone(): void $api->expects($this->once()) ->method('put') ->with('groups/1/milestones/3', ['title' => 'Updated milestone', 'due_date' => '2015-04-01', 'state_event' => 'close']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 3, ['title' => 'Updated milestone', 'due_date' => '2015-04-01', 'state_event' => 'close'])); } - /** - * @test - */ + #[Test] public function shouldRemoveMilestone(): void { $expectedBool = true; @@ -100,15 +179,12 @@ public function shouldRemoveMilestone(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/milestones/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMilestonesIssues(): void { $expectedArray = [ @@ -120,15 +196,13 @@ public function shouldGetMilestonesIssues(): void $api->expects($this->once()) ->method('get') ->with('groups/1/milestones/3/issues') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->issues(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetMilestonesMergeRequests(): void { $expectedArray = [ @@ -140,13 +214,13 @@ public function shouldGetMilestonesMergeRequests(): void $api->expects($this->once()) ->method('get') ->with('groups/1/milestones/3/merge_requests') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->mergeRequests(1, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return GroupsMilestones::class; } diff --git a/tests/Api/GroupsTest.php b/tests/Api/GroupsTest.php index 8f2bad40..3b90e6f2 100644 --- a/tests/Api/GroupsTest.php +++ b/tests/Api/GroupsTest.php @@ -14,13 +14,13 @@ namespace Gitlab\Tests\Api; +use DateTime; use Gitlab\Api\Groups; +use PHPUnit\Framework\Attributes\Test; class GroupsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllGroups(): void { $expectedArray = [ @@ -32,15 +32,13 @@ public function shouldGetAllGroups(): void $api->expects($this->once()) ->method('get') ->with('groups', ['page' => 1, 'per_page' => 10]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(['page' => 1, 'per_page' => 10])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupsWithBooleanParam(): void { $expectedArray = [ @@ -52,15 +50,13 @@ public function shouldGetAllGroupsWithBooleanParam(): void $api->expects($this->once()) ->method('get') ->with('groups', ['all_available' => 'false']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(['all_available' => false])); } - /** - * @test - */ + #[Test] public function shouldGetAllTopLevelGroupsWithoutSubgroups(): void { $expectedArray = [ @@ -72,15 +68,13 @@ public function shouldGetAllTopLevelGroupsWithoutSubgroups(): void $api->expects($this->once()) ->method('get') ->with('groups', ['top_level_only' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(['top_level_only' => true])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsWithBooleanParam(): void { $expectedArray = [ @@ -92,15 +86,13 @@ public function shouldGetAllGroupProjectsWithBooleanParam(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['archived' => 'false']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['archived' => false])); } - /** - * @test - */ + #[Test] public function shouldNotNeedPaginationWhenGettingGroups(): void { $expectedArray = [ @@ -112,15 +104,13 @@ public function shouldNotNeedPaginationWhenGettingGroups(): void $api->expects($this->once()) ->method('get') ->with('groups', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldShowGroup(): void { $expectedArray = ['id' => 1, 'name' => 'A group']; @@ -129,15 +119,13 @@ public function shouldShowGroup(): void $api->expects($this->once()) ->method('get') ->with('groups/1') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1)); } - /** - * @test - */ + #[Test] public function shouldCreateGroup(): void { $expectedArray = ['id' => 1, 'name' => 'A new group']; @@ -146,15 +134,13 @@ public function shouldCreateGroup(): void $api->expects($this->once()) ->method('post') ->with('groups', ['name' => 'A new group', 'path' => 'a-new-group', 'visibility' => 'private']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('A new group', 'a-new-group')); } - /** - * @test - */ + #[Test] public function shouldCreateGroupWithDescriptionAndVisibility(): void { $expectedArray = ['id' => 1, 'name' => 'A new group', 'visibility_level' => 2]; @@ -163,15 +149,13 @@ public function shouldCreateGroupWithDescriptionAndVisibility(): void $api->expects($this->once()) ->method('post') ->with('groups', ['name' => 'A new group', 'path' => 'a-new-group', 'description' => 'Description', 'visibility' => 'public']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('A new group', 'a-new-group', 'Description', 'public')); } - /** - * @test - */ + #[Test] public function shouldCreateGroupWithDescriptionVisibilityAndParentId(): void { $expectedArray = ['id' => 1, 'name' => 'A new group', 'visibility_level' => 2, 'parent_id' => 666]; @@ -180,15 +164,13 @@ public function shouldCreateGroupWithDescriptionVisibilityAndParentId(): void $api->expects($this->once()) ->method('post') ->with('groups', ['name' => 'A new group', 'path' => 'a-new-group', 'description' => 'Description', 'visibility' => 'public', 'parent_id' => 666]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('A new group', 'a-new-group', 'Description', 'public', null, null, 666)); } - /** - * @test - */ + #[Test] public function shouldUpdateGroup(): void { $expectedArray = ['id' => 3, 'name' => 'Group name', 'path' => 'group-path']; @@ -197,15 +179,13 @@ public function shouldUpdateGroup(): void $api->expects($this->once()) ->method('put') ->with('groups/3', ['name' => 'Group name', 'path' => 'group-path']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(3, ['name' => 'Group name', 'path' => 'group-path'])); } - /** - * @test - */ + #[Test] public function shouldTransferProjectToGroup(): void { $expectedBool = true; @@ -214,15 +194,12 @@ public function shouldTransferProjectToGroup(): void $api->expects($this->once()) ->method('post') ->with('groups/1/projects/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->transfer(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetAllMembers(): void { $expectedArray = [ @@ -234,15 +211,13 @@ public function shouldGetAllMembers(): void $api->expects($this->once()) ->method('get') ->with('groups/1/members/all') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->allMembers(1)); } - /** - * @test - */ + #[Test] public function shouldGetAllMember(): void { $expectedArray = ['id' => 2, 'name' => 'Bob']; @@ -251,14 +226,12 @@ public function shouldGetAllMember(): void $api->expects($this->once()) ->method('get') ->with('groups/1/members/all/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->allMember(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMembers(): void { $expectedArray = [ @@ -270,32 +243,31 @@ public function shouldGetMembers(): void $api->expects($this->once()) ->method('get') ->with('groups/1/members') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->members(1)); } - /** - * @test - */ + #[Test] public function shouldAddMember(): void { - $expectedArray = ['id' => 1, 'name' => 'Matt']; + $tomorrow = (new DateTime('tomorrow')); + $expectedArray = ['id' => 1, 'name' => 'Matt', 'expires_at' => $tomorrow]; $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('groups/1/members', ['user_id' => 2, 'access_level' => 3]) - ->will($this->returnValue($expectedArray)) + ->with('groups/1/members', [ + 'user_id' => 2, 'access_level' => 10, 'expires_at' => $tomorrow->format('Y-m-d'), + ]) + ->willReturn($expectedArray) ; - $this->assertEquals($expectedArray, $api->addMember(1, 2, 3)); + $this->assertEquals($expectedArray, $api->addMember(1, 2, 10, ['expires_at' => $tomorrow])); } - /** - * @test - */ + #[Test] public function shouldSaveMember(): void { $expectedArray = ['id' => 1, 'name' => 'Matt']; @@ -304,15 +276,13 @@ public function shouldSaveMember(): void $api->expects($this->once()) ->method('put') ->with('groups/1/members/2', ['access_level' => 4]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->saveMember(1, 2, 4)); } - /** - * @test - */ + #[Test] public function shouldRemoveMember(): void { $expectedBool = true; @@ -321,15 +291,12 @@ public function shouldRemoveMember(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/members/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeMember(1, 2)); } - /** - * @test - */ + #[Test] public function shouldRemoveGroup(): void { $expectedBool = true; @@ -338,15 +305,12 @@ public function shouldRemoveGroup(): void $api->expects($this->once()) ->method('delete') ->with('groups/1') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1)); } - /** - * @test - */ + #[Test] public function shouldGetAllSubgroups(): void { $expectedArray = [ @@ -358,15 +322,32 @@ public function shouldGetAllSubgroups(): void $api->expects($this->once()) ->method('get') ->with('groups/1/subgroups', ['page' => 1, 'per_page' => 10]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->subgroups(1, ['page' => 1, 'per_page' => 10])); } - /** - * @test - */ + #[Test] + public function shouldGetAllIssues(): void + { + $expectedArray = [ + ['id' => 101, 'name' => 'An issue'], + ['id' => 102, 'name' => 'Another issue'], + ['id' => 103, 'name' => 'A third issue'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/issues', ['page' => 1, 'per_page' => 10]) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->issues(1, ['page' => 1, 'per_page' => 10])); + } + + #[Test] public function shouldGetLabels(): void { $expectedArray = [ @@ -378,15 +359,13 @@ public function shouldGetLabels(): void $api->expects($this->once()) ->method('get') ->with('groups/1/labels') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->labels(1)); } - /** - * @test - */ + #[Test] public function shouldAddLabel(): void { $expectedArray = ['name' => 'bug', 'color' => '#000000']; @@ -395,15 +374,13 @@ public function shouldAddLabel(): void $api->expects($this->once()) ->method('post') ->with('groups/1/labels', ['name' => 'wont-fix', 'color' => '#ffffff']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addLabel(1, ['name' => 'wont-fix', 'color' => '#ffffff'])); } - /** - * @test - */ + #[Test] public function shouldUpdateLabel(): void { $expectedArray = ['name' => 'bug', 'color' => '#00ffff']; @@ -412,15 +389,13 @@ public function shouldUpdateLabel(): void $api->expects($this->once()) ->method('put') ->with('groups/1/labels/123', ['new_name' => 'big-bug', 'color' => '#00ffff']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateLabel(1, 123, ['new_name' => 'big-bug', 'color' => '#00ffff'])); } - /** - * @test - */ + #[Test] public function shouldRemoveLabel(): void { $expectedBool = true; @@ -429,8 +404,7 @@ public function shouldRemoveLabel(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/labels/456', []) - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeLabel(1, 456)); } @@ -446,15 +420,13 @@ public function shouldGetVariables(): void $api->expects($this->once()) ->method('get') ->with('groups/1/variables') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->variables(1)); } - /** - * @test - */ + #[Test] public function shouldGetVariable(): void { $expectedArray = ['key' => 'ftp_username', 'value' => 'ftp']; @@ -463,7 +435,7 @@ public function shouldGetVariable(): void $api->expects($this->once()) ->method('get') ->with('groups/1/variables/ftp_username') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->variable(1, 'ftp_username')); @@ -483,15 +455,13 @@ public function shouldAddVariable(): void $api->expects($this->once()) ->method('post') ->with('groups/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addVariable(1, $expectedKey, $expectedValue)); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithProtected(): void { $expectedArray = [ @@ -504,15 +474,13 @@ public function shouldAddVariableWithProtected(): void $api->expects($this->once()) ->method('post') ->with('groups/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addVariable(1, 'DEPLOY_SERVER', 'stage.example.com', true)); } - /** - * @test - */ + #[Test] public function shouldUpdateVariable(): void { $expectedKey = 'ftp_port'; @@ -527,15 +495,13 @@ public function shouldUpdateVariable(): void $api->expects($this->once()) ->method('put') ->with('groups/1/variables/'.$expectedKey, ['value' => $expectedValue]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateVariable(1, $expectedKey, $expectedValue)); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithProtected(): void { $expectedArray = [ @@ -548,15 +514,13 @@ public function shouldUpdateVariableWithProtected(): void $api->expects($this->once()) ->method('put') ->with('groups/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'protected' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateVariable(1, 'DEPLOY_SERVER', 'stage.example.com', true)); } - /** - * @test - */ + #[Test] public function shouldRemoveVariable(): void { $expectedBool = true; @@ -565,20 +529,17 @@ public function shouldRemoveVariable(): void $api->expects($this->once()) ->method('delete') ->with('groups/1/variables/ftp_password') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeVariable(1, 'ftp_password')); } - protected function getApiClass() + protected function getApiClass(): string { return Groups::class; } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsWithIssuesEnabled(): void { $expectedArray = [ @@ -590,15 +551,13 @@ public function shouldGetAllGroupProjectsWithIssuesEnabled(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['with_issues_enabled' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['with_issues_enabled' => true])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsWithMergeRequestsEnabled(): void { $expectedArray = [ @@ -610,15 +569,13 @@ public function shouldGetAllGroupProjectsWithMergeRequestsEnabled(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['with_merge_requests_enabled' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['with_merge_requests_enabled' => true])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsSharedToGroup(): void { $expectedArray = [ @@ -630,15 +587,13 @@ public function shouldGetAllGroupProjectsSharedToGroup(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['with_shared' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['with_shared' => true])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsIncludingSubsgroups(): void { $expectedArray = [ @@ -650,15 +605,13 @@ public function shouldGetAllGroupProjectsIncludingSubsgroups(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['include_subgroups' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['include_subgroups' => true])); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupProjectsIncludingCustomAttributes(): void { $expectedArray = [ @@ -670,15 +623,43 @@ public function shouldGetAllGroupProjectsIncludingCustomAttributes(): void $api->expects($this->once()) ->method('get') ->with('groups/1/projects', ['with_custom_attributes' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->projects(1, ['with_custom_attributes' => true])); } - /** - * @test - */ + #[Test] + public function shouldGetIterations(): void + { + $expectedArray = [ + [ + 'id' => 5, + 'iid' => 2, + 'sequence' => 1, + 'group_id' => 123, + 'title' => '2022: Sprint 1', + 'description' => '', + 'state' => 3, + 'created_at' => '2021-09-29T21:24:43.913Z', + 'updated_at' => '2022-03-29T19:09:08.368Z', + 'start_date' => '2022-01-10', + 'due_date' => '2022-01-23', + 'web_url' => 'https://example.com/groups/example/-/iterations/34', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/iterations') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->iterations(1)); + } + + #[Test] public function shouldGetPackages(): void { $expectedArray = [ @@ -710,9 +691,195 @@ public function shouldGetPackages(): void $api->expects($this->once()) ->method('get') ->with('groups/1/packages') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->packages(1)); } + + #[Test] + public function shouldGetGroupMergeRequests(): void + { + $expectedArray = [ + ['id' => 1, 'title' => 'A merge request'], + ['id' => 2, 'title' => 'Another merge request'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/merge_requests') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->mergeRequests(1, [])); + } + + #[Test] + public function shouldGetDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => false, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/deploy_tokens') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->deployTokens(1)); + } + + #[Test] + public function shouldGetActiveDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => true, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/deploy_tokens', ['active' => true]) + ->willReturn([]); + + $this->assertEquals([], $api->deployTokens(1, true)); + } + + #[Test] + public function shouldGetInactiveDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => true, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/1/deploy_tokens', ['active' => false]) + ->willReturn([]); + + $this->assertEquals([], $api->deployTokens(1, false)); + } + + #[Test] + public function shouldCreateDeployToken(): void + { + $expectedArray = [ + 'id' => 1, + 'name' => 'My Deploy Token', + 'username' => 'custom-user', + 'token' => 'jMRvtPNxrn3crTAGukpZ', + 'expires_at' => '2021-01-01T00:00:00.000Z', + 'revoked' => false, + 'expired' => false, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with( + 'groups/1/deploy_tokens', + [ + 'name' => 'My Deploy Token', + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + 'expires_at' => (new DateTime('2021-01-01'))->format('c'), + ] + ) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->createDeployToken(1, [ + 'name' => 'My Deploy Token', + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + 'expires_at' => new DateTime('2021-01-01'), + ])); + } + + #[Test] + public function shouldDeleteDeployToken(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('groups/1/deploy_tokens/2') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->deleteDeployToken(1, 2)); + } + + #[Test] + public function shouldSearchGroups(): void + { + $expectedArray = [ + ['id' => 6, 'name' => 'Project 6 bla'], + ['id' => 7, 'name' => 'Project 7 bla'], + ['id' => 8, 'name' => 'Project 8 bla'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('groups/123/search', [ + 'scope' => 'projects', + 'confidential' => 'false', + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->search(123, [ + 'scope' => 'projects', + 'confidential' => false, + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ])); + } } diff --git a/tests/Api/IssueBoardsTest.php b/tests/Api/IssueBoardsTest.php index d39ebe0e..45f83fb1 100644 --- a/tests/Api/IssueBoardsTest.php +++ b/tests/Api/IssueBoardsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\IssueBoards; +use PHPUnit\Framework\Attributes\Test; class IssueBoardsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllBoards(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllBoards(): void $api->expects($this->once()) ->method('get') ->with('boards', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldShowIssueBoard(): void { $expectedArray = ['id' => 2, 'name' => 'Another issue board']; @@ -49,15 +46,13 @@ public function shouldShowIssueBoard(): void $api->expects($this->once()) ->method('get') ->with('projects/1/boards/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateIssueBoard(): void { $expectedArray = ['id' => 3, 'name' => 'A new issue board']; @@ -66,15 +61,13 @@ public function shouldCreateIssueBoard(): void $api->expects($this->once()) ->method('post') ->with('projects/1/boards', ['name' => 'A new issue board']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['name' => 'A new issue board'])); } - /** - * @test - */ + #[Test] public function shouldUpdateIssueBoard(): void { $expectedArray = ['id' => 2, 'name' => 'A renamed issue board']; @@ -83,15 +76,13 @@ public function shouldUpdateIssueBoard(): void $api->expects($this->once()) ->method('put') ->with('projects/1/boards/2', ['name' => 'A renamed issue board', 'labels' => 'foo']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 2, ['name' => 'A renamed issue board', 'labels' => 'foo'])); } - /** - * @test - */ + #[Test] public function shouldRemoveIssueBoard(): void { $expectedBool = true; @@ -100,15 +91,12 @@ public function shouldRemoveIssueBoard(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/boards/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetAllLists(): void { $expectedArray = [ @@ -135,15 +123,13 @@ public function shouldGetAllLists(): void $api->expects($this->once()) ->method('get') ->with('projects/1/boards/2/lists') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->allLists(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetList(): void { $expectedArray = [ @@ -162,15 +148,13 @@ public function shouldGetList(): void $api->expects($this->once()) ->method('get') ->with('projects/1/boards/2/lists/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showList(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldCreateList(): void { $expectedArray = [ @@ -189,15 +173,13 @@ public function shouldCreateList(): void $api->expects($this->once()) ->method('post') ->with('projects/1/boards/2/lists', ['label_id' => 4]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createList(1, 2, 4)); } - /** - * @test - */ + #[Test] public function shouldUpdateList(): void { $expectedArray = [ @@ -216,15 +198,13 @@ public function shouldUpdateList(): void $api->expects($this->once()) ->method('put') ->with('projects/5/boards/2/lists/3', ['position' => 1]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateList(5, 2, 3, 1)); } - /** - * @test - */ + #[Test] public function shouldDeleteList(): void { $expectedBool = true; @@ -233,13 +213,12 @@ public function shouldDeleteList(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/boards/2/lists/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteList(1, 2, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return IssueBoards::class; } diff --git a/tests/Api/IssueLinksTest.php b/tests/Api/IssueLinksTest.php index 2c76233d..ed400ad7 100644 --- a/tests/Api/IssueLinksTest.php +++ b/tests/Api/IssueLinksTest.php @@ -15,20 +15,19 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\IssueLinks; +use PHPUnit\Framework\Attributes\Test; class IssueLinksTest extends TestCase { /** * {@inheritdoc} */ - protected function getApiClass() + protected function getApiClass(): string { return IssueLinks::class; } - /** - * @test - */ + #[Test] public function shouldGetIssueLinks(): void { $expectedArray = [ @@ -40,15 +39,13 @@ public function shouldGetIssueLinks(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/10/links') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, 10)); } - /** - * @test - */ + #[Test] public function shouldCreateIssueLink(): void { $expectedArray = [ @@ -60,15 +57,13 @@ public function shouldCreateIssueLink(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/10/links', ['target_project_id' => 2, 'target_issue_iid' => 20]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, 10, 2, 20)); } - /** - * @test - */ + #[Test] public function shouldRemoveIssueLink(): void { $expectedArray = [ @@ -80,7 +75,7 @@ public function shouldRemoveIssueLink(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/issues/10/links/100') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->remove(1, 10, 100)); diff --git a/tests/Api/IssueSubscribeTest.php b/tests/Api/IssueSubscribeTest.php index 2918eef4..140a8313 100644 --- a/tests/Api/IssueSubscribeTest.php +++ b/tests/Api/IssueSubscribeTest.php @@ -28,7 +28,7 @@ public function testSubscribeIssue(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/subscribe') - ->will($this->returnValue($expectedValue)); + ->willReturn($expectedValue); $this->assertEquals($expectedValue, $api->subscribe(1, 2)); } @@ -40,12 +40,12 @@ public function testUnsubscribeIssue(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/unsubscribe') - ->will($this->returnValue($expectedValue)); + ->willReturn($expectedValue); $this->assertEquals($expectedValue, $api->unsubscribe(1, 2)); } - protected function getApiClass() + protected function getApiClass(): string { return Issues::class; } diff --git a/tests/Api/IssuesStatisticsTest.php b/tests/Api/IssuesStatisticsTest.php index 86898fd7..1b83cdb9 100644 --- a/tests/Api/IssuesStatisticsTest.php +++ b/tests/Api/IssuesStatisticsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\IssuesStatistics; +use PHPUnit\Framework\Attributes\Test; class IssuesStatisticsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAll(): void { $expectedArray = []; @@ -46,7 +45,7 @@ public function shouldGetAll(): void 'updated_before' => $now->format('c'), 'confidential' => 'false', ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->all([ 'milestone' => '', @@ -66,9 +65,7 @@ public function shouldGetAll(): void ])); } - /** - * @test - */ + #[Test] public function shouldGetProject(): void { $expectedArray = []; @@ -77,14 +74,12 @@ public function shouldGetProject(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues_statistics', []) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->project(1, [])); } - /** - * @test - */ + #[Test] public function shouldGetGroup(): void { $expectedArray = []; @@ -93,12 +88,12 @@ public function shouldGetGroup(): void $api->expects($this->once()) ->method('get') ->with('groups/1/issues_statistics', []) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->group(1, [])); } - protected function getApiClass() + protected function getApiClass(): string { return IssuesStatistics::class; } diff --git a/tests/Api/IssuesTest.php b/tests/Api/IssuesTest.php index c62e198f..ce72acb4 100644 --- a/tests/Api/IssuesTest.php +++ b/tests/Api/IssuesTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Issues; +use PHPUnit\Framework\Attributes\Test; class IssuesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllIssues(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllIssues(): void $api->expects($this->once()) ->method('get') ->with('issues', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetAllGroupIssues(): void { $expectedArray = [ @@ -52,15 +49,13 @@ public function shouldGetAllGroupIssues(): void $api->expects($this->once()) ->method('get') ->with('groups/1/issues', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->group(1)); } - /** - * @test - */ + #[Test] public function shouldGetGroupIssuesWithPagination(): void { $expectedArray = [ @@ -72,15 +67,13 @@ public function shouldGetGroupIssuesWithPagination(): void $api->expects($this->once()) ->method('get') ->with('groups/1/issues', ['page' => 2, 'per_page' => 5]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->group(1, ['page' => 2, 'per_page' => 5])); } - /** - * @test - */ + #[Test] public function shouldGetGroupIssuesWithParams(): void { $expectedArray = [ @@ -91,16 +84,14 @@ public function shouldGetGroupIssuesWithParams(): void $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('groups/1/issues', ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened']) - ->will($this->returnValue($expectedArray)) + ->with('groups/1/issues', ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened', 'iteration_title' => 'Title', 'assignee_id' => 1]) + ->willReturn($expectedArray) ; - $this->assertEquals($expectedArray, $api->group(1, ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened'])); + $this->assertEquals($expectedArray, $api->group(1, ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened', 'iteration_title' => 'Title', 'assignee_id' => 1])); } - /** - * @test - */ + #[Test] public function shouldGetProjectIssuesWithPagination(): void { $expectedArray = [ @@ -112,15 +103,13 @@ public function shouldGetProjectIssuesWithPagination(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues', ['page' => 2, 'per_page' => 5]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, ['page' => 2, 'per_page' => 5])); } - /** - * @test - */ + #[Test] public function shouldGetProjectIssuesWithParams(): void { $expectedArray = [ @@ -131,16 +120,14 @@ public function shouldGetProjectIssuesWithParams(): void $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/issues', ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened']) - ->will($this->returnValue($expectedArray)) + ->with('projects/1/issues', ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened', 'iteration_id' => 1, 'assignee_id' => 2]) + ->willReturn($expectedArray) ; - $this->assertEquals($expectedArray, $api->all(1, ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened'])); + $this->assertEquals($expectedArray, $api->all(1, ['order_by' => 'created_at', 'sort' => 'desc', 'labels' => 'foo,bar', 'state' => 'opened', 'iteration_id' => 1, 'assignee_id' => 2])); } - /** - * @test - */ + #[Test] public function shouldShowIssue(): void { $expectedArray = ['id' => 2, 'title' => 'Another issue']; @@ -149,15 +136,13 @@ public function shouldShowIssue(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateIssue(): void { $expectedArray = ['id' => 3, 'title' => 'A new issue']; @@ -166,15 +151,13 @@ public function shouldCreateIssue(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues', ['title' => 'A new issue', 'labels' => 'foo,bar']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['title' => 'A new issue', 'labels' => 'foo,bar'])); } - /** - * @test - */ + #[Test] public function shouldUpdateIssue(): void { $expectedArray = ['id' => 2, 'title' => 'A renamed issue']; @@ -183,15 +166,13 @@ public function shouldUpdateIssue(): void $api->expects($this->once()) ->method('put') ->with('projects/1/issues/2', ['title' => 'A renamed issue', 'labels' => 'foo']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 2, ['title' => 'A renamed issue', 'labels' => 'foo'])); } - /** - * @test - */ + #[Test] public function shouldReorderIssue(): void { $expectedArray = ['id' => 2, 'title' => 'A reordered issue']; @@ -199,14 +180,12 @@ public function shouldReorderIssue(): void $api->expects($this->once()) ->method('put') ->with('projects/1/issues/2/reorder', ['move_after_id' => 3, 'move_before_id' => 4]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->reorder(1, 2, ['move_after_id' => 3, 'move_before_id' => 4])); } - /** - * @test - */ + #[Test] public function shouldMoveIssue(): void { $expectedArray = ['id' => 2, 'title' => 'A moved issue']; @@ -215,15 +194,13 @@ public function shouldMoveIssue(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/move', ['to_project_id' => 3]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->move(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldGetNotes(): void { $expectedArray = [ @@ -235,15 +212,13 @@ public function shouldGetNotes(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/notes') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNotes(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -252,15 +227,13 @@ public function shouldGetNote(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/notes/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNote(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldCreateNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -269,15 +242,13 @@ public function shouldCreateNote(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/notes', ['body' => 'A new note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addNote(1, 2, 'A new note')); } - /** - * @test - */ + #[Test] public function shouldUpdateNote(): void { $expectedArray = ['id' => 3, 'body' => 'An edited comment']; @@ -286,15 +257,13 @@ public function shouldUpdateNote(): void $api->expects($this->once()) ->method('put') ->with('projects/1/issues/2/notes/3', ['body' => 'An edited comment']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateNote(1, 2, 3, 'An edited comment')); } - /** - * @test - */ + #[Test] public function shouldRemoveNote(): void { $expectedBool = true; @@ -303,15 +272,12 @@ public function shouldRemoveNote(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/issues/2/notes/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeNote(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldGetIssueDiscussions(): void { $expectedArray = [ @@ -323,15 +289,13 @@ public function shouldGetIssueDiscussions(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/discussions') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showDiscussions(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetIssueDiscussion(): void { $expectedArray = ['id' => 'abc', 'body' => 'A discussion']; @@ -340,15 +304,13 @@ public function shouldGetIssueDiscussion(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/discussions/abc') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showDiscussion(1, 2, 'abc')); } - /** - * @test - */ + #[Test] public function shouldCreateDiscussion(): void { $expectedArray = ['id' => 'abc', 'body' => 'A new discussion']; @@ -357,15 +319,13 @@ public function shouldCreateDiscussion(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/discussions', ['body' => 'A new discussion']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addDiscussion(1, 2, 'A new discussion')); } - /** - * @test - */ + #[Test] public function shouldCreateDiscussionNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new discussion note']; @@ -374,15 +334,13 @@ public function shouldCreateDiscussionNote(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/discussions/abc/notes', ['body' => 'A new discussion note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addDiscussionNote(1, 2, 'abc', 'A new discussion note')); } - /** - * @test - */ + #[Test] public function shouldUpdateDiscussionNote(): void { $expectedArray = ['id' => 3, 'body' => 'An edited discussion note']; @@ -391,15 +349,13 @@ public function shouldUpdateDiscussionNote(): void $api->expects($this->once()) ->method('put') ->with('projects/1/issues/2/discussions/abc/notes/3', ['body' => 'An edited discussion note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateDiscussionNote(1, 2, 'abc', 3, 'An edited discussion note')); } - /** - * @test - */ + #[Test] public function shouldRemoveDiscussionNote(): void { $expectedBool = true; @@ -408,15 +364,12 @@ public function shouldRemoveDiscussionNote(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/issues/2/discussions/abc/notes/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeDiscussionNote(1, 2, 'abc', 3)); } - /** - * @test - */ + #[Test] public function shouldSetTimeEstimate(): void { $expectedArray = ['time_estimate' => 14400, 'total_time_spent' => 0, 'human_time_estimate' => '4h', 'human_total_time_spent' => null]; @@ -425,15 +378,13 @@ public function shouldSetTimeEstimate(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/time_estimate', ['duration' => '4h']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->setTimeEstimate(1, 2, '4h')); } - /** - * @test - */ + #[Test] public function shouldResetTimeEstimate(): void { $expectedArray = ['time_estimate' => 0, 'total_time_spent' => 0, 'human_time_estimate' => null, 'human_total_time_spent' => null]; @@ -442,15 +393,13 @@ public function shouldResetTimeEstimate(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/reset_time_estimate') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->resetTimeEstimate(1, 2)); } - /** - * @test - */ + #[Test] public function shouldAddSpentTime(): void { $expectedArray = ['time_estimate' => 0, 'total_time_spent' => 14400, 'human_time_estimate' => null, 'human_total_time_spent' => '4h']; @@ -459,15 +408,13 @@ public function shouldAddSpentTime(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/add_spent_time', ['duration' => '4h']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addSpentTime(1, 2, '4h')); } - /** - * @test - */ + #[Test] public function shouldResetSpentTime(): void { $expectedArray = ['time_estimate' => 0, 'total_time_spent' => 0, 'human_time_estimate' => null, 'human_total_time_spent' => null]; @@ -476,15 +423,13 @@ public function shouldResetSpentTime(): void $api->expects($this->once()) ->method('post') ->with('projects/1/issues/2/reset_spent_time') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->resetSpentTime(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetIssueTimeStats(): void { $expectedArray = ['time_estimate' => 14400, 'total_time_spent' => 5400, 'human_time_estimate' => '4h', 'human_total_time_spent' => '1h 30m']; @@ -493,15 +438,13 @@ public function shouldGetIssueTimeStats(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/time_stats') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->getTimeStats(1, 2)); } - /** - * @test - */ + #[Test] public function shouldIssueAwardEmoji(): void { $expectedArray = [ @@ -513,15 +456,13 @@ public function shouldIssueAwardEmoji(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/award_emoji') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); } - /** - * @test - */ + #[Test] public function shouldRevokeAwardEmoji(): void { $expectedBool = true; @@ -530,15 +471,12 @@ public function shouldRevokeAwardEmoji(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/issues/2/award_emoji/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals(true, $api->removeAwardEmoji(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldGetIssueClosedByMergeRequests(): void { $expectedArray = [ @@ -550,15 +488,13 @@ public function shouldGetIssueClosedByMergeRequests(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/closed_by') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->closedByMergeRequests(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetIssueRelatedMergeRequests(): void { $expectedArray = [ @@ -570,15 +506,13 @@ public function shouldGetIssueRelatedMergeRequests(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/related_merge_requests') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->relatedMergeRequests(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetProjectIssuesByAssignee(): void { $expectedArray = [ @@ -590,15 +524,13 @@ public function shouldGetProjectIssuesByAssignee(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues', ['assignee_id' => 1]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, ['assignee_id' => 1])); } - /** - * @test - */ + #[Test] public function shouldGetIssueParticipants(): void { $expectedArray = [ @@ -624,15 +556,13 @@ public function shouldGetIssueParticipants(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/participants') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showParticipants(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetIssueResourceLabelEvents(): void { $expectedArray = [ @@ -644,15 +574,13 @@ public function shouldGetIssueResourceLabelEvents(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/resource_label_events') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showResourceLabelEvents(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetIssueResourceLabelEvent(): void { $expectedArray = ['id' => 1, 'resource_type' => 'Issue', 'action' => 'add']; @@ -661,13 +589,13 @@ public function shouldGetIssueResourceLabelEvent(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues/2/resource_label_events/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showResourceLabelEvent(1, 2, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return Issues::class; } diff --git a/tests/Api/JobsTest.php b/tests/Api/JobsTest.php index 840e8ba6..6753353d 100644 --- a/tests/Api/JobsTest.php +++ b/tests/Api/JobsTest.php @@ -16,12 +16,11 @@ use Gitlab\Api\Jobs; use GuzzleHttp\Psr7\Response; +use PHPUnit\Framework\Attributes\Test; class JobsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllJobs(): void { $expectedArray = [ @@ -35,15 +34,13 @@ public function shouldGetAllJobs(): void ->with('projects/1/jobs', [ 'scope' => ['pending'], ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, ['scope' => Jobs::SCOPE_PENDING])); } - /** - * @test - */ + #[Test] public function shouldGetPipelineJobs(): void { $expectedArray = [ @@ -57,15 +54,35 @@ public function shouldGetPipelineJobs(): void ->with('projects/1/pipelines/2/jobs', [ 'scope' => ['pending', 'running'], ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->pipelineJobs(1, 2, ['scope' => [Jobs::SCOPE_PENDING, Jobs::SCOPE_RUNNING]])); } - /** - * @test - */ + #[Test] + public function shouldGetPipelineJobsIncludingRetried(): void + { + $expectedArray = [ + ['id' => 1, 'name' => 'A job'], + ['id' => 2, 'name' => 'Another job'], + ['id' => 3, 'name' => 'A job'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/pipelines/2/jobs', [ + 'scope' => ['pending', 'running'], + 'include_retried' => true, + ]) + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->pipelineJobs(1, 2, ['scope' => [Jobs::SCOPE_PENDING, Jobs::SCOPE_RUNNING], 'include_retried' => true])); + } + + #[Test] public function shouldGetPipelineBridges(): void { $expectedArray = [ @@ -79,15 +96,13 @@ public function shouldGetPipelineBridges(): void ->with('projects/1/pipelines/2/bridges', [ 'scope' => ['pending', 'running'], ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->pipelineBridges(1, 2, ['scope' => [Jobs::SCOPE_PENDING, Jobs::SCOPE_RUNNING]])); } - /** - * @test - */ + #[Test] public function shouldGetJob(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -96,15 +111,13 @@ public function shouldGetJob(): void $api->expects($this->once()) ->method('get') ->with('projects/1/jobs/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetArtifacts(): void { $returnedStream = new Response(200, [], 'foobar'); @@ -113,15 +126,26 @@ public function shouldGetArtifacts(): void $api->expects($this->once()) ->method('getAsResponse') ->with('projects/1/jobs/3/artifacts') - ->will($this->returnValue($returnedStream)) - ; + ->willReturn($returnedStream); $this->assertEquals('foobar', $api->artifacts(1, 3)->getContents()); } - /** - * @test - */ + #[Test] + public function shouldGetArtifactsByJobId(): void + { + $returnedStream = new Response(200, [], 'foobar'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('getAsResponse') + ->with('projects/1/jobs/3/artifacts/artifact_path') + ->willReturn($returnedStream); + + $this->assertEquals('foobar', $api->artifactByJobId(1, 3, 'artifact_path')->getContents()); + } + + #[Test] public function shouldGetArtifactsByRefName(): void { $returnedStream = new Response(200, [], 'foobar'); @@ -130,17 +154,14 @@ public function shouldGetArtifactsByRefName(): void $api->expects($this->once()) ->method('getAsResponse') ->with('projects/1/jobs/artifacts/master/download', [ - 'job' => 'job_name', + 'job' => 'job name', ]) - ->will($this->returnValue($returnedStream)) - ; + ->willReturn($returnedStream); - $this->assertEquals('foobar', $api->artifactsByRefName(1, 'master', 'job_name')->getContents()); + $this->assertEquals('foobar', $api->artifactsByRefName(1, 'master', 'job name')->getContents()); } - /** - * @test - */ + #[Test] public function shouldGetArtifactByRefName(): void { $returnedStream = new Response(200, [], 'foobar'); @@ -148,16 +169,14 @@ public function shouldGetArtifactByRefName(): void $api->expects($this->once()) ->method('getAsResponse') ->with('projects/1/jobs/artifacts/master/raw/artifact_path', [ - 'job' => 'job_name', + 'job' => 'job name', ]) - ->will($this->returnValue($returnedStream)) - ; - $this->assertEquals('foobar', $api->artifactByRefName(1, 'master', 'job_name', 'artifact_path')->getContents()); + ->willReturn($returnedStream); + + $this->assertEquals('foobar', $api->artifactByRefName(1, 'master', 'job name', 'artifact_path')->getContents()); } - /** - * @test - */ + #[Test] public function shouldGetTrace(): void { $expectedString = 'some trace'; @@ -166,15 +185,12 @@ public function shouldGetTrace(): void $api->expects($this->once()) ->method('get') ->with('projects/1/jobs/3/trace') - ->will($this->returnValue($expectedString)) - ; + ->willReturn($expectedString); $this->assertEquals($expectedString, $api->trace(1, 3)); } - /** - * @test - */ + #[Test] public function shouldCancel(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -183,15 +199,13 @@ public function shouldCancel(): void $api->expects($this->once()) ->method('post') ->with('projects/1/jobs/3/cancel') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->cancel(1, 3)); } - /** - * @test - */ + #[Test] public function shouldRetry(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -200,15 +214,13 @@ public function shouldRetry(): void $api->expects($this->once()) ->method('post') ->with('projects/1/jobs/3/retry') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->retry(1, 3)); } - /** - * @test - */ + #[Test] public function shouldErase(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -217,15 +229,13 @@ public function shouldErase(): void $api->expects($this->once()) ->method('post') ->with('projects/1/jobs/3/erase') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->erase(1, 3)); } - /** - * @test - */ + #[Test] public function shouldKeepArtifacts(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -234,15 +244,13 @@ public function shouldKeepArtifacts(): void $api->expects($this->once()) ->method('post') ->with('projects/1/jobs/3/artifacts/keep') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->keepArtifacts(1, 3)); } - /** - * @test - */ + #[Test] public function shouldPlay(): void { $expectedArray = ['id' => 3, 'name' => 'A job']; @@ -251,13 +259,13 @@ public function shouldPlay(): void $api->expects($this->once()) ->method('post') ->with('projects/1/jobs/3/play') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->play(1, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return Jobs::class; } diff --git a/tests/Api/KeysTest.php b/tests/Api/KeysTest.php index 89af69f5..08c7f268 100644 --- a/tests/Api/KeysTest.php +++ b/tests/Api/KeysTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Keys; +use PHPUnit\Framework\Attributes\Test; class KeysTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldShowKey(): void { $expectedArray = ['id' => 1, 'title' => 'A key', 'key' => 'ssh-rsa key', 'created_at' => '2016-01-01T01:00:00.000Z']; @@ -28,12 +27,12 @@ public function shouldShowKey(): void $api->expects($this->once()) ->method('get') ->with('keys/1') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1)); } - protected function getApiClass() + protected function getApiClass(): string { return Keys::class; } diff --git a/tests/Api/MergeRequestsTest.php b/tests/Api/MergeRequestsTest.php index 957d2efa..c0803014 100644 --- a/tests/Api/MergeRequestsTest.php +++ b/tests/Api/MergeRequestsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\MergeRequests; +use PHPUnit\Framework\Attributes\Test; class MergeRequestsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAll(): void { $expectedArray = $this->getMultipleMergeRequestsData(); @@ -29,15 +28,13 @@ public function shouldGetAll(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldGetAllWithNoProject(): void { $expectedArray = $this->getMultipleMergeRequestsData(); @@ -46,15 +43,13 @@ public function shouldGetAllWithNoProject(): void $api->expects($this->once()) ->method('get') ->with('merge_requests', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetAllWithParams(): void { $expectedArray = $this->getMultipleMergeRequestsData(); @@ -78,7 +73,7 @@ public function shouldGetAllWithParams(): void 'with_merge_status_recheck' => true, 'approved_by_ids' => [1], ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, [ @@ -99,26 +94,24 @@ public function shouldGetAllWithParams(): void ])); } - /** - * @test - */ + #[Test] public function shouldGetAllWithDateTimeParams(): void { $expectedArray = $this->getMultipleMergeRequestsData(); $createdAfter = new \DateTime('2018-01-01 00:00:00'); - $createdBefore = new \DateTime('2018-01-31 00:00:00'); + $createdBefore = new \DateTime('2018-01-31 12:00:00.123+03:00'); $expectedWithArray = [ - 'created_after' => $createdAfter->format(\DATE_ATOM), - 'created_before' => $createdBefore->format(\DATE_ATOM), + 'created_after' => '2018-01-01T00:00:00.000Z', + 'created_before' => '2018-01-31T09:00:00.123Z', ]; $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests', $expectedWithArray) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals( @@ -127,9 +120,7 @@ public function shouldGetAllWithDateTimeParams(): void ); } - /** - * @test - */ + #[Test] public function shouldShowMergeRequest(): void { $expectedArray = ['id' => 2, 'name' => 'A merge request']; @@ -138,15 +129,13 @@ public function shouldShowMergeRequest(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldShowMergeRequestWithOptionalParameters(): void { $expectedArray = [ @@ -160,7 +149,7 @@ public function shouldShowMergeRequestWithOptionalParameters(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2', ['include_diverged_commits_count' => true, 'include_rebase_in_progress' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2, [ @@ -169,9 +158,7 @@ public function shouldShowMergeRequestWithOptionalParameters(): void ])); } - /** - * @test - */ + #[Test] public function shouldCreateMergeRequestWithoutOptionalParams(): void { $expectedArray = ['id' => 3, 'title' => 'Merge Request']; @@ -184,15 +171,13 @@ public function shouldCreateMergeRequestWithoutOptionalParams(): void 'target_branch' => 'master', 'source_branch' => 'develop', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, 'develop', 'master', 'Merge Request')); } - /** - * @test - */ + #[Test] public function shouldCreateMergeRequestWithOptionalParams(): void { $expectedArray = ['id' => 3, 'title' => 'Merge Request']; @@ -209,7 +194,7 @@ public function shouldCreateMergeRequestWithOptionalParams(): void 'description' => 'Some changes', 'remove_source_branch' => true, ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals( @@ -224,9 +209,7 @@ public function shouldCreateMergeRequestWithOptionalParams(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateMergeRequest(): void { $expectedArray = ['id' => 2, 'title' => 'Updated title']; @@ -235,7 +218,7 @@ public function shouldUpdateMergeRequest(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2', ['title' => 'Updated title', 'description' => 'No so many changes now', 'state_event' => 'close']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 2, [ @@ -245,9 +228,7 @@ public function shouldUpdateMergeRequest(): void ])); } - /** - * @test - */ + #[Test] public function shouldMergeMergeRequest(): void { $expectedArray = ['id' => 2, 'title' => 'Updated title']; @@ -256,15 +237,13 @@ public function shouldMergeMergeRequest(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/merge', ['merge_commit_message' => 'Accepted']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->merge(1, 2, ['merge_commit_message' => 'Accepted'])); } - /** - * @test - */ + #[Test] public function shouldGetNotes(): void { $expectedArray = [ @@ -276,15 +255,13 @@ public function shouldGetNotes(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/notes') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNotes(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -293,15 +270,13 @@ public function shouldGetNote(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/notes/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNote(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldCreateNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -310,15 +285,13 @@ public function shouldCreateNote(): void $api->expects($this->once()) ->method('post') ->with('projects/1/merge_requests/2/notes', ['body' => 'A new note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addNote(1, 2, 'A new note')); } - /** - * @test - */ + #[Test] public function shouldUpdateNote(): void { $expectedArray = ['id' => 3, 'body' => 'An edited comment']; @@ -327,15 +300,13 @@ public function shouldUpdateNote(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/notes/3', ['body' => 'An edited comment']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateNote(1, 2, 3, 'An edited comment')); } - /** - * @test - */ + #[Test] public function shouldRemoveNote(): void { $expectedBool = true; @@ -344,15 +315,44 @@ public function shouldRemoveNote(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/merge_requests/2/notes/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeNote(1, 2, 3)); } - /** - * @test - */ + #[Test] + public function shouldGetMergeRequestParticipants(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'John Doe1', + 'username' => 'user1', + 'state' => 'active', + 'avatar_url' => 'http://www.gravatar.com/avatar/c922747a93b40d1ea88262bf1aebee62?s=80&d=identicon', + 'web_url' => 'http://localhost/user1', + ], + [ + 'id' => 5, + 'name' => 'John Doe5', + 'username' => 'user5', + 'state' => 'active', + 'avatar_url' => 'http://www.gravatar.com/avatar/4aea8cf834ed91844a2da4ff7ae6b491?s=80&d=identicon', + 'web_url' => 'http://localhost/user5', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/merge_requests/2/participants') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->showParticipants(1, 2)); + } + + #[Test] public function shouldGetMergeRequestChanges(): void { $expectedArray = ['id' => 1, 'title' => 'A merge request']; @@ -361,15 +361,13 @@ public function shouldGetMergeRequestChanges(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/changes') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->changes(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMergeRequestDiscussions(): void { $expectedArray = [ @@ -381,15 +379,13 @@ public function shouldGetMergeRequestDiscussions(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/discussions') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showDiscussions(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMergeRequestDiscussion(): void { $expectedArray = ['id' => 'abc', 'body' => 'A discussion']; @@ -398,15 +394,13 @@ public function shouldGetMergeRequestDiscussion(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/discussions/abc') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showDiscussion(1, 2, 'abc')); } - /** - * @test - */ + #[Test] public function shouldCreateDiscussion(): void { $expectedArray = ['id' => 'abc', 'body' => 'A new discussion']; @@ -415,15 +409,13 @@ public function shouldCreateDiscussion(): void $api->expects($this->once()) ->method('post') ->with('projects/1/merge_requests/2/discussions', ['body' => 'A new discussion']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addDiscussion(1, 2, ['body' => 'A new discussion'])); } - /** - * @test - */ + #[Test] public function shouldResolveDiscussion(): void { $expectedArray = ['id' => 'abc', 'resolved' => true]; @@ -432,15 +424,13 @@ public function shouldResolveDiscussion(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/discussions/abc', ['resolved' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->resolveDiscussion(1, 2, 'abc', true)); } - /** - * @test - */ + #[Test] public function shouldUnresolveDiscussion(): void { $expectedArray = ['id' => 'abc', 'resolved' => false]; @@ -449,15 +439,13 @@ public function shouldUnresolveDiscussion(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/discussions/abc', ['resolved' => false]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->resolveDiscussion(1, 2, 'abc', false)); } - /** - * @test - */ + #[Test] public function shouldCreateDiscussionNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new discussion note']; @@ -466,15 +454,13 @@ public function shouldCreateDiscussionNote(): void $api->expects($this->once()) ->method('post') ->with('projects/1/merge_requests/2/discussions/abc/notes', ['body' => 'A new discussion note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addDiscussionNote(1, 2, 'abc', 'A new discussion note')); } - /** - * @test - */ + #[Test] public function shouldUpdateDiscussionNote(): void { $expectedArray = ['id' => 3, 'body' => 'An edited discussion note']; @@ -483,15 +469,13 @@ public function shouldUpdateDiscussionNote(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/discussions/abc/notes/3', ['body' => 'An edited discussion note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateDiscussionNote(1, 2, 'abc', 3, ['body' => 'An edited discussion note'])); } - /** - * @test - */ + #[Test] public function shouldRemoveDiscussionNote(): void { $expectedBool = true; @@ -500,15 +484,12 @@ public function shouldRemoveDiscussionNote(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/merge_requests/2/discussions/abc/notes/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeDiscussionNote(1, 2, 'abc', 3)); } - /** - * @test - */ + #[Test] public function shouldGetIssuesClosedByMergeRequest(): void { $expectedArray = ['id' => 1, 'title' => 'A merge request']; @@ -517,15 +498,13 @@ public function shouldGetIssuesClosedByMergeRequest(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/closes_issues') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->closesIssues(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMergeRequestByIid(): void { $expectedArray = ['id' => 1, 'title' => 'A merge request']; @@ -534,15 +513,13 @@ public function shouldGetMergeRequestByIid(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests', ['iids' => [2]]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, ['iids' => [2]])); } - /** - * @test - */ + #[Test] public function shouldApproveMergeRequest(): void { $expectedArray = ['id' => 1, 'title' => 'Approvals API']; @@ -551,15 +528,13 @@ public function shouldApproveMergeRequest(): void $api->expects($this->once()) ->method('post') ->with('projects/1/merge_requests/2/approve') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->approve(1, 2)); } - /** - * @test - */ + #[Test] public function shouldUnApproveMergeRequest(): void { $expectedArray = ['id' => 1, 'title' => 'Approvals API']; @@ -568,15 +543,13 @@ public function shouldUnApproveMergeRequest(): void $api->expects($this->once()) ->method('post') ->with('projects/1/merge_requests/2/unapprove') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->unapprove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMergeRequestApprovals(): void { $expectedArray = ['id' => 1, 'title' => 'Approvals API']; @@ -585,15 +558,13 @@ public function shouldGetMergeRequestApprovals(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests', ['iids' => [2]]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1, ['iids' => [2]])); } - /** - * @test - */ + #[Test] public function shouldIssueMergeRequestAwardEmoji(): void { $expectedArray = [ @@ -605,15 +576,13 @@ public function shouldIssueMergeRequestAwardEmoji(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/award_emoji') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); } - /** - * @test - */ + #[Test] public function shouldRevokeMergeRequestAwardEmoji(): void { $expectedBool = true; @@ -622,15 +591,12 @@ public function shouldRevokeMergeRequestAwardEmoji(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/merge_requests/2/award_emoji/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals(true, $api->removeAwardEmoji(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shoudGetApprovalState(): void { $expectedArray = [ @@ -642,14 +608,12 @@ public function shoudGetApprovalState(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/approval_state') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->approvalState(1, 2)); } - /** - * @test - */ + #[Test] public function shoudGetLevelRules(): void { $expectedArray = [ @@ -672,14 +636,12 @@ public function shoudGetLevelRules(): void $api->expects($this->once()) ->method('get') ->with('projects/1/merge_requests/2/approval_rules') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->levelRules(1, 2)); } - /** - * @test - */ + #[Test] public function shoudCreateLevelRuleWithoutOptionalParameters(): void { $expectedArray = [ @@ -706,14 +668,12 @@ public function shoudCreateLevelRuleWithoutOptionalParameters(): void 'approvals_required' => 3, ] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createLevelRule(1, 2, 'Foo', 3)); } - /** - * @test - */ + #[Test] public function shoudCreateLevelRuleWithOptionalParameters(): void { $expectedArray = [ @@ -742,7 +702,7 @@ public function shoudCreateLevelRuleWithOptionalParameters(): void 'group_ids' => [104121], ] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createLevelRule(1, 2, 'Foo', 3, [ 'user_ids' => [1951878], @@ -750,9 +710,7 @@ public function shoudCreateLevelRuleWithOptionalParameters(): void ])); } - /** - * @test - */ + #[Test] public function shoudUpdateLevelRuleWithoutOptionalParameters(): void { $expectedArray = [ @@ -779,14 +737,12 @@ public function shoudUpdateLevelRuleWithoutOptionalParameters(): void 'approvals_required' => 3, ] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateLevelRule(1, 2, 20892835, 'Foo', 3)); } - /** - * @test - */ + #[Test] public function shoudUpdateLevelRuleWithOptionalParameters(): void { $expectedArray = [ @@ -815,7 +771,7 @@ public function shoudUpdateLevelRuleWithOptionalParameters(): void 'group_ids' => [104121], ] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateLevelRule(1, 2, 20892835, 'Foo', 3, [ 'user_ids' => [1951878], @@ -823,9 +779,7 @@ public function shoudUpdateLevelRuleWithOptionalParameters(): void ])); } - /** - * @test - */ + #[Test] public function shoudDeleteLevelRule(): void { $expectedValue = true; @@ -834,12 +788,12 @@ public function shoudDeleteLevelRule(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/merge_requests/2/approval_rules/3') - ->will($this->returnValue($expectedValue)); + ->willReturn($expectedValue); $this->assertEquals($expectedValue, $api->deleteLevelRule(1, 2, 3)); } - protected function getMultipleMergeRequestsData() + protected function getMultipleMergeRequestsData(): array { return [ ['id' => 1, 'title' => 'A merge request'], @@ -847,14 +801,12 @@ protected function getMultipleMergeRequestsData() ]; } - protected function getApiClass() + protected function getApiClass(): string { return MergeRequests::class; } - /** - * @test - */ + #[Test] public function shouldRebaseMergeRequest(): void { $expectedArray = ['rebase_in_progress' => true]; @@ -863,7 +815,7 @@ public function shouldRebaseMergeRequest(): void $api->expects($this->once()) ->method('put') ->with('projects/1/merge_requests/2/rebase', ['skip_ci' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->rebase(1, 2, [ diff --git a/tests/Api/MilestonesTest.php b/tests/Api/MilestonesTest.php index 5bb14797..bb9104be 100644 --- a/tests/Api/MilestonesTest.php +++ b/tests/Api/MilestonesTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Milestones; +use PHPUnit\Framework\Attributes\Test; class MilestonesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllMilestones(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllMilestones(): void $api->expects($this->once()) ->method('get') ->with('projects/1/milestones') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowMilestone(): void { $expectedArray = ['id' => 1, 'name' => 'A milestone']; @@ -49,15 +46,13 @@ public function shouldShowMilestone(): void $api->expects($this->once()) ->method('get') ->with('projects/1/milestones/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateMilestone(): void { $expectedArray = ['id' => 3, 'title' => 'A new milestone']; @@ -66,15 +61,13 @@ public function shouldCreateMilestone(): void $api->expects($this->once()) ->method('post') ->with('projects/1/milestones', ['description' => 'Some text', 'title' => 'A new milestone']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, ['description' => 'Some text', 'title' => 'A new milestone'])); } - /** - * @test - */ + #[Test] public function shouldUpdateMilestone(): void { $expectedArray = ['id' => 3, 'title' => 'Updated milestone']; @@ -83,15 +76,13 @@ public function shouldUpdateMilestone(): void $api->expects($this->once()) ->method('put') ->with('projects/1/milestones/3', ['title' => 'Updated milestone', 'due_date' => '2015-04-01', 'state_event' => 'close']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 3, ['title' => 'Updated milestone', 'due_date' => '2015-04-01', 'state_event' => 'close'])); } - /** - * @test - */ + #[Test] public function shouldRemoveMilestone(): void { $expectedBool = true; @@ -100,15 +91,12 @@ public function shouldRemoveMilestone(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/milestones/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMilestonesIssues(): void { $expectedArray = [ @@ -120,13 +108,31 @@ public function shouldGetMilestonesIssues(): void $api->expects($this->once()) ->method('get') ->with('projects/1/milestones/3/issues') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->issues(1, 3)); } - protected function getApiClass() + #[Test] + public function shouldGetMilestonesMergeRequests(): void + { + $expectedArray = [ + ['id' => 1, 'title' => 'A merge request'], + ['id' => 2, 'title' => 'Another merge request'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/milestones/3/merge_requests') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->mergeRequests(1, 3)); + } + + protected function getApiClass(): string { return Milestones::class; } diff --git a/tests/Api/PackagesTest.php b/tests/Api/PackagesTest.php index 44265c46..96553b6d 100644 --- a/tests/Api/PackagesTest.php +++ b/tests/Api/PackagesTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Packages; +use PHPUnit\Framework\Attributes\Test; final class PackagesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllPackages(): void { $expectedArray = [ @@ -43,14 +42,12 @@ public function shouldGetAllPackages(): void $api->expects($this->once()) ->method('get') ->with('projects/1/packages') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowPackage(): void { $expectedArray = [ @@ -61,14 +58,12 @@ public function shouldShowPackage(): void $api->expects($this->once()) ->method('get') ->with('projects/1/packages/1') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1, 1)); } - /** - * @test - */ + #[Test] public function shouldGetAllPackageFiles(): void { $expectedArray = [ @@ -81,14 +76,12 @@ public function shouldGetAllPackageFiles(): void $api->expects($this->once()) ->method('get') ->with('projects/1/packages/1/package_files') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->allFiles(1, 1)); } - /** - * @test - */ + #[Test] public function shouldRemovePackage(): void { $expectedBool = true; @@ -97,14 +90,12 @@ public function shouldRemovePackage(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/packages/1') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 1)); } - /** - * @test - */ + #[Test] public function shouldRemovePackageFile(): void { $expectedBool = true; @@ -113,12 +104,12 @@ public function shouldRemovePackageFile(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/packages/1/package_files/25') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeFile(1, 1, 25)); } - protected function getApiClass() + protected function getApiClass(): string { return Packages::class; } diff --git a/tests/Api/ProjectNamespacesTest.php b/tests/Api/ProjectNamespacesTest.php index 69e59ecd..7ac81c59 100644 --- a/tests/Api/ProjectNamespacesTest.php +++ b/tests/Api/ProjectNamespacesTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\ProjectNamespaces; +use PHPUnit\Framework\Attributes\Test; class ProjectNamespacesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllNamespaces(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllNamespaces(): void $api->expects($this->once()) ->method('get') ->with('namespaces', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldShowNamespace(): void { $expectedArray = ['id' => 1, 'name' => 'internal']; @@ -49,13 +46,13 @@ public function shouldShowNamespace(): void $api->expects($this->once()) ->method('get') ->with('namespaces/1') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1)); } - protected function getApiClass() + protected function getApiClass(): string { return ProjectNamespaces::class; } diff --git a/tests/Api/ProjectsTest.php b/tests/Api/ProjectsTest.php index 200de417..62b5dfcc 100644 --- a/tests/Api/ProjectsTest.php +++ b/tests/Api/ProjectsTest.php @@ -16,12 +16,13 @@ use DateTime; use Gitlab\Api\Projects; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\MockObject\MockObject; class ProjectsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -31,9 +32,7 @@ public function shouldGetAllProjects(): void $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetAllProjectsSortedByName(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -50,9 +49,7 @@ public function shouldGetAllProjectsSortedByName(): void ); } - /** - * @test - */ + #[Test] public function shouldNotNeedPaginationWhenGettingProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -61,14 +58,12 @@ public function shouldNotNeedPaginationWhenGettingProjects(): void $api->expects($this->once()) ->method('get') ->with('projects') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetAccessibleProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -78,9 +73,7 @@ public function shouldGetAccessibleProjects(): void $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetOwnedProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -90,9 +83,7 @@ public function shouldGetOwnedProjects(): void $this->assertEquals($expectedArray, $api->all(['owned' => true])); } - /** - * @test - */ + #[Test] public function shouldGetNotArchivedProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -102,10 +93,8 @@ public function shouldGetNotArchivedProjects(): void $this->assertEquals($expectedArray, $api->all(['archived' => false])); } - /** - * @test - * @dataProvider possibleAccessLevels - */ + #[Test] + #[DataProvider('possibleAccessLevels')] public function shouldGetProjectsWithMinimumAccessLevel($level): void { $expectedArray = $this->getMultipleProjectsData(); @@ -115,9 +104,7 @@ public function shouldGetProjectsWithMinimumAccessLevel($level): void $this->assertEquals($expectedArray, $api->all(['min_access_level' => $level])); } - /** - * @test - */ + #[Test] public function shouldSearchProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -126,9 +113,7 @@ public function shouldSearchProjects(): void $this->assertEquals($expectedArray, $api->all(['search' => 'a project'])); } - /** - * @test - */ + #[Test] public function shouldSearchProjectsWithNamespace(): void { $expectedArray = $this->getMultipleProjectsDataWithNamespace(); @@ -137,9 +122,7 @@ public function shouldSearchProjectsWithNamespace(): void $this->assertEquals($expectedArray, $api->all(['search' => 'a_project', 'search_namespaces' => true])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsAfterId(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -149,9 +132,7 @@ public function shouldGetProjectsAfterId(): void $this->assertEquals($expectedArray, $api->all(['id_after' => 0])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithLastActivityAfter(): void { $unixEpochDateTime = new DateTime('@0'); @@ -163,9 +144,7 @@ public function shouldGetProjectsWithLastActivityAfter(): void $this->assertEquals($expectedArray, $api->all(['last_activity_after' => $unixEpochDateTime])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithLastActivityBefore(): void { $now = new DateTime(); @@ -177,9 +156,7 @@ public function shouldGetProjectsWithLastActivityBefore(): void $this->assertEquals($expectedArray, $api->all(['last_activity_before' => $now])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithoutFailedRepositoryChecksum(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -189,9 +166,7 @@ public function shouldGetProjectsWithoutFailedRepositoryChecksum(): void $this->assertEquals($expectedArray, $api->all(['repository_checksum_failed' => false])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithDefaultRepositoryStorage(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -201,9 +176,7 @@ public function shouldGetProjectsWithDefaultRepositoryStorage(): void $this->assertEquals($expectedArray, $api->all(['repository_storage' => 'default'])); } - /** - * @test - */ + #[Test] public function shouldGetStarredProjects(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -213,9 +186,7 @@ public function shouldGetStarredProjects(): void $this->assertEquals($expectedArray, $api->all(['starred' => true])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithoutFailedWikiChecksum(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -225,9 +196,7 @@ public function shouldGetProjectsWithoutFailedWikiChecksum(): void $this->assertEquals($expectedArray, $api->all(['wiki_checksum_failed' => false])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithCustomAttributes(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -237,9 +206,7 @@ public function shouldGetProjectsWithCustomAttributes(): void $this->assertEquals($expectedArray, $api->all(['with_custom_attributes' => true])); } - /** - * @test - */ + #[Test] public function shouldGetProjectsWithPhpProgrammingLanguage(): void { $expectedArray = $this->getMultipleProjectsData(); @@ -249,9 +216,7 @@ public function shouldGetProjectsWithPhpProgrammingLanguage(): void $this->assertEquals($expectedArray, $api->all(['with_programming_language' => 'php'])); } - /** - * @test - */ + #[Test] public function shouldShowProject(): void { $expectedArray = ['id' => 1, 'name' => 'Project Name']; @@ -260,14 +225,12 @@ public function shouldShowProject(): void $api->expects($this->once()) ->method('get') ->with('projects/1') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1)); } - /** - * @test - */ + #[Test] public function shouldShowProjectWithStatistics(): void { $expectedArray = [ @@ -286,14 +249,12 @@ public function shouldShowProjectWithStatistics(): void $api->expects($this->once()) ->method('get') ->with('projects/1', ['statistics' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1, ['statistics' => true])); } - /** - * @test - */ + #[Test] public function shouldCreateProject(): void { $expectedArray = ['id' => 1, 'name' => 'Project Name']; @@ -302,16 +263,14 @@ public function shouldCreateProject(): void $api->expects($this->once()) ->method('post') ->with('projects', ['name' => 'Project Name', 'issues_enabled' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->create('Project Name', [ 'issues_enabled' => true, ])); } - /** - * @test - */ + #[Test] public function shouldUpdateProject(): void { $expectedArray = ['id' => 1, 'name' => 'Updated Name']; @@ -320,7 +279,7 @@ public function shouldUpdateProject(): void $api->expects($this->once()) ->method('put') ->with('projects/1', ['name' => 'Updated Name', 'issues_enabled' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->update(1, [ 'name' => 'Updated Name', @@ -328,9 +287,7 @@ public function shouldUpdateProject(): void ])); } - /** - * @test - */ + #[Test] public function shouldArchiveProject(): void { $expectedArray = ['id' => 1, 'archived' => true]; @@ -339,14 +296,12 @@ public function shouldArchiveProject(): void $api->expects($this->once()) ->method('post') ->with('projects/1/archive') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->archive(1)); } - /** - * @test - */ + #[Test] public function shouldUnarchiveProject(): void { $expectedArray = ['id' => 1, 'archived' => false]; @@ -355,14 +310,12 @@ public function shouldUnarchiveProject(): void $api->expects($this->once()) ->method('post') ->with('projects/1/unarchive') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->unarchive(1)); } - /** - * @test - */ + #[Test] public function shouldCreateProjectForUser(): void { $expectedArray = ['id' => 1, 'name' => 'Project Name']; @@ -371,16 +324,14 @@ public function shouldCreateProjectForUser(): void $api->expects($this->once()) ->method('post') ->with('projects/user/1', ['name' => 'Project Name', 'issues_enabled' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createForUser(1, 'Project Name', [ 'issues_enabled' => true, ])); } - /** - * @test - */ + #[Test] public function shouldRemoveProject(): void { $expectedBool = true; @@ -389,14 +340,12 @@ public function shouldRemoveProject(): void $api->expects($this->once()) ->method('delete') ->with('projects/1') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1)); } - /** - * @test - */ + #[Test] public function shouldGetPipelines(): void { $expectedArray = [ @@ -409,14 +358,12 @@ public function shouldGetPipelines(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipelines(1)); } - /** - * @test - */ + #[Test] public function shouldGetTriggers(): void { $expectedArray = [ @@ -428,14 +375,12 @@ public function shouldGetTriggers(): void $api->expects($this->once()) ->method('get') ->with('projects/1/triggers') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->triggers(1)); } - /** - * @test - */ + #[Test] public function shouldGetTrigger(): void { $expectedArray = [ @@ -448,16 +393,12 @@ public function shouldGetTrigger(): void $api->expects($this->once()) ->method('get') ->with('projects/1/triggers/3') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->trigger(1, 3)); } - /** - * Check we can request project issues. - * - * @test - */ + #[Test] public function shouldGetProjectIssues(): void { $expectedArray = $this->getProjectIssuesExpectedArray(); @@ -466,16 +407,12 @@ public function shouldGetProjectIssues(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->issues(1)); } - /** - * Check we can request project issues. - * - * @test - */ + #[Test] public function shouldGetProjectUsers(): void { $expectedArray = $this->getProjectUsersExpectedArray(); @@ -484,16 +421,12 @@ public function shouldGetProjectUsers(): void $api->expects($this->once()) ->method('get') ->with('projects/1/users') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->users(1)); } - /** - * Check we can request project issues with query parameters. - * - * @test - */ + #[Test] public function shouldGetProjectIssuesParameters(): void { $expectedArray = $this->getProjectIssuesExpectedArray(); @@ -502,7 +435,7 @@ public function shouldGetProjectIssuesParameters(): void $api->expects($this->once()) ->method('get') ->with('projects/1/issues') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->issues(1, ['state' => 'opened'])); } @@ -513,7 +446,7 @@ public function shouldGetProjectIssuesParameters(): void * @return array * Project issues list */ - public function getProjectIssuesExpectedArray() + public function getProjectIssuesExpectedArray(): array { return [ [ @@ -583,10 +516,8 @@ public function getProjectIssuesExpectedArray() /** * Get expected array for tests which check project users method. - * - * @return array */ - public function getProjectUsersExpectedArray() + public function getProjectUsersExpectedArray(): array { return [ [ @@ -600,9 +531,7 @@ public function getProjectUsersExpectedArray() ]; } - /** - * @test - */ + #[Test] public function shouldGetBoards(): void { $expectedArray = $this->getProjectIssuesExpectedArray(); @@ -611,7 +540,7 @@ public function shouldGetBoards(): void $api->expects($this->once()) ->method('get') ->with('projects/1/boards') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->boards(1)); } @@ -622,7 +551,7 @@ public function shouldGetBoards(): void * @return array * Project issues list */ - public function getProjectBoardsExpectedArray() + public function getProjectBoardsExpectedArray(): array { return [ [ @@ -673,9 +602,37 @@ public function getProjectBoardsExpectedArray() ]; } - /** - * @test - */ + #[Test] + public function shouldGetIterations(): void + { + $expectedArray = [ + [ + 'id' => 5, + 'iid' => 2, + 'sequence' => 1, + 'group_id' => 123, + 'title' => '2022: Sprint 1', + 'description' => '', + 'state' => 3, + 'created_at' => '2021-09-29T21:24:43.913Z', + 'updated_at' => '2022-03-29T19:09:08.368Z', + 'start_date' => '2022-01-10', + 'due_date' => '2022-01-23', + 'web_url' => 'https://example.com/groups/example/-/iterations/34', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/iterations') + ->willReturn($expectedArray) + ; + + $this->assertEquals($expectedArray, $api->iterations(1)); + } + + #[Test] public function shouldCreateTrigger(): void { $expectedArray = [ @@ -688,14 +645,26 @@ public function shouldCreateTrigger(): void $api->expects($this->once()) ->method('post') ->with('projects/1/triggers', ['description' => 'foobar']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createTrigger(1, 'foobar')); } - /** - * @test - */ + #[Test] + public function shouldRemoveTrigger(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1/triggers/2') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->removeTrigger(1, 2)); + } + + #[Test] public function shouldTriggerPipeline(): void { $expectedArray = [ @@ -712,14 +681,12 @@ public function shouldTriggerPipeline(): void 'projects/1/trigger/pipeline', ['ref' => 'master', 'token' => 'some_token', 'variables' => ['VAR_1' => 'value 1']] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->triggerPipeline(1, 'master', 'some_token', ['VAR_1' => 'value 1'])); } - /** - * @test - */ + #[Test] public function shouldGetPipelinesWithBooleanParam(): void { $expectedArray = [ @@ -732,14 +699,12 @@ public function shouldGetPipelinesWithBooleanParam(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines', ['yaml_errors' => 'false']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipelines(1, ['yaml_errors' => false])); } - /** - * @test - */ + #[Test] public function shouldGetPipelineWithDateParam(): void { $expectedArray = [ @@ -748,8 +713,8 @@ public function shouldGetPipelineWithDateParam(): void ['id' => 3, 'status' => 'pending', 'ref' => 'test-pipeline'], ]; - $updated_after = new \DateTime('2018-01-01 00:00:00'); - $updated_before = new \DateTime('2018-01-31 00:00:00'); + $updated_after = new DateTime('2018-01-01 00:00:00'); + $updated_before = new DateTime('2018-01-31 00:00:00'); $expectedWithArray = [ 'updated_after' => $updated_after->format('Y-m-d'), @@ -760,7 +725,7 @@ public function shouldGetPipelineWithDateParam(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines', $expectedWithArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipelines(1, [ 'updated_after' => $updated_after, @@ -768,9 +733,7 @@ public function shouldGetPipelineWithDateParam(): void ])); } - /** - * @test - */ + #[Test] public function shouldGetPipelinesWithSHA(): void { $expectedArray = [ @@ -783,14 +746,12 @@ public function shouldGetPipelinesWithSHA(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines', ['sha' => '123']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipelines(1, ['sha' => '123'])); } - /** - * @test - */ + #[Test] public function shouldGetPipeline(): void { $expectedArray = [ @@ -803,14 +764,30 @@ public function shouldGetPipeline(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines/3') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipeline(1, 3)); } - /** - * @test - */ + #[Test] + public function shouldGetPipelineJobs(): void + { + $expectedArray = [ + ['id' => 1, 'status' => 'success', 'stage' => 'Build'], + ['id' => 2, 'status' => 'failed', 'stage' => 'Build'], + ['id' => 3, 'status' => 'pending', 'stage' => 'Build'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/pipelines/3/jobs') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->pipelineJobs(1, 3)); + } + + #[Test] public function shouldGetPipelineVariables(): void { $expectedArray = [ @@ -822,14 +799,56 @@ public function shouldGetPipelineVariables(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipelines/3/variables') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->pipelineVariables(1, 3)); } - /** - * @test - */ + #[Test] + public function shouldGetPipelineTestReport(): void + { + $expectedArray = [ + 'total_time' => 0.011809, + 'total_count' => 8, + 'success_count' => 8, + 'failed_count' => 0, + 'skipped_count' => 0, + 'error_count' => 0, + 'test_suites' => [], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/pipelines/3/test_report') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->pipelineTestReport(1, 3)); + } + + #[Test] + public function shouldGetPipelineTestReportSummary(): void + { + $expectedArray = [ + 'total_time' => 0.011809, + 'total_count' => 8, + 'success_count' => 8, + 'failed_count' => 0, + 'skipped_count' => 0, + 'error_count' => 0, + 'test_suites' => [], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/pipelines/3/test_report_summary') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->pipelineTestReportSummary(1, 3)); + } + + #[Test] public function shouldCreatePipeline(): void { $expectedArray = [ @@ -839,15 +858,13 @@ public function shouldCreatePipeline(): void $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/pipeline', ['ref' => 'test-pipeline']) - ->will($this->returnValue($expectedArray)); + ->with('projects/1/pipeline', [], [], [], ['ref' => 'test-pipeline']) + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createPipeline(1, 'test-pipeline')); } - /** - * @test - */ + #[Test] public function shouldCreatePipelineWithVariables(): void { $expectedArray = [ @@ -868,15 +885,13 @@ public function shouldCreatePipelineWithVariables(): void $api = $this->getApiMock(); $api->expects($this->once()) ->method('post') - ->with('projects/1/pipeline', ['ref' => 'test-pipeline', 'variables' => $variables]) - ->will($this->returnValue($expectedArray)); + ->with('projects/1/pipeline', ['variables' => $variables], [], [], ['ref' => 'test-pipeline']) + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createPipeline(1, 'test-pipeline', $variables)); } - /** - * @test - */ + #[Test] public function shouldRetryPipeline(): void { $expectedArray = [ @@ -887,14 +902,12 @@ public function shouldRetryPipeline(): void $api->expects($this->once()) ->method('post') ->with('projects/1/pipelines/4/retry') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->retryPipeline(1, 4)); } - /** - * @test - */ + #[Test] public function shouldCancelPipeline(): void { $expectedArray = [ @@ -905,14 +918,12 @@ public function shouldCancelPipeline(): void $api->expects($this->once()) ->method('post') ->with('projects/1/pipelines/6/cancel') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->cancelPipeline(1, 6)); } - /** - * @test - */ + #[Test] public function shouldDeletePipeline(): void { $expectedBool = true; @@ -921,14 +932,12 @@ public function shouldDeletePipeline(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/pipelines/3') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deletePipeline(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetAllMembers(): void { $expectedArray = [ @@ -940,14 +949,12 @@ public function shouldGetAllMembers(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members/all') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->allMembers(1)); } - /** - * @test - */ + #[Test] public function shouldGetAllMember(): void { $expectedArray = ['id' => 2, 'name' => 'Bob']; @@ -956,14 +963,12 @@ public function shouldGetAllMember(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members/all/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->allMember(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetMembers(): void { $expectedArray = [ @@ -975,14 +980,12 @@ public function shouldGetMembers(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->members(1)); } - /** - * @test - */ + #[Test] public function shouldGetMembersWithQuery(): void { $expectedArray = [ @@ -993,14 +996,12 @@ public function shouldGetMembersWithQuery(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members', ['query' => 'at']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->members(1, ['query' => 'at'])); } - /** - * @test - */ + #[Test] public function shouldGetMembersWithNullQuery(): void { $expectedArray = [ @@ -1012,14 +1013,12 @@ public function shouldGetMembersWithNullQuery(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->members(1)); } - /** - * @test - */ + #[Test] public function shouldGetMembersWithPagination(): void { $expectedArray = [ @@ -1034,14 +1033,12 @@ public function shouldGetMembersWithPagination(): void 'page' => 2, 'per_page' => 15, ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->members(1, ['page' => 2, 'per_page' => 15])); } - /** - * @test - */ + #[Test] public function shouldGetMember(): void { $expectedArray = ['id' => 2, 'name' => 'Matt']; @@ -1050,14 +1047,12 @@ public function shouldGetMember(): void $api->expects($this->once()) ->method('get') ->with('projects/1/members/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->member(1, 2)); } - /** - * @test - */ + #[Test] public function shouldAddMember(): void { $expectedArray = ['id' => 1, 'name' => 'Matt']; @@ -1066,14 +1061,32 @@ public function shouldAddMember(): void $api->expects($this->once()) ->method('post') ->with('projects/1/members', ['user_id' => 2, 'access_level' => 3]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addMember(1, 2, 3)); } - /** - * @test - */ + #[Test] + public function shouldAddMemberWithExpiration(): void + { + // tomorrow + $expiration = \date('Y-m-d', \time() + 86400); + $expectedArray = [ + 'user_id' => 3, + 'access_level' => 3, + 'expires_at' => $expiration, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/members', ['user_id' => 3, 'access_level' => 3, 'expires_at' => $expiration]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->addMember(1, 3, 3, $expiration)); + } + + #[Test] public function shouldSaveMember(): void { $expectedArray = ['id' => 1, 'name' => 'Matt']; @@ -1082,14 +1095,32 @@ public function shouldSaveMember(): void $api->expects($this->once()) ->method('put') ->with('projects/1/members/2', ['access_level' => 4]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->saveMember(1, 2, 4)); } - /** - * @test - */ + #[Test] + public function shouldSaveMemberWithExpiration(): void + { + // tomorrow + $expiration = \date('Y-m-d', \time() + 86400); + $expectedArray = [ + 'user_id' => 3, + 'access_level' => 4, + 'expires_at' => $expiration, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with('projects/1/members/3', ['access_level' => 4, 'expires_at' => $expiration]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->saveMember(1, 3, 4, $expiration)); + } + + #[Test] public function shouldRemoveMember(): void { $expectedBool = true; @@ -1098,14 +1129,12 @@ public function shouldRemoveMember(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/members/2') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeMember(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetHooks(): void { $expectedArray = [ @@ -1117,14 +1146,12 @@ public function shouldGetHooks(): void $api->expects($this->once()) ->method('get') ->with('projects/1/hooks') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->hooks(1)); } - /** - * @test - */ + #[Test] public function shouldGetHook(): void { $expectedArray = ['id' => 2, 'name' => 'Another hook']; @@ -1133,14 +1160,12 @@ public function shouldGetHook(): void $api->expects($this->once()) ->method('get') ->with('projects/1/hooks/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->hook(1, 2)); } - /** - * @test - */ + #[Test] public function shouldAddHook(): void { $expectedArray = ['id' => 3, 'name' => 'A new hook', 'url' => 'http://www.example.com/']; @@ -1154,7 +1179,7 @@ public function shouldAddHook(): void 'issues_events' => true, 'merge_requests_events' => true, ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addHook( 1, @@ -1163,9 +1188,7 @@ public function shouldAddHook(): void )); } - /** - * @test - */ + #[Test] public function shouldAddHookWithOnlyUrl(): void { $expectedArray = ['id' => 3, 'name' => 'A new hook', 'url' => 'http://www.example.com/']; @@ -1174,14 +1197,12 @@ public function shouldAddHookWithOnlyUrl(): void $api->expects($this->once()) ->method('post') ->with('projects/1/hooks', ['url' => 'http://www.example.com/', 'push_events' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addHook(1, 'http://www.example.com/')); } - /** - * @test - */ + #[Test] public function shouldAddHookWithoutPushEvents(): void { $expectedArray = ['id' => 3, 'name' => 'A new hook', 'url' => 'http://www.example.com/']; @@ -1190,14 +1211,12 @@ public function shouldAddHookWithoutPushEvents(): void $api->expects($this->once()) ->method('post') ->with('projects/1/hooks', ['url' => 'http://www.example.com/', 'push_events' => false]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addHook(1, 'http://www.example.com/', ['push_events' => false])); } - /** - * @test - */ + #[Test] public function shouldUpdateHook(): void { $expectedArray = ['id' => 3, 'name' => 'A new hook', 'url' => 'http://www.example.com/']; @@ -1206,7 +1225,7 @@ public function shouldUpdateHook(): void $api->expects($this->once()) ->method('put') ->with('projects/1/hooks/3', ['url' => 'http://www.example-test.com/', 'push_events' => false]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1214,9 +1233,7 @@ public function shouldUpdateHook(): void ); } - /** - * @test - */ + #[Test] public function shouldRemoveHook(): void { $expectedBool = true; @@ -1225,14 +1242,12 @@ public function shouldRemoveHook(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/hooks/2') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeHook(1, 2)); } - /** - * @test - */ + #[Test] public function shouldTransfer(): void { $expectedArray = [ @@ -1245,14 +1260,12 @@ public function shouldTransfer(): void $api->expects($this->once()) ->method('put') ->with('projects/1/transfer', ['namespace' => 'a_namespace']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->transfer(1, 'a_namespace')); } - /** - * @test - */ + #[Test] public function shouldGetDeployKeys(): void { $expectedArray = [ @@ -1264,14 +1277,12 @@ public function shouldGetDeployKeys(): void $api->expects($this->once()) ->method('get') ->with('projects/1/deploy_keys') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->deployKeys(1)); } - /** - * @test - */ + #[Test] public function shouldGetDeployKey(): void { $expectedArray = ['id' => 2, 'title' => 'another-key']; @@ -1280,14 +1291,12 @@ public function shouldGetDeployKey(): void $api->expects($this->once()) ->method('get') ->with('projects/1/deploy_keys/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->deployKey(1, 2)); } - /** - * @test - */ + #[Test] public function shouldAddKey(): void { $expectedArray = ['id' => 3, 'title' => 'new-key', 'can_push' => false]; @@ -1296,14 +1305,12 @@ public function shouldAddKey(): void $api->expects($this->once()) ->method('post') ->with('projects/1/deploy_keys', ['title' => 'new-key', 'key' => '...', 'can_push' => false]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addDeployKey(1, 'new-key', '...')); } - /** - * @test - */ + #[Test] public function shouldAddKeyWithPushOption(): void { $expectedArray = ['id' => 3, 'title' => 'new-key', 'can_push' => true]; @@ -1312,14 +1319,12 @@ public function shouldAddKeyWithPushOption(): void $api->expects($this->once()) ->method('post') ->with('projects/1/deploy_keys', ['title' => 'new-key', 'key' => '...', 'can_push' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addDeployKey(1, 'new-key', '...', true)); } - /** - * @test - */ + #[Test] public function shouldDeleteDeployKey(): void { $expectedBool = true; @@ -1328,14 +1333,12 @@ public function shouldDeleteDeployKey(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/deploy_keys/3') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteDeployKey(1, 3)); } - /** - * @test - */ + #[Test] public function shoudEnableDeployKey(): void { $expectedBool = true; @@ -1344,14 +1347,150 @@ public function shoudEnableDeployKey(): void $api->expects($this->once()) ->method('post') ->with('projects/1/deploy_keys/3/enable') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->enableDeployKey(1, 3)); } - /** - * @test - */ + #[Test] + public function shouldGetDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => false, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deploy_tokens') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->deployTokens(1)); + } + + #[Test] + public function shouldGetActiveDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => true, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deploy_tokens', ['active' => true]) + ->willReturn([]); + + $this->assertEquals([], $api->deployTokens(1, true)); + } + + #[Test] + public function shouldGetInactiveDeployTokens(): void + { + $expectedArray = [ + [ + 'id' => 1, + 'name' => 'MyToken', + 'username' => 'gitlab+deploy-token-1', + 'expires_at' => '2020-02-14T00:00:00.000Z', + 'revoked' => false, + 'expired' => true, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deploy_tokens', ['active' => false]) + ->willReturn([]); + + $this->assertEquals([], $api->deployTokens(1, false)); + } + + #[Test] + public function shouldCreateDeployToken(): void + { + $expectedArray = [ + 'id' => 1, + 'name' => 'My Deploy Token', + 'username' => 'custom-user', + 'token' => 'jMRvtPNxrn3crTAGukpZ', + 'expires_at' => '2021-01-01T00:00:00.000Z', + 'revoked' => false, + 'expired' => false, + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with( + 'projects/1/deploy_tokens', + [ + 'name' => 'My Deploy Token', + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + 'expires_at' => (new DateTime('2021-01-01'))->format('c'), + ] + ) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->createDeployToken(1, [ + 'name' => 'My Deploy Token', + 'scopes' => [ + 'read_repository', + 'read_registry', + ], + 'expires_at' => new DateTime('2021-01-01'), + ])); + } + + #[Test] + public function shouldDeleteDeployToken(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('projects/1/deploy_tokens/2') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->deleteDeployToken(1, 2)); + } + + #[Test] public function shouldGetEvents(): void { $expectedArray = [ @@ -1363,14 +1502,12 @@ public function shouldGetEvents(): void $api->expects($this->once()) ->method('get') ->with('projects/1/events', []) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1)); } - /** - * @test - */ + #[Test] public function shouldGetEventsWithDateTimeParams(): void { $expectedArray = [ @@ -1378,8 +1515,8 @@ public function shouldGetEventsWithDateTimeParams(): void ['id' => 2, 'title' => 'Another event'], ]; - $after = new \DateTime('2018-01-01 00:00:00'); - $before = new \DateTime('2018-01-31 00:00:00'); + $after = new DateTime('2018-01-01 00:00:00'); + $before = new DateTime('2018-01-31 00:00:00'); $expectedWithArray = [ 'after' => $after->format('Y-m-d'), @@ -1390,14 +1527,12 @@ public function shouldGetEventsWithDateTimeParams(): void $api->expects($this->once()) ->method('get') ->with('projects/1/events', $expectedWithArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1, ['after' => $after, 'before' => $before])); } - /** - * @test - */ + #[Test] public function shouldGetEventsWithPagination(): void { $expectedArray = [ @@ -1412,14 +1547,12 @@ public function shouldGetEventsWithPagination(): void 'page' => 2, 'per_page' => 15, ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1, ['page' => 2, 'per_page' => 15])); } - /** - * @test - */ + #[Test] public function shouldGetLabels(): void { $expectedArray = [ @@ -1431,14 +1564,12 @@ public function shouldGetLabels(): void $api->expects($this->once()) ->method('get') ->with('projects/1/labels') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->labels(1)); } - /** - * @test - */ + #[Test] public function shouldAddLabel(): void { $expectedArray = ['name' => 'bug', 'color' => '#000000']; @@ -1447,14 +1578,12 @@ public function shouldAddLabel(): void $api->expects($this->once()) ->method('post') ->with('projects/1/labels', ['name' => 'wont-fix', 'color' => '#ffffff']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addLabel(1, ['name' => 'wont-fix', 'color' => '#ffffff'])); } - /** - * @test - */ + #[Test] public function shouldUpdateLabel(): void { $expectedArray = ['name' => 'bug', 'color' => '#00ffff']; @@ -1463,7 +1592,7 @@ public function shouldUpdateLabel(): void $api->expects($this->once()) ->method('put') ->with('projects/1/labels/123', ['new_name' => 'big-bug', 'color' => '#00ffff']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1471,9 +1600,7 @@ public function shouldUpdateLabel(): void ); } - /** - * @test - */ + #[Test] public function shouldRemoveLabel(): void { $expectedBool = true; @@ -1482,28 +1609,24 @@ public function shouldRemoveLabel(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/labels/456', []) - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeLabel(1, 456)); } - /** - * @test - */ + #[Test] public function shouldGetLanguages(): void { $expectedArray = ['php' => 100]; $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->languages(1)); } - /** - * @test - */ + #[Test] public function shouldForkWithNamespace(): void { $expectedArray = [ @@ -1514,16 +1637,14 @@ public function shouldForkWithNamespace(): void $api->expects($this->once()) ->method('post') ->with('projects/1/fork', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->fork(1, [ 'namespace' => 'new_namespace', ])); } - /** - * @test - */ + #[Test] public function shouldForkWithNamespaceAndPath(): void { $expectedArray = [ @@ -1535,7 +1656,7 @@ public function shouldForkWithNamespaceAndPath(): void $api->expects($this->once()) ->method('post') ->with('projects/1/fork', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->fork(1, [ 'namespace' => 'new_namespace', @@ -1543,9 +1664,7 @@ public function shouldForkWithNamespaceAndPath(): void ])); } - /** - * @test - */ + #[Test] public function shouldForkWithNamespaceAndPathAndName(): void { $expectedArray = [ @@ -1558,7 +1677,7 @@ public function shouldForkWithNamespaceAndPathAndName(): void $api->expects($this->once()) ->method('post') ->with('projects/1/fork', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->fork(1, [ 'namespace' => 'new_namespace', @@ -1567,9 +1686,7 @@ public function shouldForkWithNamespaceAndPathAndName(): void ])); } - /** - * @test - */ + #[Test] public function shouldCreateForkRelation(): void { $expectedArray = ['project_id' => 1, 'forked_id' => 2]; @@ -1578,14 +1695,12 @@ public function shouldCreateForkRelation(): void $api->expects($this->once()) ->method('post') ->with('projects/1/fork/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createForkRelation(1, 2)); } - /** - * @test - */ + #[Test] public function shouldRemoveForkRelation(): void { $expectedBool = true; @@ -1594,14 +1709,12 @@ public function shouldRemoveForkRelation(): void $api->expects($this->once()) ->method('delete') ->with('projects/2/fork') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeForkRelation(2)); } - /** - * @test - */ + #[Test] public function shouldGetForks(): void { $expectedArray = [ @@ -1622,14 +1735,75 @@ public function shouldGetForks(): void $api->expects($this->once()) ->method('get') ->with('projects/1/forks') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->forks(1)); } - /** - * @test - */ + #[Test] + public function shouldGetForksUsingParameters(): void + { + $expectedArray = [ + [ + 'id' => 2, + 'forked_from_project' => [ + 'id' => 1, + ], + ], + [ + 'id' => 3, + 'forked_from_project' => [ + 'id' => 1, + ], + ], + ]; + $updated_after = new DateTime('2018-01-01 00:00:00'); + $updated_before = new DateTime('2018-01-31 00:00:00'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/forks', [ + 'archived' => 'false', + 'visibility' => 'public', + 'order_by' => 'id', + 'sort' => 'asc', + 'search' => 'term', + 'simple' => 'true', + 'owned' => 'false', + 'membership' => 'false', + 'starred' => 'false', + 'statistics' => 'false', + 'with_issues_enabled' => 'false', + 'with_merge_requests_enabled' => 'false', + 'min_access_level' => 30, + 'updated_after' => $updated_after->format('c'), + 'updated_before' => $updated_before->format('c'), + 'with_custom_attributes' => 'true', + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->forks(1, [ + 'archived' => false, + 'visibility' => 'public', + 'order_by' => 'id', + 'sort' => 'asc', + 'search' => 'term', + 'simple' => true, + 'owned' => false, + 'membership' => false, + 'starred' => false, + 'statistics' => false, + 'with_issues_enabled' => false, + 'with_merge_requests_enabled' => false, + 'min_access_level' => 30, + 'updated_after' => $updated_after, + 'updated_before' => $updated_before, + 'with_custom_attributes' => true, + ])); + } + + #[Test] public function shouldSetService(): void { $expectedBool = true; @@ -1638,14 +1812,12 @@ public function shouldSetService(): void $api->expects($this->once()) ->method('put') ->with('projects/1/services/hipchat', ['param' => 'value']) - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->setService(1, 'hipchat', ['param' => 'value'])); } - /** - * @test - */ + #[Test] public function shouldRemoveService(): void { $expectedBool = true; @@ -1654,14 +1826,12 @@ public function shouldRemoveService(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/services/hipchat') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeService(1, 'hipchat')); } - /** - * @test - */ + #[Test] public function shouldGetVariables(): void { $expectedArray = [ @@ -1673,14 +1843,12 @@ public function shouldGetVariables(): void $api->expects($this->once()) ->method('get') ->with('projects/1/variables') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->variables(1)); } - /** - * @test - */ + #[Test] public function shouldGetVariable(): void { $expectedArray = ['key' => 'ftp_username', 'value' => 'ftp']; @@ -1689,14 +1857,12 @@ public function shouldGetVariable(): void $api->expects($this->once()) ->method('get') ->with('projects/1/variables/ftp_username') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->variable(1, 'ftp_username')); } - /** - * @test - */ + #[Test] public function shouldAddVariable(): void { $expectedKey = 'ftp_port'; @@ -1711,14 +1877,12 @@ public function shouldAddVariable(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addVariable(1, $expectedKey, $expectedValue)); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithProtected(): void { $expectedArray = [ @@ -1731,14 +1895,12 @@ public function shouldAddVariableWithProtected(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addVariable(1, 'DEPLOY_SERVER', 'stage.example.com', true)); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithEnvironment(): void { $expectedArray = [ @@ -1751,7 +1913,7 @@ public function shouldAddVariableWithEnvironment(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1759,9 +1921,7 @@ public function shouldAddVariableWithEnvironment(): void ); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithProtectionAndEnvironment(): void { $expectedArray = [ @@ -1775,7 +1935,7 @@ public function shouldAddVariableWithProtectionAndEnvironment(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1783,9 +1943,7 @@ public function shouldAddVariableWithProtectionAndEnvironment(): void ); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithEnvironmentAndVariableType(): void { $expectedArray = [ @@ -1799,7 +1957,7 @@ public function shouldAddVariableWithEnvironmentAndVariableType(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1807,9 +1965,7 @@ public function shouldAddVariableWithEnvironmentAndVariableType(): void ); } - /** - * @test - */ + #[Test] public function shouldAddVariableWithEnvironmentFromParameterList(): void { $expectedArray = [ @@ -1822,7 +1978,7 @@ public function shouldAddVariableWithEnvironmentFromParameterList(): void $api->expects($this->once()) ->method('post') ->with('projects/1/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1830,9 +1986,7 @@ public function shouldAddVariableWithEnvironmentFromParameterList(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateVariable(): void { $expectedKey = 'ftp_port'; @@ -1847,14 +2001,12 @@ public function shouldUpdateVariable(): void $api->expects($this->once()) ->method('put') ->with('projects/1/variables/'.$expectedKey, ['value' => $expectedValue]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateVariable(1, $expectedKey, $expectedValue)); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithProtected(): void { $expectedArray = [ @@ -1867,14 +2019,12 @@ public function shouldUpdateVariableWithProtected(): void $api->expects($this->once()) ->method('put') ->with('projects/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'protected' => true]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateVariable(1, 'DEPLOY_SERVER', 'stage.example.com', true)); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithEnvironment(): void { $expectedArray = [ @@ -1890,7 +2040,7 @@ public function shouldUpdateVariableWithEnvironment(): void 'projects/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'environment_scope' => 'staging'] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1898,9 +2048,7 @@ public function shouldUpdateVariableWithEnvironment(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithProtectedAndEnvironment(): void { $expectedArray = [ @@ -1917,7 +2065,7 @@ public function shouldUpdateVariableWithProtectedAndEnvironment(): void 'projects/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'protected' => true, 'environment_scope' => 'staging'] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1925,9 +2073,7 @@ public function shouldUpdateVariableWithProtectedAndEnvironment(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithEnvironmentAndVariableType(): void { $expectedArray = [ @@ -1944,7 +2090,7 @@ public function shouldUpdateVariableWithEnvironmentAndVariableType(): void 'projects/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'environment_scope' => 'staging', 'variable_type' => 'file'] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1952,9 +2098,7 @@ public function shouldUpdateVariableWithEnvironmentAndVariableType(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateVariableWithEnvironmentFromParameterList(): void { $expectedArray = [ @@ -1970,7 +2114,7 @@ public function shouldUpdateVariableWithEnvironmentFromParameterList(): void 'projects/1/variables/DEPLOY_SERVER', ['value' => 'stage.example.com', 'environment_scope' => 'staging'] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -1978,9 +2122,7 @@ public function shouldUpdateVariableWithEnvironmentFromParameterList(): void ); } - /** - * @test - */ + #[Test] public function shouldRemoveVariable(): void { $expectedBool = true; @@ -1989,25 +2131,23 @@ public function shouldRemoveVariable(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/variables/ftp_password') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeVariable(1, 'ftp_password')); } - protected function getMultipleProjectsRequestMock($path, $expectedArray = [], $expectedParameters = []) + protected function getMultipleProjectsRequestMock($path, $expectedArray = [], $expectedParameters = []): MockObject { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with($path, $expectedParameters) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); return $api; } - /** - * @test - */ + #[Test] public function shouldGetDeployments(): void { $expectedArray = [ @@ -2019,14 +2159,12 @@ public function shouldGetDeployments(): void $api->expects($this->once()) ->method('get') ->with('projects/1/deployments', []) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->deployments(1)); } - /** - * @test - */ + #[Test] public function shouldGetDeploymentsWithPagination(): void { $expectedArray = [ @@ -2041,12 +2179,66 @@ public function shouldGetDeploymentsWithPagination(): void 'page' => 2, 'per_page' => 15, ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->deployments(1, ['page' => 2, 'per_page' => 15])); } - protected function getMultipleProjectsData() + #[Test] + public function shouldGetDeploymentsSorted(): void + { + $expectedArray = [ + ['id' => 1, 'sha' => '0000001'], + ['id' => 2, 'sha' => '0000002'], + ['id' => 3, 'sha' => '0000003'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deployments', [ + 'order_by' => 'id', + 'sort' => 'asc', + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->deployments(1, ['order_by' => 'id', 'sort' => 'asc'])); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deployments', [ + 'order_by' => 'id', + 'sort' => 'desc', + ]) + ->willReturn(\array_reverse($expectedArray)); + + $this->assertEquals(\array_reverse($expectedArray), $api->deployments(1, ['order_by' => 'id', 'sort' => 'desc'])); + } + + #[Test] + public function shouldGetDeploymentsFiltered(): void + { + $expectedArray = [ + ['id' => 1, 'sha' => '0000001'], + ['id' => 2, 'sha' => '0000002'], + ['id' => 3, 'sha' => '0000003'], + ]; + + $time = new DateTime('now'); + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/deployments', [ + 'updated_after' => $time->format('c'), + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->deployments(1, ['updated_after' => $time])); + } + + protected function getMultipleProjectsData(): array { return [ ['id' => 1, 'name' => 'A project'], @@ -2054,7 +2246,7 @@ protected function getMultipleProjectsData() ]; } - protected function getMultipleProjectsDataWithNamespace() + protected function getMultipleProjectsDataWithNamespace(): array { return [ ['id' => 1, 'name' => 'A project', 'namespace' => ['id' => 4, 'name' => 'A namespace', 'path' => 'a_namespace']], @@ -2062,7 +2254,7 @@ protected function getMultipleProjectsDataWithNamespace() ]; } - public function possibleAccessLevels() + public static function possibleAccessLevels(): array { return [ [10], @@ -2073,7 +2265,7 @@ public function possibleAccessLevels() ]; } - public function getBadgeExpectedArray() + public function getBadgeExpectedArray(): array { return [ [ @@ -2095,9 +2287,7 @@ public function getBadgeExpectedArray() ]; } - /** - * @test - */ + #[Test] public function shouldGetBadges(): void { $expectedArray = $this->getBadgeExpectedArray(); @@ -2106,14 +2296,12 @@ public function shouldGetBadges(): void $api->expects($this->once()) ->method('get') ->with('projects/1/badges') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->badges(1)); } - /** - * @test - */ + #[Test] public function shouldGetBadge(): void { $expectedBadgesArray = $this->getBadgeExpectedArray(); @@ -2125,14 +2313,12 @@ public function shouldGetBadge(): void $api->expects($this->once()) ->method('get') ->with('projects/1/badges/1') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->badge(1, 1)); } - /** - * @test - */ + #[Test] public function shouldAddBadge(): void { $link_url = 'http://example.com/ci_status.svg?project=%{project_path}&ref=%{default_branch}'; @@ -2147,7 +2333,7 @@ public function shouldAddBadge(): void $api->expects($this->once()) ->method('post') ->with('projects/1/badges', ['link_url' => $link_url, 'image_url' => $image_url]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals( $expectedArray, @@ -2155,9 +2341,7 @@ public function shouldAddBadge(): void ); } - /** - * @test - */ + #[Test] public function shouldUpdateBadge(): void { $image_url = 'https://shields.io/my/new/badge'; @@ -2169,14 +2353,12 @@ public function shouldUpdateBadge(): void $api->expects($this->once()) ->method('put') ->with('projects/1/badges/2') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateBadge(1, 2, ['image_url' => $image_url])); } - /** - * @test - */ + #[Test] public function shouldRemoveBadge(): void { $expectedBool = true; @@ -2185,14 +2367,12 @@ public function shouldRemoveBadge(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/badges/1') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeBadge(1, 1)); } - /** - * @test - */ + #[Test] public function shouldAddProtectedBranch(): void { $expectedArray = [ @@ -2213,13 +2393,11 @@ public function shouldAddProtectedBranch(): void 'projects/1/protected_branches', ['name' => 'master', 'push_access_level' => 0, 'merge_access_level' => 30] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addProtectedBranch(1, ['name' => 'master', 'push_access_level' => 0, 'merge_access_level' => 30])); } - /** - * @test - */ + #[Test] public function shouldRemoveProtectedBranch(): void { $expectedBool = true; @@ -2229,14 +2407,12 @@ public function shouldRemoveProtectedBranch(): void ->with( 'projects/1/protected_branches/test-branch' ) - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteProtectedBranch(1, 'test-branch')); } - /** - * @test - */ + #[Test] public function shoudGetApprovalsConfiguration(): void { $expectedArray = [ @@ -2254,14 +2430,12 @@ public function shoudGetApprovalsConfiguration(): void $api->expects($this->once()) ->method('get') ->with('projects/1/approvals') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->approvalsConfiguration(1)); } - /** - * @test - */ + #[Test] public function shoudGetApprovalsRules(): void { $expectedArray = [ @@ -2282,14 +2456,12 @@ public function shoudGetApprovalsRules(): void $api->expects($this->once()) ->method('get') ->with('projects/1/approval_rules') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->approvalsRules(1)); } - /** - * @test - */ + #[Test] public function shoudCreateApprovalsRule(): void { $expectedArray = [ @@ -2304,7 +2476,7 @@ public function shoudCreateApprovalsRule(): void $api->expects($this->once()) ->method('post') ->with('projects/1/approval_rules/', ['name' => 'All Members', 'rule_type' => 'any_approver']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createApprovalsRule(1, [ 'name' => 'All Members', @@ -2312,9 +2484,7 @@ public function shoudCreateApprovalsRule(): void ])); } - /** - * @test - */ + #[Test] public function shoudUpdateApprovalsRule(): void { $expectedArray = [ @@ -2327,16 +2497,14 @@ public function shoudUpdateApprovalsRule(): void $api->expects($this->once()) ->method('put') ->with('projects/1/approval_rules/1', ['name' => 'Updated Name']) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateApprovalsRule(1, 1, [ 'name' => 'Updated Name', ])); } - /** - * @test - */ + #[Test] public function shoudDeleteApprovalsRule(): void { $expectedBool = true; @@ -2345,14 +2513,12 @@ public function shoudDeleteApprovalsRule(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/approval_rules/1') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteApprovalsRule(1, 1)); } - /** - * @test - */ + #[Test] public function shouldDeleteAllMergedBranches(): void { $expectedBool = true; @@ -2361,14 +2527,12 @@ public function shouldDeleteAllMergedBranches(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/repository/merged_branches') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteAllMergedBranches(1)); } - /** - * @test - */ + #[Test] public function shouldGetProtectedBranches(): void { $expectedArray = [ @@ -2396,14 +2560,12 @@ public function shouldGetProtectedBranches(): void $api->expects($this->once()) ->method('get') ->with('projects/1/protected_branches') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->protectedBranches(1)); } - /** - * @test - */ + #[Test] public function shouldGetProjectAccessTokens(): void { $expectedArray = [ @@ -2425,14 +2587,37 @@ public function shouldGetProjectAccessTokens(): void $api->expects($this->once()) ->method('get') ->with('projects/1/access_tokens') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->projectAccessTokens(1)); } - /** - * @test - */ + #[Test] + public function shouldGetProjectAccessToken(): void + { + $expectedArray = [ + 'user_id' => 141, + 'scopes' => [ + 'api', + ], + 'name' => 'token', + 'expires_at' => '2021-01-31', + 'id' => 42, + 'active' => true, + 'created_at' => '2021-01-20T22:11:48.151Z', + 'revoked' => false, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/access_tokens/42') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->projectAccessToken(1, 42)); + } + + #[Test] public function shouldCreateProjectAccessToken(): void { $expectedArray = [ @@ -2460,10 +2645,11 @@ public function shouldCreateProjectAccessToken(): void 'api', 'read_repository', ], + 'access_level' => 30, 'expires_at' => '2021-01-31', ] ) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->createProjectAccessToken(1, [ 'name' => 'test_token', @@ -2471,13 +2657,12 @@ public function shouldCreateProjectAccessToken(): void 'api', 'read_repository', ], + 'access_level' => 30, 'expires_at' => new DateTime('2021-01-31'), ])); } - /** - * @test - */ + #[Test] public function shouldDeleteProjectAccessToken(): void { $expectedBool = true; @@ -2486,14 +2671,12 @@ public function shouldDeleteProjectAccessToken(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/access_tokens/2') - ->will($this->returnValue($expectedBool)); + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteProjectAccessToken(1, 2)); } - /** - * @test - */ + #[Test] public function shouldUploadAvatar(): void { $emptyPNGContents = 'iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAACYElEQVR42u3UMQEAAAjDMFCO9GEAByQSerQrmQJeagMAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwADAAAwADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMAAzAAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwADMAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAMAAZwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAwAAAAwAMADAAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMADAAAADAAwAMAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAMAAAAMADAAwAOCybrx+H1CTHLYAAAAASUVORK5CYII='; @@ -2504,14 +2687,82 @@ public function shouldUploadAvatar(): void $api = $this->getApiMock(); $api->expects($this->once()) ->method('put') - ->with('projects/1/', [], [], ['avatar' => $fileName]) - ->will($this->returnValue($expectedArray)); + ->with('projects/1', [], [], ['avatar' => $fileName]) + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->uploadAvatar(1, $fileName)); \unlink($fileName); } - protected function getApiClass() + #[Test] + public function shouldAddProtectedTag(): void + { + $expectedArray = [ + 'name' => 'release-*', + 'create_access_level' => [ + ['access_level' => 40, 'access_level_description' => 'Maintainers'], + ['group_id' => 123], + ], + ]; + $api = $this->getApiMock(); + $params = [ + 'name' => 'release-*', + 'create_access_level' => 40, + 'allowed_to_create' => [['group_id' => 123]], + ]; + $api->expects($this->once()) + ->method('post') + ->with('projects/1/protected_tags', $params) + ->willReturn($expectedArray); + $this->assertEquals($expectedArray, $api->addProtectedTag(1, $params)); + } + + #[Test] + public function shouldRemoveProtectedTag(): void + { + $expectedBool = true; + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with( + 'projects/1/protected_tags/release-%2A' + ) + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->deleteProtectedTag(1, 'release-*')); + } + + protected function getApiClass(): string { return Projects::class; } + + #[Test] + public function shouldSearchGroups(): void + { + $expectedArray = [ + ['id' => 6, 'title' => 'Issue 6 bla'], + ['id' => 7, 'title' => 'Issue 7 bla'], + ['id' => 8, 'title' => 'Issue 8 bla'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/123/search', [ + 'scope' => 'issues', + 'confidential' => 'false', + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->search(123, [ + 'scope' => 'issues', + 'confidential' => false, + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ])); + } } diff --git a/tests/Api/RepositoriesTest.php b/tests/Api/RepositoriesTest.php index 54cf1c5e..3b5d7334 100644 --- a/tests/Api/RepositoriesTest.php +++ b/tests/Api/RepositoriesTest.php @@ -15,12 +15,12 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Repositories; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; class RepositoriesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetBranches(): void { $expectedArray = [ @@ -32,15 +32,13 @@ public function shouldGetBranches(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/branches', ['search' => '^term']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->branches(1, ['search' => '^term'])); } - /** - * @test - */ + #[Test] public function shouldGetBranch(): void { $expectedArray = ['name' => 'master']; @@ -49,15 +47,13 @@ public function shouldGetBranch(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/branches/master') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->branch(1, 'master')); } - /** - * @test - */ + #[Test] public function shouldCreateBranch(): void { $expectedArray = ['name' => 'feature']; @@ -66,15 +62,13 @@ public function shouldCreateBranch(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/branches', ['branch' => 'feature', 'ref' => 'master']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createBranch(1, 'feature', 'master')); } - /** - * @test - */ + #[Test] public function shouldDeleteBranch(): void { $expectedBool = true; @@ -83,15 +77,12 @@ public function shouldDeleteBranch(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/repository/branches/feature%2FTEST-15') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deleteBranch(1, 'feature/TEST-15')); } - /** - * @test - */ + #[Test] public function shouldProtectBranch(): void { $expectedArray = ['name' => 'master']; @@ -100,15 +91,13 @@ public function shouldProtectBranch(): void $api->expects($this->once()) ->method('put') ->with('projects/1/repository/branches/master/protect', ['developers_can_push' => false, 'developers_can_merge' => false]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->protectBranch(1, 'master')); } - /** - * @test - */ + #[Test] public function shouldProtectBranchWithPermissions(): void { $expectedArray = ['name' => 'master']; @@ -117,15 +106,13 @@ public function shouldProtectBranchWithPermissions(): void $api->expects($this->once()) ->method('put') ->with('projects/1/repository/branches/master/protect', ['developers_can_push' => true, 'developers_can_merge' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->protectBranch(1, 'master', true, true)); } - /** - * @test - */ + #[Test] public function shouldUnprotectBranch(): void { $expectedArray = ['name' => 'master']; @@ -134,15 +121,13 @@ public function shouldUnprotectBranch(): void $api->expects($this->once()) ->method('put') ->with('projects/1/repository/branches/master/unprotect') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->unprotectBranch(1, 'master')); } - /** - * @test - */ + #[Test] public function shouldGetTags(): void { $expectedArray = [ @@ -154,15 +139,13 @@ public function shouldGetTags(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/tags') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->tags(1, ['search' => '^term'])); } - /** - * @test - */ + #[Test] public function shouldCreateTag(): void { $expectedArray = ['name' => '1.0']; @@ -175,15 +158,13 @@ public function shouldCreateTag(): void 'ref' => 'abcd1234', 'message' => '1.0 release', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createTag(1, '1.0', 'abcd1234', '1.0 release')); } - /** - * @test - */ + #[Test] public function shouldCreateRelease(): void { $project_id = 1; @@ -200,15 +181,13 @@ public function shouldCreateRelease(): void 'tag_name' => $tagName, 'description' => $description, ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createRelease($project_id, $tagName, $description)); } - /** - * @test - */ + #[Test] public function shouldUpdateRelease(): void { $project_id = 1; @@ -225,15 +204,13 @@ public function shouldUpdateRelease(): void 'tag_name' => $tagName, 'description' => $description, ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateRelease($project_id, $tagName, $description)); } - /** - * @test - */ + #[Test] public function shouldGetReleases(): void { $project_id = 1; @@ -250,15 +227,13 @@ public function shouldGetReleases(): void $api->expects($this->once()) ->method('get') ->with('projects/1/releases') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->releases($project_id)); } - /** - * @test - */ + #[Test] public function shouldGetCommits(): void { $expectedArray = [ @@ -270,15 +245,13 @@ public function shouldGetCommits(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commits(1)); } - /** - * @test - */ + #[Test] public function shouldGetCommitsWithParams(): void { $expectedArray = [ @@ -290,15 +263,13 @@ public function shouldGetCommitsWithParams(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits', ['page' => 2, 'per_page' => 25, 'ref_name' => 'master', 'all' => 'true', 'with_stats' => 'true', 'path' => 'file_path/file_name']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commits(1, ['page' => 2, 'per_page' => 25, 'ref_name' => 'master', 'all' => true, 'with_stats' => true, 'path' => 'file_path/file_name'])); } - /** - * @test - */ + #[Test] public function shouldGetCommitsWithTimeParams(): void { $expectedArray = [ @@ -318,15 +289,13 @@ public function shouldGetCommitsWithTimeParams(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits', $expectedWithArray) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commits(1, ['since' => $since, 'until' => $until])); } - /** - * @test - */ + #[Test] public function shouldGetCommit(): void { $expectedArray = ['id' => 'abcd1234', 'title' => 'A commit']; @@ -335,15 +304,13 @@ public function shouldGetCommit(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits/abcd1234') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commit(1, 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldGetCommitRefs(): void { $expectedArray = [ @@ -355,32 +322,27 @@ public function shouldGetCommitRefs(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits/abcd1234/refs') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commitRefs(1, 'abcd1234')); } - /** - * @dataProvider dataGetCommitRefsWithParams - * @test - * - * @param string $type - * @param array $expectedArray - */ + #[Test] + #[DataProvider('dataGetCommitRefsWithParams')] public function shouldGetCommitRefsWithParams(string $type, array $expectedArray): void { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits/abcd1234/refs', ['type' => $type]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commitRefs(1, 'abcd1234', ['type' => $type])); } - public function dataGetCommitRefsWithParams() + public static function dataGetCommitRefsWithParams(): array { return [ 'type_tag' => [ @@ -394,9 +356,7 @@ public function dataGetCommitRefsWithParams() ]; } - /** - * @test - */ + #[Test] public function shouldCreateCommit(): void { $expectedArray = ['title' => 'Initial commit.', 'author_name' => 'John Doe', 'author_email' => 'john@example.com']; @@ -405,7 +365,7 @@ public function shouldCreateCommit(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/commits') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createCommit(1, [ @@ -428,9 +388,7 @@ public function shouldCreateCommit(): void ])); } - /** - * @test - */ + #[Test] public function shouldRevertCommit(): void { $expectedArray = ['title' => 'Initial commit.', 'author_name' => 'John Doe', 'author_email' => 'john@example.com']; @@ -439,15 +397,13 @@ public function shouldRevertCommit(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/commits/abcd1234/revert') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->revertCommit(1, 'develop', 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldGetCommitComments(): void { $expectedArray = [ @@ -459,15 +415,13 @@ public function shouldGetCommitComments(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits/abcd1234/comments') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->commitComments(1, 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldCreateCommitComment(): void { $expectedArray = ['id' => 2, 'title' => 'A new comment']; @@ -476,15 +430,13 @@ public function shouldCreateCommitComment(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/commits/abcd1234/comments', ['note' => 'A new comment']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createCommitComment(1, 'abcd1234', 'A new comment')); } - /** - * @test - */ + #[Test] public function shouldCreateCommitCommentWithParams(): void { $expectedArray = ['id' => 2, 'title' => 'A new comment']; @@ -497,7 +449,7 @@ public function shouldCreateCommitCommentWithParams(): void 'path' => '/some/file.txt', 'line' => 123, 'line_type' => 'old', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createCommitComment(1, 'abcd1234', 'A new comment', [ @@ -507,9 +459,7 @@ public function shouldCreateCommitCommentWithParams(): void ])); } - /** - * @test - */ + #[Test] public function shouldCompareStraight(): void { $expectedArray = ['commit' => 'object']; @@ -518,15 +468,13 @@ public function shouldCompareStraight(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/compare', ['from' => 'master', 'to' => 'feature', 'straight' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->compare(1, 'master', 'feature', true)); } - /** - * @test - */ + #[Test] public function shouldNotCompareStraight(): void { $expectedArray = ['commit' => 'object']; @@ -535,15 +483,13 @@ public function shouldNotCompareStraight(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/compare', ['from' => 'master', 'to' => 'feature', 'straight' => 'false']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->compare(1, 'master', 'feature')); } - /** - * @test - */ + #[Test] public function shouldCompareComplexBranchName(): void { $expectedArray = ['commit' => 'object']; @@ -552,15 +498,13 @@ public function shouldCompareComplexBranchName(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/compare', ['from' => 'master', 'to' => 'feature/760.fake-branch', 'straight' => 'true']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->compare(1, 'master', 'feature/760.fake-branch', true)); } - /** - * @test - */ + #[Test] public function shouldCompareWithFromProjectId(): void { $expectedArray = ['commit' => 'object']; @@ -569,15 +513,13 @@ public function shouldCompareWithFromProjectId(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/compare', ['from' => 'master', 'to' => 'feature', 'straight' => 'true', 'from_project_id' => '123']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->compare(1, 'master', 'feature', true, '123')); } - /** - * @test - */ + #[Test] public function shouldGetDiff(): void { $expectedArray = [ @@ -589,15 +531,13 @@ public function shouldGetDiff(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/commits/abcd1234/diff') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->diff(1, 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldGetTree(): void { $expectedArray = [ @@ -609,15 +549,13 @@ public function shouldGetTree(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/tree') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->tree(1)); } - /** - * @test - */ + #[Test] public function shouldGetTreeWithParams(): void { $expectedArray = [ @@ -629,15 +567,13 @@ public function shouldGetTreeWithParams(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/tree', ['path' => 'dir/', 'ref_name' => 'master']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->tree(1, ['path' => 'dir/', 'ref_name' => 'master'])); } - /** - * @test - */ + #[Test] public function shouldGetContributors(): void { $expectedArray = [ @@ -649,15 +585,13 @@ public function shouldGetContributors(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/contributors') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->contributors(1)); } - /** - * @test - */ + #[Test] public function shouldGetMergeBase(): void { $expectedArray = [ @@ -681,15 +615,13 @@ public function shouldGetMergeBase(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/merge_base', ['refs' => ['efgh5678efgh5678efgh5678efgh5678efgh5678', '1234567812345678123456781234567812345678']]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->mergeBase(1, ['efgh5678efgh5678efgh5678efgh5678efgh5678', '1234567812345678123456781234567812345678'])); } - /** - * @test - */ + #[Test] public function shouldCherryPick(): void { $expectedArray = [ @@ -714,13 +646,13 @@ public function shouldCherryPick(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/commits/123456123456/cherry_pick', ['branch' => 'feature_branch']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->cherryPick(1, '123456123456', ['branch' => 'feature_branch'])); } - protected function getApiClass() + protected function getApiClass(): string { return Repositories::class; } diff --git a/tests/Api/RepositoryFilesTest.php b/tests/Api/RepositoryFilesTest.php index 81600a59..d9dfdf3b 100644 --- a/tests/Api/RepositoryFilesTest.php +++ b/tests/Api/RepositoryFilesTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\RepositoryFiles; +use PHPUnit\Framework\Attributes\Test; class RepositoryFilesTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetBlob(): void { $expectedString = 'something in a file'; @@ -29,15 +28,12 @@ public function shouldGetBlob(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/files/dir%2Ffile1.txt/raw', ['ref' => 'abcd1234']) - ->will($this->returnValue($expectedString)) - ; + ->willReturn($expectedString); $this->assertEquals($expectedString, $api->getRawFile(1, 'dir/file1.txt', 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldGetFile(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -46,15 +42,13 @@ public function shouldGetFile(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/files/dir%2Ffile1.txt', ['ref' => 'abcd1234']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->getFile(1, 'dir/file1.txt', 'abcd1234')); } - /** - * @test - */ + #[Test] public function shouldCreateFile(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -68,7 +62,7 @@ public function shouldCreateFile(): void 'content' => 'some contents', 'commit_message' => 'Added new file', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createFile(1, [ @@ -79,9 +73,7 @@ public function shouldCreateFile(): void ])); } - /** - * @test - */ + #[Test] public function shouldCreateFileWithEncoding(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -96,7 +88,7 @@ public function shouldCreateFileWithEncoding(): void 'content' => 'some contents', 'commit_message' => 'Added new file', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createFile(1, [ @@ -108,9 +100,7 @@ public function shouldCreateFileWithEncoding(): void ])); } - /** - * @test - */ + #[Test] public function shouldCreateFileWithAuthor(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -126,7 +116,7 @@ public function shouldCreateFileWithAuthor(): void 'author_email' => 'gitlab@example.com', 'author_name' => 'GitLab User', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createFile(1, [ @@ -139,9 +129,7 @@ public function shouldCreateFileWithAuthor(): void ])); } - /** - * @test - */ + #[Test] public function shouldUpdateFile(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -155,7 +143,7 @@ public function shouldUpdateFile(): void 'content' => 'some new contents', 'commit_message' => 'Updated new file', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateFile(1, [ @@ -166,9 +154,7 @@ public function shouldUpdateFile(): void ])); } - /** - * @test - */ + #[Test] public function shouldUpdateFileWithEncoding(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -183,7 +169,7 @@ public function shouldUpdateFileWithEncoding(): void 'content' => 'c29tZSBuZXcgY29udGVudHM=', 'commit_message' => 'Updated file', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateFile(1, [ @@ -195,9 +181,7 @@ public function shouldUpdateFileWithEncoding(): void ])); } - /** - * @test - */ + #[Test] public function shouldUpdateFileWithAuthor(): void { $expectedArray = ['file_name' => 'file1.txt', 'file_path' => 'dir/file1.txt']; @@ -213,7 +197,7 @@ public function shouldUpdateFileWithAuthor(): void 'author_email' => 'gitlab@example.com', 'author_name' => 'GitLab User', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateFile(1, [ @@ -226,9 +210,7 @@ public function shouldUpdateFileWithAuthor(): void ])); } - /** - * @test - */ + #[Test] public function shouldDeleteFile(): void { $expectedArray = ['file_name' => 'app/project.rb', 'branch' => 'master']; @@ -241,7 +223,7 @@ public function shouldDeleteFile(): void 'branch' => 'master', 'commit_message' => 'Deleted file', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->deleteFile(1, [ @@ -251,9 +233,7 @@ public function shouldDeleteFile(): void ])); } - /** - * @test - */ + #[Test] public function shouldDeleteFileWithAuthor(): void { $expectedArray = ['file_name' => 'app/project.rb', 'branch' => 'master']; @@ -268,7 +248,7 @@ public function shouldDeleteFileWithAuthor(): void 'author_email' => 'gitlab@example.com', 'author_name' => 'GitLab User', ]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->deleteFile(1, [ @@ -280,10 +260,7 @@ public function shouldDeleteFileWithAuthor(): void ])); } - /** - * @return string - */ - protected function getApiClass() + protected function getApiClass(): string { return RepositoryFiles::class; } diff --git a/tests/Api/ResourceIterationEventsTest.php b/tests/Api/ResourceIterationEventsTest.php new file mode 100644 index 00000000..28b86ecd --- /dev/null +++ b/tests/Api/ResourceIterationEventsTest.php @@ -0,0 +1,135 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\ResourceIterationEvents; +use PHPUnit\Framework\Attributes\Test; + +class ResourceIterationEventsTest extends TestCase +{ + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'iteration' => [ + 'id' => 50, + 'iid' => 9, + 'group_id' => 5, + 'title' => 'Iteration I', + 'description' => 'Ipsum Lorem', + 'state' => 1, + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + ], + 'action' => 'add', + ], + [ + 'id' => 143, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-21T14=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'iteration' => [ + 'id' => 53, + 'iid' => 13, + 'group_id' => 5, + 'title' => 'Iteration II', + 'description' => 'Ipsum Lorem ipsum', + 'state' => 2, + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + ], + 'action' => 'remove', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_iteration_events', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all(1, 253)); + } + + #[Test] + public function shouldShowEvent(): void + { + $expectedArray = [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'iteration' => [ + 'id' => 50, + 'iid' => 9, + 'group_id' => 5, + 'title' => 'Iteration I', + 'description' => 'Ipsum Lorem', + 'state' => 1, + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + ], + 'action' => 'add', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_iteration_events/142', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->show(1, 253, 142)); + } + + protected function getApiClass(): string + { + return ResourceIterationEvents::class; + } +} diff --git a/tests/Api/ResourceLabelEventsTest.php b/tests/Api/ResourceLabelEventsTest.php new file mode 100644 index 00000000..8a2651ef --- /dev/null +++ b/tests/Api/ResourceLabelEventsTest.php @@ -0,0 +1,117 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\ResourceLabelEvents; +use PHPUnit\Framework\Attributes\Test; + +class ResourceLabelEventsTest extends TestCase +{ + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'label' => [ + 'id' => 73, + 'name' => 'a1', + 'color' => '#34495E', + 'description' => '', + ], + 'action' => 'add', + ], + [ + 'id' => 143, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'label' => [ + 'id' => 74, + 'name' => 'p1', + 'color' => '#0033CC', + 'description' => '', + ], + 'action' => 'remove', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_label_events', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all(1, 253)); + } + + #[Test] + public function shouldShowEvent(): void + { + $expectedArray = [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'label' => [ + 'id' => 73, + 'name' => 'a1', + 'color' => '#34495E', + 'description' => '', + ], + 'action' => 'add', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_label_events/142', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->show(1, 253, 142)); + } + + protected function getApiClass(): string + { + return ResourceLabelEvents::class; + } +} diff --git a/tests/Api/ResourceMilestoneEventsTest.php b/tests/Api/ResourceMilestoneEventsTest.php new file mode 100644 index 00000000..4fb35335 --- /dev/null +++ b/tests/Api/ResourceMilestoneEventsTest.php @@ -0,0 +1,138 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\ResourceMilestoneEvents; +use PHPUnit\Framework\Attributes\Test; + +class ResourceMilestoneEventsTest extends TestCase +{ + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'milestone' => [ + 'id' => 61, + 'iid' => 9, + 'project_id' => 7, + 'title' => 'v1.2', + 'description' => 'Ipsum Lorem', + 'state' => 'active', + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + 'web_url' => 'http=>//gitlab.example.com=>3000/group/project/-/milestones/9', + ], + 'action' => 'add', + ], + [ + 'id' => 143, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-21T14=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'milestone' => [ + 'id' => 61, + 'iid' => 9, + 'project_id' => 7, + 'title' => 'v1.2', + 'description' => 'Ipsum Lorem', + 'state' => 'active', + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + 'web_url' => 'http=>//gitlab.example.com=>3000/group/project/-/milestones/9', + ], + 'action' => 'remove', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_milestone_events', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all(1, 253)); + } + + #[Test] + public function shouldShowEvent(): void + { + $expectedArray = [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 253, + 'milestone' => [ + 'id' => 61, + 'iid' => 9, + 'project_id' => 7, + 'title' => 'v1.2', + 'description' => 'Ipsum Lorem', + 'state' => 'active', + 'created_at' => '2020-01-27T05=>07=>12.573Z', + 'updated_at' => '2020-01-27T05=>07=>12.573Z', + 'due_date' => null, + 'start_date' => null, + 'web_url' => 'http=>//gitlab.example.com=>3000/group/project/-/milestones/9', + ], + 'action' => 'add', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_milestone_events/142', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->show(1, 253, 142)); + } + + protected function getApiClass(): string + { + return ResourceMilestoneEvents::class; + } +} diff --git a/tests/Api/ResourceStateEventsTest.php b/tests/Api/ResourceStateEventsTest.php new file mode 100644 index 00000000..cad7b710 --- /dev/null +++ b/tests/Api/ResourceStateEventsTest.php @@ -0,0 +1,99 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\ResourceStateEvents; +use PHPUnit\Framework\Attributes\Test; + +class ResourceStateEventsTest extends TestCase +{ + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 11, + 'state' => 'opened', + ], + [ + 'id' => 143, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-21T14=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 11, + 'state' => 'closed', + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/11/resource_state_events', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all(1, 11)); + } + + #[Test] + public function shouldShowEvent(): void + { + $expectedArray = [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'resource_type' => 'Issue', + 'resource_id' => 11, + 'state' => 'opened', + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/11/resource_state_events/142', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->show(1, 11, 142)); + } + + protected function getApiClass(): string + { + return ResourceStateEvents::class; + } +} diff --git a/tests/Api/ResourceWeightEventsTest.php b/tests/Api/ResourceWeightEventsTest.php new file mode 100644 index 00000000..d554de7d --- /dev/null +++ b/tests/Api/ResourceWeightEventsTest.php @@ -0,0 +1,96 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\ResourceWeightEvents; +use PHPUnit\Framework\Attributes\Test; + +class ResourceWeightEventsTest extends TestCase +{ + #[Test] + public function shouldGetAllEvents(): void + { + $expectedArray = [ + [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'issue_id' => 253, + 'weight' => 3, + ], + [ + 'id' => 143, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-21T14=>38=>20.077Z', + 'issue_id' => 253, + 'weight' => 2, + ], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_weight_events', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all(1, 253)); + } + + #[Test] + public function shouldShowEvent(): void + { + $expectedArray = [ + 'id' => 142, + 'user' => [ + 'id' => 1, + 'name' => 'Administrator', + 'username' => 'root', + 'state' => 'active', + 'avatar_url' => 'https=>//www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', + 'web_url' => 'http=>//gitlab.example.com/root', + ], + 'created_at' => '2018-08-20T13=>38=>20.077Z', + 'issue_id' => 253, + 'weight' => 3, + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('projects/1/issues/253/resource_weight_events/142', []) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->show(1, 253, 142)); + } + + protected function getApiClass(): string + { + return ResourceWeightEvents::class; + } +} diff --git a/tests/Api/ScheduleTest.php b/tests/Api/ScheduleTest.php index 35625e85..e5f64e98 100644 --- a/tests/Api/ScheduleTest.php +++ b/tests/Api/ScheduleTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Schedules; +use PHPUnit\Framework\Attributes\Test; class ScheduleTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldCreateSchedule(): void { $expectedArray = [ @@ -49,7 +48,7 @@ public function shouldCreateSchedule(): void 'created_at' => '2017-05-19T13:31:08.849Z', 'updated_at' => '2017-05-19T13:40:17.727Z', ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->create( 1, @@ -67,9 +66,7 @@ public function shouldCreateSchedule(): void )); } - /** - * @test - */ + #[Test] public function shouldShowSchedule(): void { $expectedArray = ['id' => 1, 'name' => 'A schedule']; @@ -78,15 +75,13 @@ public function shouldShowSchedule(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipeline_schedules/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldShowAllSchedule(): void { $expectedArray = ['id' => 1, 'name' => 'A schedule']; @@ -95,15 +90,13 @@ public function shouldShowAllSchedule(): void $api->expects($this->once()) ->method('get') ->with('projects/1/pipeline_schedules') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showAll(1)); } - /** - * @test - */ + #[Test] public function shouldUpdateSchedule(): void { $expectedArray = ['id' => 3, 'title' => 'Updated schedule']; @@ -112,15 +105,13 @@ public function shouldUpdateSchedule(): void $api->expects($this->once()) ->method('put') ->with('projects/1/pipeline_schedules/3', ['title' => 'Updated schedule', 'due_date' => '2015-04-01', 'state_event' => 'close']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 3, ['title' => 'Updated schedule', 'due_date' => '2015-04-01', 'state_event' => 'close'])); } - /** - * @test - */ + #[Test] public function shouldRemoveSchedule(): void { $expectedBool = true; @@ -129,15 +120,12 @@ public function shouldRemoveSchedule(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/pipeline_schedules/2') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateScheduleVariable(): void { $expectedArray = [ @@ -150,7 +138,7 @@ public function shouldCreateScheduleVariable(): void $api->expects($this->once()) ->method('post') ->with('projects/1/pipeline_schedules/2/variables', $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->addVariable( 1, @@ -159,9 +147,7 @@ public function shouldCreateScheduleVariable(): void )); } - /** - * @test - */ + #[Test] public function shouldUpdateScheduleVariable(): void { $variabelName = 'FOO_BAR'; @@ -175,7 +161,7 @@ public function shouldUpdateScheduleVariable(): void $api->expects($this->once()) ->method('put') ->with('projects/1/pipeline_schedules/2/variables/'.$variabelName, $expectedArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->updateVariable( 1, @@ -185,9 +171,7 @@ public function shouldUpdateScheduleVariable(): void )); } - /** - * @test - */ + #[Test] public function shouldRemoveScheduleVariable(): void { $expectedBool = true; @@ -196,13 +180,40 @@ public function shouldRemoveScheduleVariable(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/pipeline_schedules/2/variables/FOO_BAR') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeVariable(1, 2, 'FOO_BAR')); } - protected function getApiClass() + #[Test] + public function shouldTakeOwnership(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/pipeline_schedules/2/take_ownership') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->takeOwnership(1, 2)); + } + + #[Test] + public function shouldPlay(): void + { + $expectedBool = true; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with('projects/1/pipeline_schedules/2/play') + ->willReturn($expectedBool); + + $this->assertEquals($expectedBool, $api->play(1, 2)); + } + + protected function getApiClass(): string { return Schedules::class; } diff --git a/tests/Api/SearchTest.php b/tests/Api/SearchTest.php new file mode 100644 index 00000000..cbb39a2e --- /dev/null +++ b/tests/Api/SearchTest.php @@ -0,0 +1,56 @@ + + * (c) Graham Campbell + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Gitlab\Tests\Api; + +use Gitlab\Api\Search; +use PHPUnit\Framework\Attributes\Test; + +class SearchTest extends TestCase +{ + #[Test] + public function shouldGetAll(): void + { + $expectedArray = [ + ['id' => 6, 'name' => 'Project 6 bla'], + ['id' => 7, 'name' => 'Project 7 bla'], + ['id' => 8, 'name' => 'Project 8 bla'], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with('search', [ + 'scope' => 'projects', + 'confidential' => 'false', + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ]) + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->all([ + 'scope' => 'projects', + 'confidential' => false, + 'search' => 'bla', + 'order_by' => 'created_at', + 'sort' => 'desc', + ])); + } + + protected function getApiClass(): string + { + return Search::class; + } +} diff --git a/tests/Api/SnippetsTest.php b/tests/Api/SnippetsTest.php index 16272201..0d75c5c9 100644 --- a/tests/Api/SnippetsTest.php +++ b/tests/Api/SnippetsTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Snippets; +use PHPUnit\Framework\Attributes\Test; class SnippetsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllSnippets(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllSnippets(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowSnippet(): void { $expectedArray = ['id' => 2, 'title' => 'Another snippet']; @@ -49,15 +46,13 @@ public function shouldShowSnippet(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateSnippet(): void { $expectedArray = ['id' => 3, 'title' => 'A new snippet']; @@ -66,15 +61,13 @@ public function shouldCreateSnippet(): void $api->expects($this->once()) ->method('post') ->with('projects/1/snippets', ['title' => 'A new snippet', 'code' => 'A file', 'file_name' => 'file.txt', 'visibility' => 'public']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create(1, 'A new snippet', 'file.txt', 'A file', 'public')); } - /** - * @test - */ + #[Test] public function shouldUpdateSnippet(): void { $expectedArray = ['id' => 3, 'title' => 'Updated snippet']; @@ -83,15 +76,13 @@ public function shouldUpdateSnippet(): void $api->expects($this->once()) ->method('put') ->with('projects/1/snippets/3', ['title' => 'Updated snippet', 'code' => 'New content', 'file_name' => 'new_file.txt']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 3, ['file_name' => 'new_file.txt', 'code' => 'New content', 'title' => 'Updated snippet'])); } - /** - * @test - */ + #[Test] public function shouldShowContent(): void { $expectedString = 'New content'; @@ -100,15 +91,12 @@ public function shouldShowContent(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets/3/raw') - ->will($this->returnValue($expectedString)) - ; + ->willReturn($expectedString); $this->assertEquals($expectedString, $api->content(1, 3)); } - /** - * @test - */ + #[Test] public function shouldRemoveSnippet(): void { $expectedBool = true; @@ -117,15 +105,12 @@ public function shouldRemoveSnippet(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/snippets/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetNotes(): void { $expectedArray = [ @@ -137,15 +122,13 @@ public function shouldGetNotes(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets/2/notes') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNotes(1, 2)); } - /** - * @test - */ + #[Test] public function shouldGetNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -154,15 +137,13 @@ public function shouldGetNote(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets/2/notes/3') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->showNote(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldCreateNote(): void { $expectedArray = ['id' => 3, 'body' => 'A new note']; @@ -171,15 +152,13 @@ public function shouldCreateNote(): void $api->expects($this->once()) ->method('post') ->with('projects/1/snippets/2/notes', ['body' => 'A new note']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->addNote(1, 2, 'A new note')); } - /** - * @test - */ + #[Test] public function shouldUpdateNote(): void { $expectedArray = ['id' => 3, 'body' => 'An edited comment']; @@ -188,15 +167,13 @@ public function shouldUpdateNote(): void $api->expects($this->once()) ->method('put') ->with('projects/1/snippets/2/notes/3', ['body' => 'An edited comment']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->updateNote(1, 2, 3, 'An edited comment')); } - /** - * @test - */ + #[Test] public function shouldRemoveNote(): void { $expectedBool = true; @@ -205,15 +182,12 @@ public function shouldRemoveNote(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/snippets/2/notes/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeNote(1, 2, 3)); } - /** - * @test - */ + #[Test] public function shouldIssueSnippetAwardEmoji(): void { $expectedArray = [ @@ -225,15 +199,13 @@ public function shouldIssueSnippetAwardEmoji(): void $api->expects($this->once()) ->method('get') ->with('projects/1/snippets/2/award_emoji') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->awardEmoji(1, 2)); } - /** - * @test - */ + #[Test] public function shouldRevokeSnippetAwardEmoji(): void { $expectedBool = true; @@ -242,13 +214,12 @@ public function shouldRevokeSnippetAwardEmoji(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/snippets/2/award_emoji/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals(true, $api->removeAwardEmoji(1, 2, 3)); } - protected function getApiClass() + protected function getApiClass(): string { return Snippets::class; } diff --git a/tests/Api/SystemHooksTest.php b/tests/Api/SystemHooksTest.php index 80834195..6c0d3845 100644 --- a/tests/Api/SystemHooksTest.php +++ b/tests/Api/SystemHooksTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\SystemHooks; +use PHPUnit\Framework\Attributes\Test; class SystemHooksTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllHooks(): void { $expectedArray = [ @@ -32,15 +31,13 @@ public function shouldGetAllHooks(): void $api->expects($this->once()) ->method('get') ->with('hooks') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldCreateHook(): void { $expectedArray = ['id' => 3, 'url' => 'http://www.example.net/']; @@ -49,15 +46,13 @@ public function shouldCreateHook(): void $api->expects($this->once()) ->method('post') ->with('hooks', ['url' => 'http://www.example.net/']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('http://www.example.net/')); } - /** - * @test - */ + #[Test] public function shouldTestHook(): void { $expectedBool = true; @@ -66,15 +61,12 @@ public function shouldTestHook(): void $api->expects($this->once()) ->method('get') ->with('hooks/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->test(3)); } - /** - * @test - */ + #[Test] public function shouldRemoveHook(): void { $expectedBool = true; @@ -83,13 +75,12 @@ public function shouldRemoveHook(): void $api->expects($this->once()) ->method('delete') ->with('hooks/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(3)); } - protected function getApiClass() + protected function getApiClass(): string { return SystemHooks::class; } diff --git a/tests/Api/TagsTest.php b/tests/Api/TagsTest.php index 25946aeb..2be94e67 100644 --- a/tests/Api/TagsTest.php +++ b/tests/Api/TagsTest.php @@ -15,12 +15,12 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Tags; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; class TagsTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllTags(): void { $expectedArray = [ @@ -32,13 +32,11 @@ public function shouldGetAllTags(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/tags') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->all(1)); } - /** - * @test - */ + #[Test] public function shouldShowTag(): void { $expectedArray = [ @@ -49,13 +47,11 @@ public function shouldShowTag(): void $api->expects($this->once()) ->method('get') ->with('projects/1/repository/tags/v1.0.0') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1, 'v1.0.0')); } - /** - * @test - */ + #[Test] public function shouldCreateTag(): void { $expectedArray = [ @@ -72,14 +68,12 @@ public function shouldCreateTag(): void $api->expects($this->once()) ->method('post') ->with('projects/1/repository/tags', $params) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->create(1, $params)); } - /** - * @test - */ + #[Test] public function shouldRemoveTag(): void { $expectedArray = [ @@ -90,18 +84,12 @@ public function shouldRemoveTag(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/repository/tags/v1.1.0') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->remove(1, 'v1.1.0')); } - /** - * @test - * @dataProvider releaseDataProvider - * - * @param string $releaseName - * @param string $description - * @param array $expectedResult - */ + #[Test] + #[DataProvider('releaseDataProvider')] public function shouldCreateRelease(string $releaseName, string $description, array $expectedResult): void { $params = [ @@ -112,19 +100,13 @@ public function shouldCreateRelease(string $releaseName, string $description, ar $api->expects($this->once()) ->method('post') ->with('projects/1/repository/tags/'.\str_replace('/', '%2F', $releaseName).'/release', $params) - ->will($this->returnValue($expectedResult)); + ->willReturn($expectedResult); $this->assertEquals($expectedResult, $api->createRelease(1, $releaseName, $params)); } - /** - * @test - * @dataProvider releaseDataProvider - * - * @param string $releaseName - * @param string $description - * @param array $expectedResult - */ + #[Test] + #[DataProvider('releaseDataProvider')] public function shouldUpdateRelease(string $releaseName, string $description, array $expectedResult): void { $params = [ @@ -135,16 +117,16 @@ public function shouldUpdateRelease(string $releaseName, string $description, ar $api->expects($this->once()) ->method('put') ->with('projects/1/repository/tags/'.\str_replace('/', '%2F', $releaseName).'/release', $params) - ->will($this->returnValue($expectedResult)); + ->willReturn($expectedResult); $this->assertEquals($expectedResult, $api->updateRelease(1, $releaseName, $params)); } - public function releaseDataProvider() + public static function releaseDataProvider(): array { return [ [ - 'tagName' => 'v1.1.0', + 'releaseName' => 'v1.1.0', 'description' => 'Amazing release. Wow', 'expectedResult' => [ 'tag_name' => '1.0.0', @@ -152,7 +134,7 @@ public function releaseDataProvider() ], ], [ - 'tagName' => 'version/1.1.0', + 'releaseName' => 'version/1.1.0', 'description' => 'Amazing release. Wow', 'expectedResult' => [ 'tag_name' => 'version/1.1.0', @@ -162,7 +144,7 @@ public function releaseDataProvider() ]; } - protected function getApiClass() + protected function getApiClass(): string { return Tags::class; } diff --git a/tests/Api/TestCase.php b/tests/Api/TestCase.php index 59bc8fb2..34f192c6 100644 --- a/tests/Api/TestCase.php +++ b/tests/Api/TestCase.php @@ -15,25 +15,18 @@ namespace Gitlab\Tests\Api; use Gitlab\Client; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase as BaseTestCase; use Psr\Http\Client\ClientInterface; abstract class TestCase extends BaseTestCase { - /** - * @return string - */ - abstract protected function getApiClass(); - - /** - * @param array $methods - * - * @return \PHPUnit\Framework\MockObject\MockObject - */ - protected function getApiMock(array $methods = []) + abstract protected function getApiClass(): string; + + protected function getApiMock(array $methods = []): MockObject { $httpClient = $this->getMockBuilder(ClientInterface::class) - ->setMethods(['sendRequest']) + ->onlyMethods(['sendRequest']) ->getMock(); $httpClient ->expects($this->any()) @@ -42,7 +35,7 @@ protected function getApiMock(array $methods = []) $client = Client::createWithHttpClient($httpClient); return $this->getMockBuilder($this->getApiClass()) - ->setMethods(\array_merge(['getAsResponse', 'get', 'post', 'postRaw', 'patch', 'delete', 'put', 'head'], $methods)) + ->onlyMethods(\array_merge(['getAsResponse', 'get', 'post', 'delete', 'put'], $methods)) ->setConstructorArgs([$client, null]) ->getMock(); } diff --git a/tests/Api/UsersTest.php b/tests/Api/UsersTest.php index 04f3e1d6..fdda2693 100644 --- a/tests/Api/UsersTest.php +++ b/tests/Api/UsersTest.php @@ -15,12 +15,13 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Users; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use PHPUnit\Framework\MockObject\MockObject; class UsersTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldGetAllUsers(): void { $expectedArray = [ @@ -32,15 +33,13 @@ public function shouldGetAllUsers(): void $api->expects($this->once()) ->method('get') ->with('users', []) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all()); } - /** - * @test - */ + #[Test] public function shouldGetActiveUsers(): void { $expectedArray = [ @@ -52,15 +51,13 @@ public function shouldGetActiveUsers(): void $api->expects($this->once()) ->method('get') ->with('users', ['active' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->all(['active' => true])); } - /** - * @test - */ + #[Test] public function shouldGetUsersWithDateTimeParams(): void { $expectedArray = [ @@ -80,7 +77,7 @@ public function shouldGetUsersWithDateTimeParams(): void $api->expects($this->once()) ->method('get') ->with('users', $expectedWithArray) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals( @@ -89,9 +86,7 @@ public function shouldGetUsersWithDateTimeParams(): void ); } - /** - * @test - */ + #[Test] public function shouldShowUser(): void { $expectedArray = ['id' => 1, 'name' => 'Matt']; @@ -100,13 +95,13 @@ public function shouldShowUser(): void $api->expects($this->once()) ->method('get') ->with('users/1') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->show(1)); } - protected function getUsersMembershipsData() + protected function getUsersMembershipsData(): array { return [ [ @@ -124,21 +119,19 @@ protected function getUsersMembershipsData() ]; } - protected function getUsersMembershipsRequestMock($path, $expectedArray = [], $expectedParameters = []) + protected function getUsersMembershipsRequestMock($path, $expectedArray = [], $expectedParameters = []): MockObject { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with($path, $expectedParameters) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; return $api; } - /** - * @test - */ + #[Test] public function shouldShowUsersMemberships(): void { $expectedArray = $this->getUsersMembershipsData(); @@ -148,9 +141,7 @@ public function shouldShowUsersMemberships(): void $this->assertEquals($expectedArray, $api->usersMemberships(1)); } - /** - * @test - */ + #[Test] public function shouldShowUsersMembershipsWithTypeProject(): void { $expectedArray = [$this->getUsersMembershipsData()[0]]; @@ -160,9 +151,7 @@ public function shouldShowUsersMembershipsWithTypeProject(): void $this->assertEquals($expectedArray, $api->usersMemberships(1, ['type' => 'Project'])); } - /** - * @test - */ + #[Test] public function shouldShowUsersMembershipsWithTypeNamespace(): void { $expectedArray = [$this->getUsersMembershipsData()[1]]; @@ -172,7 +161,7 @@ public function shouldShowUsersMembershipsWithTypeNamespace(): void $this->assertEquals($expectedArray, $api->usersMemberships(1, ['type' => 'Namespace'])); } - protected function getUsersProjectsData() + protected function getUsersProjectsData(): array { return [ ['id' => 1, 'name' => 'matt-project-1'], @@ -180,21 +169,19 @@ protected function getUsersProjectsData() ]; } - protected function getUsersProjectsRequestMock($path, $expectedArray = [], $expectedParameters = []) + protected function getUsersProjectsRequestMock($path, $expectedArray = [], $expectedParameters = []): MockObject { $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') ->with($path, $expectedParameters) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; return $api; } - /** - * @test - */ + #[Test] public function shouldShowUsersProjects(): void { $expectedArray = $this->getUsersProjectsData(); @@ -204,9 +191,7 @@ public function shouldShowUsersProjects(): void $this->assertEquals($expectedArray, $api->usersProjects(1)); } - /** - * @test - */ + #[Test] public function shouldShowUsersProjectsWithLimit(): void { $expectedArray = [$this->getUsersProjectsData()[0]]; @@ -216,9 +201,7 @@ public function shouldShowUsersProjectsWithLimit(): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['per_page' => 1])); } - /** - * @test - */ + #[Test] public function shouldGetAllUsersProjectsSortedByName(): void { $expectedArray = $this->getUsersProjectsData(); @@ -235,9 +218,7 @@ public function shouldGetAllUsersProjectsSortedByName(): void ); } - /** - * @test - */ + #[Test] public function shouldGetNotArchivedUsersProjects(): void { $expectedArray = $this->getUsersProjectsData(); @@ -247,9 +228,7 @@ public function shouldGetNotArchivedUsersProjects(): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['archived' => false])); } - /** - * @test - */ + #[Test] public function shouldGetOwnedUsersProjects(): void { $expectedArray = $this->getUsersProjectsData(); @@ -259,7 +238,7 @@ public function shouldGetOwnedUsersProjects(): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['owned' => true])); } - public function possibleAccessLevels() + public static function possibleAccessLevels(): array { return [ [10], @@ -270,10 +249,8 @@ public function possibleAccessLevels() ]; } - /** - * @test - * @dataProvider possibleAccessLevels - */ + #[Test] + #[DataProvider('possibleAccessLevels')] public function shouldGetProjectsWithMinimumAccessLevel($level): void { $expectedArray = $this->getUsersProjectsData(); @@ -283,9 +260,7 @@ public function shouldGetProjectsWithMinimumAccessLevel($level): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['min_access_level' => $level])); } - /** - * @test - */ + #[Test] public function shouldSearchUsersProjects(): void { $expectedArray = $this->getUsersProjectsData(); @@ -294,9 +269,84 @@ public function shouldSearchUsersProjects(): void $this->assertEquals($expectedArray, $api->usersProjects(1, ['search' => 'a project'])); } - /** - * @test - */ + #[Test] + public function shouldShowUsersStarredProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray); + + $this->assertEquals($expectedArray, $api->usersStarredProjects(1)); + } + + #[Test] + public function shouldShowUsersStarredProjectsWithLimit(): void + { + $expectedArray = [$this->getUsersProjectsData()[0]]; + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray, ['per_page' => 1]); + + $this->assertEquals($expectedArray, $api->usersStarredProjects(1, ['per_page' => 1])); + } + + #[Test] + public function shouldGetAllUsersStarredProjectsSortedByName(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock( + 'users/1/starred_projects', + $expectedArray, + ['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc'] + ); + + $this->assertEquals( + $expectedArray, + $api->usersStarredProjects(1, ['page' => 1, 'per_page' => 5, 'order_by' => 'name', 'sort' => 'asc']) + ); + } + + #[Test] + public function shouldGetNotArchivedUsersStarredProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray, ['archived' => 'false']); + + $this->assertEquals($expectedArray, $api->usersStarredProjects(1, ['archived' => false])); + } + + #[Test] + public function shouldGetOwnedUsersStarredProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray, ['owned' => 'true']); + + $this->assertEquals($expectedArray, $api->usersStarredProjects(1, ['owned' => true])); + } + + #[Test] + #[DataProvider('possibleAccessLevels')] + public function shouldGetStarredProjectsWithMinimumAccessLevel($level): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray, ['min_access_level' => $level]); + + $this->assertEquals($expectedArray, $api->usersStarredProjects(1, ['min_access_level' => $level])); + } + + #[Test] + public function shouldSearchUsersStarredProjects(): void + { + $expectedArray = $this->getUsersProjectsData(); + + $api = $this->getUsersProjectsRequestMock('users/1/starred_projects', $expectedArray, ['search' => 'a project']); + $this->assertEquals($expectedArray, $api->usersStarredProjects(1, ['search' => 'a project'])); + } + + #[Test] public function shouldCreateUser(): void { $expectedArray = ['id' => 3, 'name' => 'Billy']; @@ -305,15 +355,13 @@ public function shouldCreateUser(): void $api->expects($this->once()) ->method('post') ->with('users', ['email' => 'billy@example.com', 'password' => 'password']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('billy@example.com', 'password')); } - /** - * @test - */ + #[Test] public function shouldCreateUserWithAdditionalInfo(): void { $expectedArray = ['id' => 3, 'name' => 'Billy']; @@ -322,15 +370,13 @@ public function shouldCreateUserWithAdditionalInfo(): void $api->expects($this->once()) ->method('post') ->with('users', ['email' => 'billy@example.com', 'password' => 'password', 'name' => 'Billy', 'bio' => 'A person']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->create('billy@example.com', 'password', ['name' => 'Billy', 'bio' => 'A person'])); } - /** - * @test - */ + #[Test] public function shouldUpdateUser(): void { $expectedArray = ['id' => 3, 'name' => 'Billy Bob']; @@ -339,7 +385,7 @@ public function shouldUpdateUser(): void $api->expects($this->once()) ->method('put') ->with('users/3', ['name' => 'Billy Bob']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(3, ['name' => 'Billy Bob'])); @@ -350,15 +396,13 @@ public function shouldUpdateUser(): void $api->expects($this->once()) ->method('put') ->with('users/4', [], [], ['avatar' => '/some/image.jpg']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(4, [], ['avatar' => '/some/image.jpg'])); } - /** - * @test - */ + #[Test] public function shouldRemoveUser(): void { $expectedBool = true; @@ -367,15 +411,12 @@ public function shouldRemoveUser(): void $api->expects($this->once()) ->method('delete') ->with('users/1') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1)); } - /** - * @test - */ + #[Test] public function shouldBlockUser(): void { $expectedBool = true; @@ -384,15 +425,12 @@ public function shouldBlockUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/block') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->block(1)); } - /** - * @test - */ + #[Test] public function shouldUnblockUser(): void { $expectedBool = true; @@ -401,15 +439,12 @@ public function shouldUnblockUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/unblock') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->unblock(1)); } - /** - * @test - */ + #[Test] public function shouldActivateUser(): void { $expectedBool = true; @@ -418,15 +453,12 @@ public function shouldActivateUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/activate') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->activate(1)); } - /** - * @test - */ + #[Test] public function shouldDeactivateUser(): void { $expectedBool = true; @@ -435,15 +467,12 @@ public function shouldDeactivateUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/deactivate') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->deactivate(1)); } - /** - * @test - */ + #[Test] public function shouldShowCurrentUser(): void { $expectedArray = ['id' => 1, 'name' => 'Matt']; @@ -452,15 +481,13 @@ public function shouldShowCurrentUser(): void $api->expects($this->once()) ->method('get') ->with('user') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->me()); } - /** - * @test - */ + #[Test] public function shouldGetCurrentUserKeys(): void { $expectedArray = [ @@ -472,15 +499,13 @@ public function shouldGetCurrentUserKeys(): void $api->expects($this->once()) ->method('get') ->with('user/keys') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->keys(1)); } - /** - * @test - */ + #[Test] public function shouldGetCurrentUserKey(): void { $expectedArray = ['id' => 1, 'title' => 'A key']; @@ -489,15 +514,13 @@ public function shouldGetCurrentUserKey(): void $api->expects($this->once()) ->method('get') ->with('user/keys/1') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->key(1)); } - /** - * @test - */ + #[Test] public function shouldCreateKeyForCurrentUser(): void { $expectedArray = ['id' => 3, 'title' => 'A new key']; @@ -506,15 +529,13 @@ public function shouldCreateKeyForCurrentUser(): void $api->expects($this->once()) ->method('post') ->with('user/keys', ['title' => 'A new key', 'key' => '...']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createKey('A new key', '...')); } - /** - * @test - */ + #[Test] public function shouldDeleteKeyForCurrentUser(): void { $expectedBool = true; @@ -523,15 +544,12 @@ public function shouldDeleteKeyForCurrentUser(): void $api->expects($this->once()) ->method('delete') ->with('user/keys/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeKey(3)); } - /** - * @test - */ + #[Test] public function shouldGetUserKeys(): void { $expectedArray = [ @@ -543,15 +561,13 @@ public function shouldGetUserKeys(): void $api->expects($this->once()) ->method('get') ->with('users/1/keys') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userKeys(1)); } - /** - * @test - */ + #[Test] public function shouldGetUserKey(): void { $expectedArray = ['id' => 2, 'title' => 'Another key']; @@ -560,15 +576,13 @@ public function shouldGetUserKey(): void $api->expects($this->once()) ->method('get') ->with('users/1/keys/2') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userKey(1, 2)); } - /** - * @test - */ + #[Test] public function shouldCreateKeyForUser(): void { $expectedArray = ['id' => 3, 'title' => 'A new key']; @@ -577,15 +591,13 @@ public function shouldCreateKeyForUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/keys', ['title' => 'A new key', 'key' => '...']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createKeyForUser(1, 'A new key', '...')); } - /** - * @test - */ + #[Test] public function shouldDeleteKeyForUser(): void { $expectedBool = true; @@ -594,15 +606,12 @@ public function shouldDeleteKeyForUser(): void $api->expects($this->once()) ->method('delete') ->with('users/1/keys/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeUserKey(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetUserEmails(): void { $expectedArray = [ @@ -614,14 +623,12 @@ public function shouldGetUserEmails(): void $api->expects($this->once()) ->method('get') ->with('user/emails') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->emails()); } - /** - * @test - */ + #[Test] public function shouldGetSpecificUserEmail(): void { $expectedArray = ['id' => 1, 'email' => 'foo@bar.baz']; @@ -630,14 +637,12 @@ public function shouldGetSpecificUserEmail(): void $api->expects($this->once()) ->method('get') ->with('user/emails/1') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->email(1)); } - /** - * @test - */ + #[Test] public function shouldGetEmailsForUser(): void { $expectedArray = [ @@ -649,15 +654,13 @@ public function shouldGetEmailsForUser(): void $api->expects($this->once()) ->method('get') ->with('users/1/emails') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userEmails(1)); } - /** - * @test - */ + #[Test] public function shouldCreateEmailForUser(): void { $expectedArray = ['id' => 3, 'email' => 'foo@bar.example']; @@ -666,15 +669,13 @@ public function shouldCreateEmailForUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/emails', ['email' => 'foo@bar.example', 'skip_confirmation' => false]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createEmailForUser(1, 'foo@bar.example')); } - /** - * @test - */ + #[Test] public function shouldCreateConfirmedEmailForUser(): void { $expectedArray = ['id' => 4, 'email' => 'foo@baz.example']; @@ -683,15 +684,13 @@ public function shouldCreateConfirmedEmailForUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/emails', ['email' => 'foo@baz.example', 'skip_confirmation' => true]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createEmailForUser(1, 'foo@baz.example', true)); } - /** - * @test - */ + #[Test] public function shouldDeleteEmailForUser(): void { $expectedBool = true; @@ -700,15 +699,12 @@ public function shouldDeleteEmailForUser(): void $api->expects($this->once()) ->method('delete') ->with('users/1/emails/3') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeUserEmail(1, 3)); } - /** - * @test - */ + #[Test] public function shouldGetCurrentUserImpersonationTokens(): void { $expectedArray = [ @@ -720,15 +716,13 @@ public function shouldGetCurrentUserImpersonationTokens(): void $api->expects($this->once()) ->method('get') ->with('users/1/impersonation_tokens') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userImpersonationTokens(1)); } - /** - * @test - */ + #[Test] public function shouldGetUserImpersonationToken(): void { $expectedArray = ['id' => 2, 'name' => 'name']; @@ -737,15 +731,13 @@ public function shouldGetUserImpersonationToken(): void $api->expects($this->once()) ->method('get') ->with('users/1/impersonation_tokens/1') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userImpersonationToken(1, 1)); } - /** - * @test - */ + #[Test] public function shouldCreateImpersonationTokenForUser(): void { $expectedArray = ['id' => 1, 'name' => 'name']; @@ -754,15 +746,13 @@ public function shouldCreateImpersonationTokenForUser(): void $api->expects($this->once()) ->method('post') ->with('users/1/impersonation_tokens', ['name' => 'name', 'scopes' => ['api'], 'expires_at' => null]) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->createImpersonationToken(1, 'name', ['api'])); } - /** - * @test - */ + #[Test] public function shouldDeleteImpersonationTokenForUser(): void { $expectedBool = true; @@ -771,15 +761,12 @@ public function shouldDeleteImpersonationTokenForUser(): void $api->expects($this->once()) ->method('delete') ->with('users/1/impersonation_tokens/1') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->removeImpersonationToken(1, 1)); } - /** - * @test - */ + #[Test] public function shouldGetCurrentUserActiveImpersonationTokens(): void { $expectedArray = [ @@ -790,15 +777,13 @@ public function shouldGetCurrentUserActiveImpersonationTokens(): void $api->expects($this->once()) ->method('get') ->with('users/1/impersonation_tokens') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userImpersonationTokens(1, ['state' => 'active'])); } - /** - * @test - */ + #[Test] public function shouldGetCurrentUserInactiveImpersonationTokens(): void { $expectedArray = [ @@ -809,20 +794,18 @@ public function shouldGetCurrentUserInactiveImpersonationTokens(): void $api->expects($this->once()) ->method('get') ->with('users/1/impersonation_tokens') - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->userImpersonationTokens(1, ['state' => 'inactive'])); } - protected function getApiClass() + protected function getApiClass(): string { return Users::class; } - /** - * @test - */ + #[Test] public function shouldGetEvents(): void { $expectedArray = [ @@ -834,14 +817,12 @@ public function shouldGetEvents(): void $api->expects($this->once()) ->method('get') ->with('users/1/events', []) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1)); } - /** - * @test - */ + #[Test] public function shouldGetEventsWithDateTimeParams(): void { $expectedArray = [ @@ -861,14 +842,12 @@ public function shouldGetEventsWithDateTimeParams(): void $api->expects($this->once()) ->method('get') ->with('users/1/events', $expectedWithArray) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1, ['after' => $after, 'before' => $before])); } - /** - * @test - */ + #[Test] public function shouldGetEventsWithPagination(): void { $expectedArray = [ @@ -883,8 +862,24 @@ public function shouldGetEventsWithPagination(): void 'page' => 2, 'per_page' => 15, ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->events(1, ['page' => 2, 'per_page' => 15])); } + + #[Test] + public function getRemoveUserIdentity(): void + { + $expectedArray = [ + ['id' => 1, 'identities' => []], + ]; + + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with('users/1/identities/test') + ->willReturn($expectedArray); + + $this->assertEquals($expectedArray, $api->removeUserIdentity(1, 'test')); + } } diff --git a/tests/Api/VersionTest.php b/tests/Api/VersionTest.php index 66aa4870..63080a79 100644 --- a/tests/Api/VersionTest.php +++ b/tests/Api/VersionTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Version; +use PHPUnit\Framework\Attributes\Test; class VersionTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldShowVersion(): void { $expectedArray = [ @@ -32,11 +31,11 @@ public function shouldShowVersion(): void $api->expects($this->once()) ->method('get') ->with('version') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show()); } - protected function getApiClass() + protected function getApiClass(): string { return Version::class; } diff --git a/tests/Api/WikiTest.php b/tests/Api/WikiTest.php index 6798ba59..4bb28b52 100644 --- a/tests/Api/WikiTest.php +++ b/tests/Api/WikiTest.php @@ -15,12 +15,11 @@ namespace Gitlab\Tests\Api; use Gitlab\Api\Wiki; +use PHPUnit\Framework\Attributes\Test; class WikiTest extends TestCase { - /** - * @test - */ + #[Test] public function shouldCreateWiki(): void { $expectedArray = [ @@ -38,7 +37,7 @@ public function shouldCreateWiki(): void 'title' => 'Test Wiki', 'content' => 'This is the test Wiki', ]) - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->create( 1, @@ -50,9 +49,7 @@ public function shouldCreateWiki(): void )); } - /** - * @test - */ + #[Test] public function shouldShowWiki(): void { $expectedArray = [ @@ -65,14 +62,12 @@ public function shouldShowWiki(): void $api->expects($this->once()) ->method('get') ->with('projects/1/wikis/Test-Wiki') - ->will($this->returnValue($expectedArray)); + ->willReturn($expectedArray); $this->assertEquals($expectedArray, $api->show(1, 'Test-Wiki')); } - /** - * @test - */ + #[Test] public function shouldShowAllWiki(): void { $expectedArray = [ @@ -81,19 +76,19 @@ public function shouldShowAllWiki(): void 'format' => 'markdown', ]; + $params = ['with_content' => true]; + $api = $this->getApiMock(); $api->expects($this->once()) ->method('get') - ->with('projects/1/wikis') - ->will($this->returnValue($expectedArray)) + ->with('projects/1/wikis', $params) + ->willReturn($expectedArray) ; - $this->assertEquals($expectedArray, $api->showAll(1)); + $this->assertEquals($expectedArray, $api->showAll(1, $params)); } - /** - * @test - */ + #[Test] public function shouldUpdateWiki(): void { $expectedArray = [ @@ -107,15 +102,13 @@ public function shouldUpdateWiki(): void $api->expects($this->once()) ->method('put') ->with('projects/1/wikis/Test-Wiki', ['content' => 'This is the test Wiki that has been updated']) - ->will($this->returnValue($expectedArray)) + ->willReturn($expectedArray) ; $this->assertEquals($expectedArray, $api->update(1, 'Test-Wiki', ['content' => 'This is the test Wiki that has been updated'])); } - /** - * @test - */ + #[Test] public function shouldRemoveWiki(): void { $expectedBool = true; @@ -124,13 +117,12 @@ public function shouldRemoveWiki(): void $api->expects($this->once()) ->method('delete') ->with('projects/1/wikis/Test-Wiki') - ->will($this->returnValue($expectedBool)) - ; + ->willReturn($expectedBool); $this->assertEquals($expectedBool, $api->remove(1, 'Test-Wiki')); } - protected function getApiClass() + protected function getApiClass(): string { return Wiki::class; } diff --git a/tests/HttpClient/BuilderTest.php b/tests/HttpClient/BuilderTest.php index 0b017c32..56ce8a5a 100644 --- a/tests/HttpClient/BuilderTest.php +++ b/tests/HttpClient/BuilderTest.php @@ -17,6 +17,7 @@ use Gitlab\HttpClient\Builder; use Http\Client\Common\HttpMethodsClientInterface; use Http\Client\Common\Plugin; +use PHPUnit\Framework\Attributes\Before; use PHPUnit\Framework\TestCase; use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; @@ -27,14 +28,9 @@ */ class BuilderTest extends TestCase { - /** - * @var Builder - */ - private $subject; + private Builder $subject; - /** - * @before - */ + #[Before] public function initBuilder(): void { $this->subject = new Builder( diff --git a/tests/HttpClient/Message/ResponseMediatorTest.php b/tests/HttpClient/Message/ResponseMediatorTest.php index 4596ee24..7266ecfa 100644 --- a/tests/HttpClient/Message/ResponseMediatorTest.php +++ b/tests/HttpClient/Message/ResponseMediatorTest.php @@ -75,12 +75,7 @@ public function testGetErrrorMessageInvalidJson(): void public function testGetPagination(): void { - $header = <<<'TEXT' -; rel="first", -; rel="next", -; rel="prev", -; rel="last", -TEXT; + $header = '; rel="first",; rel="next",; rel="prev",; rel="last"'; $pagination = [ 'first' => 'https://example.gitlab.com/', diff --git a/tests/HttpClient/Util/QueryStringBuilderTest.php b/tests/HttpClient/Util/QueryStringBuilderTest.php index df3326ee..e3466897 100644 --- a/tests/HttpClient/Util/QueryStringBuilderTest.php +++ b/tests/HttpClient/Util/QueryStringBuilderTest.php @@ -14,23 +14,20 @@ namespace Gitlab\Tests\HttpClient\Util; +use Generator; use Gitlab\HttpClient\Util\QueryStringBuilder; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class QueryStringBuilderTest extends TestCase { - /** - * @dataProvider queryStringProvider - * - * @param array $query - * @param string $expected - */ + #[DataProvider('queryStringProvider')] public function testBuild(array $query, string $expected): void { $this->assertSame(\sprintf('?%s', $expected), QueryStringBuilder::build($query)); } - public function queryStringProvider() + public static function queryStringProvider(): Generator { yield 'indexed array' => [ [ diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 910aeaa3..e095c4ea 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -26,7 +26,7 @@ public function testRepoContributors(): void $response = $client ->repositories() - ->contributors(5315609); + ->contributors(16155465); $this->assertIsArray($response); $this->assertTrue(isset($response[2])); diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json index 4ba502da..a1bd73c4 100644 --- a/vendor-bin/phpstan/composer.json +++ b/vendor-bin/phpstan/composer.json @@ -1,11 +1,9 @@ { "require": { - "php": "^8.0.2", - "phpstan/phpstan": "1.4.2", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-strict-rules": "1.1.0", - "thecodingmachine/phpstan-strict-rules": "1.0.0", - "ergebnis/phpstan-rules": "1.0.0" + "php": "^8.1", + "phpstan/phpstan": "2.1.6", + "phpstan/phpstan-deprecation-rules": "2.0.1", + "phpstan/phpstan-strict-rules": "2.0.3" }, "config": { "preferred-install": "dist" diff --git a/vendor-bin/phpunit/composer.json b/vendor-bin/phpunit/composer.json index c8a184d5..21464a1e 100644 --- a/vendor-bin/phpunit/composer.json +++ b/vendor-bin/phpunit/composer.json @@ -1,7 +1,7 @@ { "require": { - "php": "^7.4.15 || ^8.0.2", - "phpunit/phpunit": "^9.5.12" + "php": "^8.1", + "phpunit/phpunit": "^10.5.45 || ^11.5.9" }, "config": { "preferred-install": "dist" diff --git a/vendor-bin/psalm/composer.json b/vendor-bin/psalm/composer.json index abd249a3..feebf503 100644 --- a/vendor-bin/psalm/composer.json +++ b/vendor-bin/psalm/composer.json @@ -1,7 +1,7 @@ { "require": { - "php": "^8.0.2", - "psalm/phar": "4.18.1" + "php": "^8.1", + "psalm/phar": "5.26.1" }, "config": { "preferred-install": "dist"