Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 113 additions & 82 deletions tests/lib/Controller/ConfigControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,44 @@
}
}

/**
* @param MockObject $mock The mock object on which the method is expected to be called
* @param string $method The method name for which the expectations are set
* @param array $calls An array of expected argument arrays for each call
*/
private function expectMethodCalls(
$mock,
string $method,
array $calls
): void {
$mock->expects($this->exactly(count($calls)))
->method($method)
->willReturnCallback(function (...$args) use (&$calls) {
$expected = array_shift($calls);
$this->assertSame($expected, $args);
});
}


/**
* Helper function to set expectations for multiple calls to methods with different arguments
* @param MockObject $mock The mock object on which the method is expected to be called
* @param string $method The method name for which the expectations are set
* @param array $calls An array of expected argument arrays for each call
*/
private function expectMethodReturn(
$mock,
string $method,
array $calls
): void {
$mock->method($method)
->willReturnCallback(function (...$args) use (&$calls) {
[$expectedArgs, $returnValue] = array_shift($calls);

Check failure on line 79 in tests/lib/Controller/ConfigControllerTest.php

View workflow job for this annotation

GitHub Actions / builds / PHP Unit & API tests (stable32, 8.2, 8, 2, mysql)

InvalidArrayOffset

tests/lib/Controller/ConfigControllerTest.php:79:5: InvalidArrayOffset: Cannot destructure non-array of type mixed|null (see https://psalm.dev/115)

Check failure on line 79 in tests/lib/Controller/ConfigControllerTest.php

View workflow job for this annotation

GitHub Actions / builds / PHP Unit & API tests (stable32, 8.3, 8, 3, mysql)

InvalidArrayOffset

tests/lib/Controller/ConfigControllerTest.php:79:5: InvalidArrayOffset: Cannot destructure non-array of type mixed|null (see https://psalm.dev/115)

Check failure on line 79 in tests/lib/Controller/ConfigControllerTest.php

View workflow job for this annotation

GitHub Actions / builds / PHP Unit & API tests (stable31, 8.3, 8, 3, mysql)

InvalidArrayOffset

tests/lib/Controller/ConfigControllerTest.php:79:5: InvalidArrayOffset: Cannot destructure non-array of type mixed|null (see https://psalm.dev/115)
$this->assertSame($expectedArgs, $args);
return $returnValue;
});
}

/**
* @param string $codeVerifier The string that should be used as code_verifier
* @param string $clientSecret The string that should be used as openproject_client_secret
Expand All @@ -54,17 +92,25 @@
$codeVerifier, $clientSecret, $startingPage = '{ page: "files" }'
) {
$configMock = $this->getMockBuilder(IConfig::class)->getMock();
$configMock
->method('getAppValue')
->withConsecutive(
['integration_openproject', 'openproject_client_id'],
['integration_openproject', 'openproject_client_secret'],
['integration_openproject', 'openproject_instance_url'],
['integration_openproject', 'openproject_client_id'],
['integration_openproject', 'openproject_client_secret'],
)->willReturnOnConsecutiveCalls(
'clientID', $clientSecret, 'http://openproject.org', 'clientID', 'clientSecret',
);
// $configMock
// ->method('getAppValue')
// ->withConsecutive(
// ['integration_openproject', 'openproject_client_id'],
// ['integration_openproject', 'openproject_client_secret'],
// ['integration_openproject', 'openproject_instance_url'],
// ['integration_openproject', 'openproject_client_id'],
// ['integration_openproject', 'openproject_client_secret'],
// )->willReturnOnConsecutiveCalls(
// 'clientID', $clientSecret, 'http://openproject.org', 'clientID', 'clientSecret',
// );
$this->expectMethodReturn($configMock, 'getAppValue', [
[['integration_openproject', 'openproject_client_id', ''], 'clientID'],
[['integration_openproject', 'openproject_client_secret', ''], $clientSecret],
[['integration_openproject', 'openproject_instance_url', ''], 'http://openproject.org'],
[['integration_openproject', 'authorization_method', ''], OpenProjectAPIService::AUTH_METHOD_OAUTH],
[['integration_openproject', 'openproject_client_id', ''], 'clientID'],
[['integration_openproject', 'openproject_client_secret', ''], 'clientSecret'],
]);
$configMock
->method('getUserValue')
->withConsecutive(
Expand All @@ -79,6 +125,12 @@
$startingPage,
'oAuthRefreshToken',
);
// $this->expectMethodReturn($configMock, 'getUserValue', [
// [['testUser', 'integration_openproject', 'oauth_state'], 'randomString'],
// [['testUser', 'integration_openproject', 'code_verifier'], $codeVerifier],
// [['testUser', 'integration_openproject', 'oauth_journey_starting_page'], $startingPage],
// [['testUser', 'integration_openproject', 'refresh_token'], 'oAuthRefreshToken'],
// ]);
return $configMock;
}

Expand Down Expand Up @@ -166,13 +218,10 @@
str_repeat("A", 128), str_repeat("S", 50));
$configMock
->method('setUserValue')
->withConsecutive(
['testUser', 'integration_openproject', 'token', 'oAuthAccessToken'],
['testUser', 'integration_openproject', 'refresh_token', 'oAuthRefreshToken'],
['testUser', 'integration_openproject', 'user_id', 1],
['testUser', 'integration_openproject', 'user_name', 'Tripathi Himal'],
['testUser', 'integration_openproject', 'oauth_connection_result', 'success'],
->with(
'testUser', 'integration_openproject', 'oauth_connection_result', 'success'
);

$urlGeneratorMock = $this->getMockBuilder(IURLGenerator::class)
->disableOriginalConstructor()
->getMock();
Expand All @@ -185,12 +234,12 @@
->getMock();

$apiServiceMock
->method('request')
->method('initUserInfo')
->with(
'testUser',
'users/me'
'oAuthAccessToken'
)
->willReturn(['lastName' => 'Himal', 'firstName' => 'Tripathi', 'id' => 1]);
->willReturn(['user_name' => 'Tripathi Himal']);

$apiServiceMock
->method('requestOAuthAccessToken')
Expand Down Expand Up @@ -273,16 +322,11 @@
$configMock = $this->getConfigMock(
str_repeat("A", 128), str_repeat("S", 50)
);
$configMock
->expects($this->exactly(2))
->method('setUserValue')
->withConsecutive(
['testUser', 'integration_openproject', 'oauth_connection_result', 'error'],
[
'testUser', 'integration_openproject', 'oauth_connection_error_message',
'Error during OAuth exchanges'
],
);

$this->expectMethodCalls($configMock, 'setUserValue', [
['testUser', 'integration_openproject', 'oauth_connection_result', 'error', null],
['testUser', 'integration_openproject', 'oauth_connection_error_message', 'Error during OAuth exchanges', null],
]);

$constructArgs = $this->getConfigControllerConstructArgs([
'config' => $configMock,
Expand Down Expand Up @@ -382,27 +426,32 @@
$loggerMock->expects($this->never())
->method('error');
// even the secret is valid, we get an error because the token request is not mocked
$calls = [
['testUser', 'integration_openproject', 'oauth_connection_result', 'error', null],
['testUser', 'integration_openproject', 'oauth_connection_error_message', 'Error getting OAuth access token', null],
];
$configMock->expects($this->exactly(2))
->method('setUserValue')
->withConsecutive(
['testUser', 'integration_openproject', 'oauth_connection_result', 'error'],
[
'testUser', 'integration_openproject', 'oauth_connection_error_message',
'Error getting OAuth access token'
],
);
->willReturnCallback(function (...$args) use (&$calls) {
$expected = array_shift($calls);
$this->assertSame($expected, $args);
});
} else {
$loggerMock->expects($this->once())
->method('error');
$calls = [
['testUser', 'integration_openproject', 'oauth_connection_result', 'error', null],
[
'testUser', 'integration_openproject', 'oauth_connection_error_message',
'Error during OAuth exchanges', null
],
];
$configMock->expects($this->exactly(2))
->method('setUserValue')
->withConsecutive(
['testUser', 'integration_openproject', 'oauth_connection_result', 'error'],
[
'testUser', 'integration_openproject', 'oauth_connection_error_message',
'Error during OAuth exchanges'
],
);
->willReturnCallback(function (...$args) use (&$calls) {
$expected = array_shift($calls);
$this->assertSame($expected, $args);
});
}

$constructArgs = $this->getConfigControllerConstructArgs([
Expand Down Expand Up @@ -1265,20 +1314,13 @@

$configMock
->method('getAppValue')
->withConsecutive(
['integration_openproject', 'openproject_instance_url', ''],
['integration_openproject', 'authorization_method', ''],
['integration_openproject', 'openproject_client_id', ''],
['integration_openproject', 'openproject_client_secret', ''],
['integration_openproject', 'oPOAuthTokenRevokeStatus', '']
)
->willReturnOnConsecutiveCalls(
$oldAdminConfig['openproject_instance_url'],
$oldAdminConfig['authorization_method'],
$oldAdminConfig['openproject_client_id'],
$oldAdminConfig['openproject_client_secret'],
''
);
->willReturnMap([
[Application::APP_ID, 'openproject_instance_url', '', $oldAdminConfig['openproject_instance_url']],
[Application::APP_ID, 'authorization_method', '', $oldAdminConfig['authorization_method']],
[Application::APP_ID, 'openproject_client_id', '', $oldAdminConfig['openproject_client_id']],
[Application::APP_ID, 'openproject_client_secret', '', $oldAdminConfig['openproject_client_secret']],
[Application::APP_ID, 'oPOAuthTokenRevokeStatus', '', ''],
]);
$configMock
->expects($this->exactly(2))
->method('deleteAppValue')
Expand Down Expand Up @@ -1522,30 +1564,19 @@
->getMock();
$configMock
->method('getAppValue')
->withConsecutive(
['integration_openproject', 'openproject_instance_url', ''],
['integration_openproject', 'authorization_method', ''],
['integration_openproject', 'oidc_provider'],
['integration_openproject', 'targeted_audience_client_id'],
['integration_openproject', 'nc_oauth_client_id', ''],
['integration_openproject', 'oPOAuthTokenRevokeStatus', ''],
['integration_openproject', 'authorization_method', ''],
['integration_openproject', 'oidc_provider'],
['integration_openproject', 'targeted_audience_client_id'],
['integration_openproject', 'openproject_instance_url'],
)
->willReturnOnConsecutiveCalls(
$oldCreds['openproject_instance_url'],
$oldCreds['authorization_method'],
$oldCreds['oidc_provider'],
$oldCreds['targeted_audience_client_id'],
'123',
'',
OpenProjectAPIService::AUTH_METHOD_OAUTH,
$credsToUpdate['oidc_provider'],
$credsToUpdate['targeted_audience_client_id'],
$credsToUpdate['openproject_instance_url']
);
->willReturnMap([
['integration_openproject', 'openproject_instance_url', '', $oldCreds['openproject_instance_url']],
['integration_openproject', 'authorization_method', '', $oldCreds['authorization_method']],
['integration_openproject', 'oidc_provider', '', $oldCreds['oidc_provider']],
['integration_openproject', 'targeted_audience_client_id', '', $oldCreds['targeted_audience_client_id']],
['integration_openproject', 'nc_oauth_client_id', '', '123'],
['integration_openproject', 'oPOAuthTokenRevokeStatus', '', ''],
['integration_openproject', 'authorization_method', '', OpenProjectAPIService::AUTH_METHOD_OIDC],
['integration_openproject', 'oidc_provider', '', $credsToUpdate['oidc_provider']],
['integration_openproject', 'targeted_audience_client_id', '', $credsToUpdate['targeted_audience_client_id']],
['integration_openproject', 'openproject_instance_url', '', $credsToUpdate['openproject_instance_url']],

]);

$apiService = $this->getMockBuilder(OpenProjectAPIService::class)
->disableOriginalConstructor()
Expand Down
Loading
Loading