[test-only] ApiTest. Disable/enable user (#5639)

This commit is contained in:
Viktor Scharf
2023-03-06 12:07:55 +01:00
committed by GitHub
parent 1c88d445bd
commit 1e1b4379ae
9 changed files with 286 additions and 65 deletions

View File

@@ -171,6 +171,7 @@ class GraphHelper {
* @param string|null $password
* @param string|null $email
* @param string|null $displayName
* @param bool|true $accountEnabled
*
* @return ResponseInterface
* @throws GuzzleException
@@ -184,13 +185,15 @@ class GraphHelper {
?string $userName = null,
?string $password = null,
?string $email = null,
?string $displayName = null
?string $displayName = null,
?bool $accountEnabled = true
): ResponseInterface {
$payload = self::preparePatchUserPayload(
$userName,
$password,
$email,
$displayName
$displayName,
$accountEnabled
);
$url = self::getFullUrl($baseUrl, 'users/' . $userId);
return HttpRequestHelper::sendRequest(
@@ -639,6 +642,7 @@ class GraphHelper {
if (!empty($email)) {
$payload['mail'] = $email ?? $userName . '@example.com';
}
$payload['accountEnabled'] = true;
return \json_encode($payload);
}
@@ -649,6 +653,7 @@ class GraphHelper {
* @param string|null $password
* @param string|null $email
* @param string|null $displayName
* @param bool|true $accountEnabled
*
* @return string
*/
@@ -656,7 +661,8 @@ class GraphHelper {
?string $userName,
?string $password,
?string $email,
?string $displayName
?string $displayName,
?bool $accountEnabled
): string {
$payload = [];
if ($userName) {
@@ -671,6 +677,8 @@ class GraphHelper {
if ($email) {
$payload['mail'] = $email;
}
$payload['accountEnabled'] = $accountEnabled;
return \json_encode($payload);
}

View File

@@ -23,7 +23,8 @@ The expected failures in this file are from features in the owncloud/ocis repo.
- [apiGraph/createGroupCaseSensitive.feature:21](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createGroupCaseSensitive.feature#L21)
- [apiGraph/createGroupCaseSensitive.feature:22](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createGroupCaseSensitive.feature#L22)
- [apiGraph/createGroup.feature:26](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createGroup.feature#L26)
- [apiGraph/createUser.feature:28](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createUser.feature#L28)
- [apiGraph/createUser.feature:29](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createUser.feature#L29)
- [apiGraph/createUser.feature:61](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createUser.feature#L61)
### [PROPFIND on accepted shares with identical names containing brackets exit with 404](https://github.com/owncloud/ocis/issues/4421)
- [apiSpacesShares/changingFilesShare.feature:12](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/changingFilesShare.feature#L12)
@@ -92,7 +93,7 @@ The expected failures in this file are from features in the owncloud/ocis repo.
#### [A User can get information of another user with Graph API](https://github.com/owncloud/ocis/issues/5125)
- [apiGraph/getUser.feature:23](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getUser.feature#L23)
- [apiGraph/getUser.feature:92](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getUser.feature#L92)
- [apiGraph/getUser.feature:102](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getUser.feature#L102)
#### [Sharing to a group with an expiration date does not work #5442](https://github.com/owncloud/ocis/issues/5442)
- [apiSpacesShares/shareSubItemOfSpace.feature:105](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiSpacesShares/shareSubItemOfSpace.feature#L105)
@@ -103,5 +104,8 @@ The expected failures in this file are from features in the owncloud/ocis repo.
#### [Normal user can get expanded members information of a group](https://github.com/owncloud/ocis/issues/5604)
- [apiGraph/getGroup.feature:100](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getGroup.feature#L100)
#### Change editUser test where we set empty value
- [apiGraph/editUser.feature:33](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editUser.feature#L33)
- [apiGraph/editUser.feature:80](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/editUser.feature#L80)
Note: always have an empty line at the end of this file.
The bash script that processes this file requires that the last line has a newline on the end.

View File

@@ -69,14 +69,14 @@ Feature: add users to group
Scenario: adding a user to a group with % and # in its name
Given these groups have been created:
| groupname | comment |
| maintenance#123 | Hash sign |
| 50%pass | Percent sign (special escaping happens) |
| 50%25=0 | %25 literal looks like an escaped "%" |
| 50%2Eagle | %2E literal looks like an escaped "." |
| 50%2Fix | %2F literal looks like an escaped slash |
| Mgmt\Middle | Backslash |
| staff?group | Question mark |
| groupname | comment |
| maintenance#123 | Hash sign |
| 50%pass | Percent sign (special escaping happens) |
| 50%25=0 | %25 literal looks like an escaped "%" |
| 50%2Eagle | %2E literal looks like an escaped "." |
| 50%2Fix | %2F literal looks like an escaped slash |
| Mgmt\Middle | Backslash |
| staff?group | Question mark |
When the administrator adds the following users to the following groups using the Graph API
| username | groupname |
| Alice | maintenance#123 |
@@ -149,3 +149,17 @@ Feature: add users to group
Scenario: admin tries to add user to a group without sending the group
When the administrator tries to add user "Alice" to group "" using the Graph API
Then the HTTP status code should be "404"
Scenario: adding a disabled user to a group
Given these groups have been created:
| groupname | comment |
| sales | normal group |
And the user "Admin" has disabled user "Alice" using the Graph API
When the administrator adds the following users to the following groups using the Graph API
| username | groupname |
| Alice | sales |
Then the HTTP status code of responses on all endpoints should be "204"
And the following users should be listed in the following groups
| username | groupname |
| Alice | sales |

View File

@@ -12,43 +12,74 @@ Feature: create user
Scenario Outline: the admin creates a user
Given the administrator has given "Alice" the role "Admin" using the settings api
When the user "Alice" creates a new user using GraphAPI with the following settings:
| userName | <userName> |
| displayName | <displayName> |
| email | <email> |
| password | <password> |
| userName | <userName> |
| displayName | <displayName> |
| email | <email> |
| password | <password> |
| accountEnabled | <enable> |
Then the HTTP status code should be "<code>"
And user "<userName>" <shouldOrNot> exist
Examples:
| userName | displayName | email | password | code | shouldOrNot |
| SameDisplayName | Alice Hansen | new@example.org | containsCharacters(*:!;_+-&) | 200 | should |
| withoutPassSameEmail | without pass | alice@example.org | | 200 | should |
| name | pass with space | example@example.org | my pass | 200 | should |
| nameWithCharacters(*:!;_+-&) | user | new@example.org | 123 | 400 | should not |
| withoutEmail | without email | | 123 | 200 | should |
| Alice | same userName | new@example.org | 123 | 400 | should |
| name with space | name with space | example@example.org | 123 | 400 | should not |
| userName | displayName | email | password | code | enable | shouldOrNot |
| SameDisplayName | Alice Hansen | new@example.org | containsCharacters(*:!;_+-&) | 200 | true | should |
| withoutPassSameEmail | without pass | alice@example.org | | 200 | true | should |
| name | pass with space | example@example.org | my pass | 200 | true | should |
| nameWithCharacters(*:!;_+-&) | user | new@example.org | 123 | 400 | true | should not |
| withoutEmail | without email | | 123 | 200 | true | should |
| Alice | same userName | new@example.org | 123 | 400 | true | should |
| name with space | name with space | example@example.org | 123 | 400 | true | should not |
| createDisabledUser | disabled user | example@example.org | 123 | 200 | false | should |
Scenario: a user cannot be created with empty name
Given the administrator has given "Alice" the role "Admin" using the settings api
When the user "Alice" creates a new user using GraphAPI with the following settings:
| userName | |
| displayName | emptyName |
| email | @example.org |
| password | 123 |
| userName | |
| displayName | emptyName |
| email | @example.org |
| password | 123 |
| accountEnabled | true |
Then the HTTP status code should be "400"
Scenario Outline: a user without admin right cannot create a user
Given the administrator has given "Alice" the role "<role>" using the settings api
When the user "Alice" creates a new user using GraphAPI with the following settings:
| userName | user |
| displayName | user |
| email | @example.org |
| password | 123 |
| userName | user |
| displayName | user |
| email | @example.org |
| password | 123 |
| accountEnabled | true |
Then the HTTP status code should be "401"
And user "user" should not exist
Examples:
| role |
| Space Admin |
| User |
Scenario: a user cannot be created with the name of the disabled user
Given user "Brian" has been created with default attributes and without skeleton files
And the administrator has given "Alice" the role "Admin" using the settings api
And the user "Alice" has disabled user "Brian" using the Graph API
When the user "Alice" creates a new user using GraphAPI with the following settings:
| userName | Brian |
| displayName | This is another Brian |
| email | brian@example.com |
| password | 123 |
| accountEnabled | true |
Then the HTTP status code should be "400"
Scenario: a user can be created with the name of the deleted user
Given user "Brian" has been created with default attributes and without skeleton files
And the administrator has given "Alice" the role "Admin" using the settings api
And the user "Alice" has deleted a user "Brian" using the Graph API
When the user "Alice" creates a new user using GraphAPI with the following settings:
| userName | Brian |
| displayName | This is another Brian |
| email | brian@example.com |
| password | 123 |
| accountEnabled | true |
Then the HTTP status code should be "200"
And user "Brian" should exist

View File

@@ -71,3 +71,13 @@ Feature: delete user
| role |
| Space Admin |
| User |
Scenario: the admin user deletes a disabled user
Given the administrator has given "Alice" the role "Admin" using the settings api
And user "Brian" has been created with default attributes and without skeleton files
And the user "Alice" has disabled user "Brian" using the Graph API
When the user "Alice" deletes a user "Brian" using the Graph API
Then the HTTP status code should be "204"
And user "Brian" should not exist

View File

@@ -139,3 +139,59 @@ Feature: edit user
| role |
| Space Admin |
| User |
Scenario: the admin user disables another user
When the user "Alice" disables user "Brian" using the Graph API
Then the HTTP status code should be "200"
When user "Alice" gets information of user "Brian" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.com | Brian | false |
Scenario Outline: a normal user should not be able to disable another user
Given user "Carol" has been created with default attributes and without skeleton files
And the administrator has given "Brian" the role "<role>" using the settings api
When the user "Brian" tries to disable user "Carol" using the Graph API
Then the HTTP status code should be "401"
When user "Alice" gets information of user "Carol" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Carol King | %uuid_v4% | carol@example.org | Carol | true |
Examples:
| role |
| Space Admin |
| User |
| Guest |
Scenario: the admin user enables disabled user
Given the user "Alice" has disabled user "Brian" using the Graph API
When the user "Alice" enables user "Brian" using the Graph API
Then the HTTP status code should be "200"
When user "Alice" gets information of user "Brian" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.com | Brian | true |
Scenario Outline: a normal user should not be able to enable another user
Given user "Carol" has been created with default attributes and without skeleton files
And the user "Alice" has disabled user "Carol" using the Graph API
And the administrator has given "Brian" the role "<role>" using the settings api
When the user "Brian" tries to enable user "Carol" using the Graph API
Then the HTTP status code should be "401"
When user "Alice" gets information of user "Carol" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Carol King | %uuid_v4% | carol@example.org | Carol | false |
Examples:
| role |
| Space Admin |
| User |
| Guest |

View File

@@ -16,8 +16,8 @@ Feature: get users
When user "Alice" gets information of user "Brian" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
Scenario: non-admin user tries to get the information of a user
@@ -30,9 +30,19 @@ Feature: get users
When user "Alice" gets all users using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice | true |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
Scenario: admin user gets all users include disabled users
Given the user "Alice" has disabled user "Brian" using the Graph API
When user "Alice" gets all users using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice | true |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | false |
Scenario: non-admin user tries to get all users
@@ -45,8 +55,8 @@ Feature: get users
When the user "Alice" gets user "Brian" along with his drive information using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
And the user retrieve API response should contain the following drive information:
| driveType | personal |
| driveAlias | personal/brian |
@@ -63,8 +73,8 @@ Feature: get users
When the user "Brian" gets his drive information using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
And the user retrieve API response should contain the following drive information:
| driveType | personal |
| driveAlias | personal/brian |
@@ -85,8 +95,8 @@ Feature: get users
When the user "Alice" gets user "Brian" along with his group information using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName | memberOf |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | tea-lover, coffee-lover |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled | memberOf |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true | tea-lover, coffee-lover |
Scenario: non-admin user tries to get the group information of a user
@@ -100,6 +110,7 @@ Feature: get users
Scenario: admin user gets all users of certain groups
Given user "Carol" has been created with default attributes and without skeleton files
And the user "Alice" has disabled user "Carol" using the Graph API
And group "tea-lover" has been created
And group "coffee-lover" has been created
And user "Alice" has been added to group "tea-lover"
@@ -108,22 +119,21 @@ Feature: get users
When the user "Alice" gets all users of the group "tea-lover" using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice | true |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
But the API response should not contain following user with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Carol King | %uuid_v4% | carol@example.org | Carol |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Carol King | %uuid_v4% | carol@example.org | Carol | false |
When the user "Alice" gets all users of two groups "tea-lover,coffee-lover" using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following user with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
But the API response should not contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice |
| Carol King | %uuid_v4% | carol@example.org | Carol |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice | true |
| Carol King | %uuid_v4% | carol@example.org | Carol | true |
Scenario Outline: non admin user tries to get users of certain groups
Given the administrator has given "Brian" the role "<role>" using the settings api
@@ -148,20 +158,20 @@ Feature: get users
When the user "Alice" gets all users with role "Space Admin" using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| Carol King | %uuid_v4% | carol@example.org | Carol |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
| Carol King | %uuid_v4% | carol@example.org | Carol | true |
But the API response should not contain following user with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice |
When the user "Alice" gets all users with role "Space Admin" and member of the group "tea-lover" using the Graph API
Then the HTTP status code should be "200"
And the API response should contain following users with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian | true |
But the API response should not contain following user with the information:
| displayName | id | mail | onPremisesSamAccountName |
| Carol King | %uuid_v4% | carol@example.org | Carol |
| displayName | id | mail | onPremisesSamAccountName | accountEnabled |
| Carol King | %uuid_v4% | carol@example.org | Carol | true |
Scenario Outline: non-admin user tries to get users with a certain role

View File

@@ -166,3 +166,20 @@ Feature: remove a user from a group
Then the HTTP status code should be "401"
And the last response should be an unauthorized response
And user "Brian" should belong to group "grp1"
Scenario: admin removes a disabled user from a group
Given these groups have been created:
| groupname | comment |
| brand-new-group | nothing special here |
And the following users have been added to the following groups
| username | groupname |
| Alice | brand-new-group |
And the user "Admin" has disabled user "Alice" using the Graph API
When the administrator removes the following users from the following groups using the Graph API
| username | groupname |
| Alice | brand-new-group |
Then the HTTP status code of responses on all endpoints should be "204"
And the following users should not belong to the following groups
| username | groupname |
| Alice | brand-new-group |

View File

@@ -128,6 +128,53 @@ class GraphContext implements Context {
$this->featureContext->setResponse($response);
}
/**
* @When /^the user "([^"]*)" disables user "([^"]*)" using the Graph API$/
* @When /^the user "([^"]*)" tries to disable user "([^"]*)" using the Graph API$/
*
* @param string $byUser
* @param string $user
*
* @return void
* @throws GuzzleException
* @throws Exception
*/
public function theUserDisablesUserToUsingTheGraphApi(string $byUser, string $user): void {
$response = $this->editUserUsingTheGraphApi($byUser, $user, null, null, null, null, false);
$this->featureContext->setResponse($response);
}
/**
* @Given /^the user "([^"]*)" has disabled user "([^"]*)" using the Graph API$/
*
* @param string $byUser
* @param string $user
*
* @return void
* @throws GuzzleException
* @throws Exception
*/
public function theUserHasDisabledUserToUsingTheGraphApi(string $byUser, string $user): void {
$this->theUserDisablesUserToUsingTheGraphApi($byUser, $user);
$this->featureContext->thenTheHTTPStatusCodeShouldBe(200);
}
/**
* @When /^the user "([^"]*)" enables user "([^"]*)" using the Graph API$/
* @When /^the user "([^"]*)" tries to enable user "([^"]*)" using the Graph API$/
*
* @param string $byUser
* @param string $user
*
* @return void
* @throws GuzzleException
* @throws Exception
*/
public function theUserEnablesUserToUsingTheGraphApi(string $byUser, string $user): void {
$response = $this->editUserUsingTheGraphApi($byUser, $user, null, null, null, null, true);
$this->featureContext->setResponse($response);
}
/**
* @Then /^the user "([^"]*)" should have information with these key and value pairs:$/
*
@@ -162,11 +209,12 @@ class GraphContext implements Context {
* @param string|null $password
* @param string|null $email
* @param string|null $displayName
* @param bool|true $accountEnabled
*
* @return void
* @throws GuzzleException
*/
public function editUserUsingTheGraphApi(string $byUser, string $user, string $userName = null, string $password = null, string $email = null, string $displayName = null): ResponseInterface {
public function editUserUsingTheGraphApi(string $byUser, string $user, string $userName = null, string $password = null, string $email = null, string $displayName = null, bool $accountEnabled = true): ResponseInterface {
$user = $this->featureContext->getActualUsername($user);
$userId = $this->featureContext->getAttributeOfCreatedUser($user, 'id');
$userId = $userId ?? $user;
@@ -179,7 +227,8 @@ class GraphContext implements Context {
$userName,
$password,
$email,
$displayName
$displayName,
$accountEnabled
);
}
@@ -369,6 +418,21 @@ class GraphContext implements Context {
$this->adminDeletesUserUsingTheGraphApi($user, $byUser);
}
/**
* @Given /^the user "([^"]*)" has deleted a user "([^"]*)" using the Graph API$/
*
* @param string $byUser
* @param string $user
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function theUserHasDeletesAUserUsingTheGraphAPI(string $byUser, string $user): void {
$this->adminDeletesUserUsingTheGraphApi($user, $byUser);
$this->featureContext->thenTheHTTPStatusCodeShouldBe(204);
}
/**
* @param string $user
* @param string $group
@@ -1303,12 +1367,19 @@ class GraphContext implements Context {
}
Assert::assertTrue(GraphHelper::isUUIDv4($actualValue['id']), __METHOD__ . ' Expected user_id to have UUIDv4 pattern but found: ' . $actualValue['id']);
break;
case "accountEnabled":
if ($expectedValue[$keyName] === 'true') {
Assert::assertTrue($actualValue[$keyName], ' Expected ' . $keyName . ' is not true ');
} else {
Assert::assertFalse($actualValue[$keyName], ' Expected ' . $keyName . ' is not false ');
}
break;
default:
Assert::assertEquals(
$expectedValue[$keyName],
$actualValue[$keyName],
__METHOD__ .
' Expected ' . $keyName . 'to have value' . $expectedValue[$keyName]
' Expected ' . $keyName . ' to have value ' . $expectedValue[$keyName]
. ' but got ' . $actualValue[$keyName]
);
break;