Skip to content

Commit

Permalink
Added Appgroup functional test case for Team Invitations (#963)
Browse files Browse the repository at this point in the history
  • Loading branch information
shishir-intelli authored Nov 20, 2023
1 parent 4b31084 commit 56e8d62
Show file tree
Hide file tree
Showing 7 changed files with 408 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/**
* Copyright 2023 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace Drupal\Tests\apigee_edge_teams\Functional\ApigeeX;

use Drupal\apigee_edge\OauthTokenFileStorage;
use Drupal\Tests\apigee_edge\Functional\ApigeeX\ApigeeEdgeFunctionalTestBase;

/**
* Base class for Apigee Edge Teams functional tests.
*/
abstract class ApigeeEdgeTeamsFunctionalTestBase extends ApigeeEdgeFunctionalTestBase {

/**
* {@inheritdoc}
*/
protected static $modules = [
'apigee_edge_teams',
];

/**
* Stores pre-configured token storage service for testing.
*/
protected function storeToken() {
// Storing the token for Appigeex Hybrid Org.
$this->testTokenData = [
'access_token' => mb_strtolower($this->randomMachineName(32)),
'token_type' => 'bearer',
'expires_in' => 300,
'refresh_token' => mb_strtolower($this->randomMachineName(32)),
'scope' => 'create',
];
$storage = $this->tokenStorage();

// Save the token.
$storage->saveToken($this->testTokenData);
}

/**
* Returns a pre-configured token storage service for testing.
*
* @param bool $rebuild
* Enforces rebuild of the container and with the the token storage
* service.
*
* @return \Drupal\apigee_edge\OauthTokenFileStorage
* The configured and initialized OAuth file token storage service.
*
* @throws \Exception
*/
private function tokenStorage(bool $rebuild = FALSE): OauthTokenFileStorage {
$config = $this->config('apigee_edge.auth');
$config->set('oauth_token_storage_location', OauthTokenFileStorage::DEFAULT_DIRECTORY)->save();
if ($rebuild) {
$this->container->get('kernel')->rebuildContainer();
}
return $this->container->get('apigee_edge.authentication.oauth_token_storage');
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
<?php

/**
* Copyright 2023 Google Inc.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

namespace Drupal\Tests\apigee_edge_teams\Functional\ApigeeX;

use Drupal\apigee_edge\Entity\Developer;
use Drupal\apigee_edge_teams\Entity\TeamRoleInterface;
use Drupal\Core\Url;
use Drupal\Tests\apigee_mock_api_client\Traits\ApigeeMockApiClientHelperTrait;
use Drupal\views\Views;

/**
* Team invitation test.
*
* @group apigee_edge
* @group apigee_edge_teams
*/
class TeamInvitationsTest extends ApigeeEdgeTeamsFunctionalTestBase {

/**
* {@inheritdoc}
*/
protected static $mock_api_client_ready = TRUE;

/**
* {@inheritdoc}
*/
protected static $modules = [
'user',
'options',
'datetime',
'views',
'apigee_edge_teams',
'apigee_mock_api_client',
];

/**
* Admin user.
*
* @var \Drupal\user\UserInterface
*/
protected $accountAdmin;

/**
* Authenticated user.
*
* @var \Drupal\user\UserInterface
*/
protected $accountUser;

/**
* Team entity to test.
*
* @var \Drupal\apigee_edge_teams\Entity\TeamInterface
*/
protected $teamA;

/**
* Team entity to test.
*
* @var \Drupal\apigee_edge_teams\Entity\TeamInterface
*/
protected $teamB;

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();

$this->storeToken();
$this->addApigeexOrganizationMatchedResponse();
$this->teamA = $this->createApigeexTeam();
$this->teamB = $this->createApigeexTeam();

$this->accountAdmin = $this->createAccount(['administer team']);
$this->accountUser = $this->createAccount([
'accept own team invitation',
]);

if (!$this->integration_enabled) {
$this->queueDeveloperResponse($this->accountAdmin);
Developer::load($this->accountAdmin->getEmail());
$this->queueDeveloperResponse($this->accountUser);
Developer::load($this->accountUser->getEmail());
}
}

/**
* {@inheritdoc}
*/
protected function tearDown(): void {
if (!$this->integration_enabled) {
return;
}
else {
$teams = [
$this->teamA,
$this->teamB,
];
foreach ($teams as $team) {
if ($team !== NULL) {
try {
$team->delete();
}
catch (\Exception $exception) {
$this->logException($exception);
}
}
}

$accounts = [
$this->accountAdmin,
$this->accountUser,
];
foreach ($accounts as $account) {
if ($account !== NULL) {
try {
$account->delete();
}
catch (\Exception $exception) {
$this->logException($exception);
}
}
}
}

parent::tearDown();
}

/**
* Tests that an email can be invited to one or more teams.
*/
public function testMultipleInvitations() {
$this->drupalLogin($this->accountAdmin);

$teams = [
$this->teamA,
$this->teamB,
];
$appgroups = [
$this->teamA->decorated(),
$this->teamB->decorated(),
];

$inCache = FALSE;
foreach ($teams as $team) {
if (!$inCache) {
$this->queueAppGroupResponse($team->decorated());
}
$this->drupalGet(Url::fromRoute('entity.team.add_members', [
'team' => $team->id(),
]));

$this->assertSession()->pageTextContains('Invite members');

$this->queueAppGroupsResponse($appgroups);
$this->queueAppGroupsResponse($appgroups);
$this->queueDevsInCompanyResponse([]);
$this->submitForm([
'developers' => $this->accountUser->getEmail(),
], 'Invite members');

$successMessage = t('The following developer has been invited to the @team @team_label: @developer.', [
'@developer' => $this->accountUser->getEmail(),
'@team' => $team->label(),
'@team_label' => mb_strtolower($team->getEntityType()->getSingularLabel()),
]);

$this->assertSession()->pageTextContains($successMessage);
$inCache = TRUE;
}
}

/**
* Tests that a user can see their list of invitations.
*/
public function testInvitationsList() {
// Ensure "team_invitations" views page is installed.
$this->assertNotNull(Views::getView('team_invitations'));

/** @var \Drupal\apigee_edge_teams\Entity\Storage\TeamInvitationStorageInterface $teamInvitationStorage */
$teamInvitationStorage = $this->entityTypeManager->getStorage('team_invitation');
$selected_roles = [TeamRoleInterface::TEAM_MEMBER_ROLE => TeamRoleInterface::TEAM_MEMBER_ROLE];
$teams = [
$this->teamA,
$this->teamB,
];
$appgroups = [
$this->teamA->decorated(),
$this->teamB->decorated(),
];

// Invite user to both teams.
foreach ($teams as $team) {
$this->queueAppGroupResponse($team->decorated());
$teamInvitationStorage->create([
'team' => ['target_id' => $team->id()],
'team_roles' => array_values(array_map(function (string $role) {
return ['target_id' => $role];
}, $selected_roles)),
'recipient' => $this->accountUser->getEmail(),
])->save();
}

// Check that user can see both invitations.
$this->drupalLogin($this->accountUser);
$invitationsUrl = Url::fromRoute('view.team_invitations.user', [
'user' => $this->accountUser->id(),
]);

$this->queueAppGroupsResponse($appgroups);
$this->queueDevsInCompanyResponse([]);
$this->drupalGet($invitationsUrl);
foreach ($teams as $team) {
$this->assertSession()->pageTextContains('Invitation to join ' . $team->label());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
*/
#}
{
"apps": [],
"name": "{{ appgroup.name|default('foo') }}",
"channelUri": "http:\/\/localhost:8080\/test\/web\/teams\/drupalteam",
"channelId": "devportal",
"displayName": "{{ appgroup.displayName }}",
"organization": "{{ org_name }}",
"status": "active",
"attributes": [],
"attributes": [
{
"name": "__apigee_reserved__developer_details",
"value": "[{\"developer\":\"[email protected]\",\"roles\":[\"admin\"]}]"
}
],
"createdAt": 1506959878351,
"createdBy" : "[email protected]",
"lastModifiedAt": 1506959878351,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{#
/**
* @file
* AppGroups
*
* Usage:
* @code {% include 'appgroups.json.twig' %} @endcode
*
* Variables:
* - appgroups: an array of appgroup objects.
*/
#}
{
"appGroups" : [
{% for appgroup in appgroups %}
{% include 'appgroup.json.twig' with {'appgroup': appgroup} %}{{ loop.last ? '' : ',' }}
{% endfor %}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,21 @@ protected function queueCompaniesResponse(array $companies, $response_code = NUL
$this->stack->queueMockResponse(['companies' => $context]);
}

/**
* Queues up a mock appgroups response.
*
* @param array $appgroups
* An array of appgroup objects.
* @param string|null $response_code
* Add a response code to override the default.
*/
protected function queueAppGroupsResponse(array $appgroups, $response_code = NULL) {
$context = empty($response_code) ? [] : ['status_code' => $response_code];
$context['appgroups'] = $appgroups;

$this->stack->queueMockResponse(['appgroups' => $context]);
}

/**
* Queues up a mock developers in a company response.
*
Expand Down
Loading

0 comments on commit 56e8d62

Please sign in to comment.