View source
<?php
namespace Drupal\Tests\apigee_edge\Functional;
use Apigee\Edge\Api\Management\Controller\DeveloperController;
use Drupal\apigee_edge\Entity\Developer;
use Drupal\apigee_edge\Plugin\ApigeeFieldStorageFormat\CSV;
use Drupal\apigee_edge\Plugin\ApigeeFieldStorageFormat\JSON;
use Drupal\Core\Url;
use Drupal\Tests\field_ui\Traits\FieldUiTestTrait;
use Drupal\user\Entity\User;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
class DeveloperSyncTest extends ApigeeEdgeFunctionalTestBase {
use FieldUiTestTrait;
const DEVELOPER_TO_CREATE_PER_TYPE = 1;
protected static $modules = [
'link',
'block',
'field_ui',
];
protected $prefix;
protected $filter;
protected $edgeDevelopers = [];
protected $drupalUsers = [];
protected $modifiedEdgeDevelopers = [];
protected $modifiedDrupalUsers = [];
protected $inactiveDeveloper;
protected $fields = [];
protected $fieldNamePrefix;
protected $formatManager;
protected function setUp() {
parent::setUp();
$this
->drupalPlaceBlock('system_breadcrumb_block');
$this->fieldNamePrefix = $this
->config('field_ui.settings')
->get('field_prefix');
$this->formatManager = $this->container
->get('plugin.manager.apigee_field_storage_format');
$this->prefix = $this
->randomMachineName();
$escaped_prefix = preg_quote($this->prefix);
$this->filter = "/^{$escaped_prefix}\\.[a-zA-Z0-9]*@example\\.com\$/";
$this->container
->get('config.factory')
->getEditable('apigee_edge.sync')
->set('filter', $this->filter)
->save();
$this
->drupalLogin($this->rootUser);
$this
->setUpUserFields();
for ($i = 0; $i < self::DEVELOPER_TO_CREATE_PER_TYPE; $i++) {
$mail = "{$this->prefix}.{$this->randomMachineName()}@example.com";
$this->edgeDevelopers[$mail] = Developer::create([
'email' => $mail,
'userName' => $this
->randomMachineName(),
'firstName' => $this
->randomMachineName(64),
'lastName' => $this
->randomMachineName(64),
]);
foreach ($this->fields as $field_type => $data) {
$formatter = $this->formatManager
->lookupPluginForFieldType($field_type);
$this->edgeDevelopers[$mail]
->setAttribute($data['name'], $formatter
->encode($data['data']));
}
$this->edgeDevelopers[$mail]
->setAttribute('invalid_email', 'invalid_email_address');
$this->edgeDevelopers[$mail]
->save();
}
$this
->disableUserPresave();
for ($i = 0; $i < self::DEVELOPER_TO_CREATE_PER_TYPE; $i++) {
$user = $this
->createAccount([], TRUE, $this->prefix);
foreach ($this->fields as $field_type => $data) {
$user
->set($this->fieldNamePrefix . $data['name'], $data['data']);
}
$user
->save();
$this->drupalUsers[$user
->getEmail()] = $user;
}
$this
->enableUserPresave();
for ($i = 0; $i < self::DEVELOPER_TO_CREATE_PER_TYPE; $i++) {
$user = $this
->createAccount([], TRUE, $this->prefix);
foreach ($this->fields as $field_type => $data) {
$user
->set($this->fieldNamePrefix . $data['name'], $data['data']);
}
$user
->set($this->fieldNamePrefix . 'invalid_email', 'valid.email@example.com');
$user
->set($this->fieldNamePrefix . 'one_track_field', 'user');
$user
->setChangedTime($this->container
->get('datetime.time')
->getCurrentTime() - 100);
$user
->save();
$this->modifiedEdgeDevelopers[$user
->getEmail()] = Developer::load($user
->getEmail());
foreach ($this->fields as $field_type => $data) {
$formatter = $this->formatManager
->lookupPluginForFieldType($field_type);
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->setAttribute($data['name'], $formatter
->encode($data['data_changed']));
}
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->setFirstName($this->randomGenerator
->word(8));
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->setLastName($this->randomGenerator
->word(8));
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->setAttribute('one_track_field', 'developer');
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->setAttribute('invalid_email', 'invalid_email_address');
$this->modifiedEdgeDevelopers[$user
->getEmail()]
->save();
}
for ($i = 0; $i < self::DEVELOPER_TO_CREATE_PER_TYPE; $i++) {
$user = $this
->createAccount([], TRUE, $this->prefix);
foreach ($this->fields as $field_type => $data) {
$user
->set($this->fieldNamePrefix . $data['name'], $data['data']);
}
$user
->save();
$this->modifiedDrupalUsers[$user
->getEmail()] = $user;
$developer = Developer::load($user
->getEmail());
$developer
->setAttribute('one_track_field', 'developer');
$developer
->save();
$this
->disableUserPresave();
foreach ($this->fields as $field_type => $data) {
$this->modifiedDrupalUsers[$user
->getEmail()]
->set($this->fieldNamePrefix . $data['name'], $data['data_changed']);
}
$this->modifiedDrupalUsers[$user
->getEmail()]
->set('first_name', $this->randomGenerator
->word(8));
$this->modifiedDrupalUsers[$user
->getEmail()]
->set('last_name', $this->randomGenerator
->word(8));
$this->modifiedDrupalUsers[$user
->getEmail()]
->set('name', $this->randomGenerator
->word(8));
$this->modifiedDrupalUsers[$user
->getEmail()]
->set($this->fieldNamePrefix . 'one_track_field', 'user');
$this->modifiedDrupalUsers[$user
->getEmail()]
->setChangedTime($this->container
->get('datetime.time')
->getCurrentTime() + 100);
$this->modifiedDrupalUsers[$user
->getEmail()]
->save();
$this
->enableUserPresave();
}
Developer::create([
'email' => "{$this->prefix}.reserved@example.com",
'userName' => reset($this->drupalUsers)
->getAccountName(),
'firstName' => $this
->randomMachineName(),
'lastName' => $this
->randomMachineName(),
])
->save();
$active_user = $this
->createAccount([], TRUE, $this->prefix);
$dc = new DeveloperController($this->container
->get('apigee_edge.sdk_connector')
->getOrganization(), $this->container
->get('apigee_edge.sdk_connector')
->getClient());
$dc
->setStatus($active_user
->getEmail(), Developer::STATUS_INACTIVE);
$this->inactiveDeveloper = Developer::load($active_user
->getEmail());
$this
->assertEquals($this->inactiveDeveloper
->getStatus(), Developer::STATUS_INACTIVE);
}
protected function setUpUserFields() {
$text = $this
->getRandomGenerator()
->sentences(5);
$link = [
[
'title' => 'Example',
'options' => [],
'uri' => 'http://example.com',
],
];
$link_changed = [
[
'title' => 'Example_Changed',
'options' => [],
'uri' => 'http://example.com/changed',
],
];
$this->fields = [
'boolean' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => 1,
],
],
'data_changed' => [
[
'value' => 0,
],
],
],
'email' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => 'test@example.com',
],
],
'data_changed' => [
[
'value' => 'test.changed@example.com',
],
],
],
'timestamp' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => 1531212177,
],
],
'data_changed' => [
[
'value' => 1531000000,
],
],
],
'integer' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => 4,
],
[
'value' => 9,
],
],
'data_changed' => [
[
'value' => 2,
],
[
'value' => 8,
],
[
'value' => 1,
],
],
],
'list_integer' => [
'name' => strtolower($this
->randomMachineName()),
'settings' => [
'settings[allowed_values]' => implode(PHP_EOL, [
1,
2,
3,
]),
],
'data' => [
[
'value' => 2,
],
[
'value' => 3,
],
],
'data_changed' => [
[
'value' => 1,
],
[
'value' => 3,
],
],
],
'list_string' => [
'name' => strtolower($this
->randomMachineName()),
'settings' => [
'settings[allowed_values]' => implode(PHP_EOL, [
'qwer',
'asdf',
'zxcv',
]),
],
'data' => [
[
'value' => 'qwer',
],
[
'value' => 'asdf',
],
[
'value' => 'zxcv',
],
],
'data_changed' => [
[
'value' => 'qwer',
],
[
'value' => 'asdf',
],
],
],
'string' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => $text,
],
],
'data_changed' => [
[
'value' => strrev($text),
],
],
],
'string_long' => [
'name' => strtolower($this
->randomMachineName()),
'data' => [
[
'value' => $text,
],
],
'data_changed' => [
[
'value' => strrev($text),
],
],
],
'link' => [
'name' => strtolower($this
->randomMachineName()),
'data' => $link,
'data_changed' => $link_changed,
],
];
foreach ($this->fields as $field_type => $data) {
$this
->fieldUIAddNewField(Url::fromRoute('entity.user.admin_form')
->toString(), $data['name'], mb_strtoupper($data['name']), $field_type, ($data['settings'] ?? []) + [
'cardinality' => -1,
], []);
}
$this
->fieldUIAddNewField(Url::fromRoute('entity.user.admin_form')
->toString(), 'one_track_field', strtoupper('one_track_field'), 'string', [
'cardinality' => -1,
], []);
$this
->fieldUIAddNewField(Url::fromRoute('entity.user.admin_form')
->toString(), 'invalid_email', strtoupper('invalid_email'), 'email', [
'cardinality' => -1,
], []);
drupal_flush_all_caches();
$this
->drupalGet(Url::fromRoute('apigee_edge.settings.developer.attributes'));
$full_field_names = [];
foreach ($this->fields as $field_type => $data) {
$full_field_name = "{$this->fieldNamePrefix}{$data['name']}";
$this
->getSession()
->getPage()
->checkField("attributes[{$full_field_name}]");
$full_field_names[] = $full_field_name;
}
$this
->getSession()
->getPage()
->checkField("attributes[{$this->fieldNamePrefix}invalid_email]");
$full_field_names[] = "{$this->fieldNamePrefix}invalid_email";
$this
->getSession()
->getPage()
->pressButton('Save configuration');
$this
->assertSession()
->pageTextContains('The configuration options have been saved.');
$user_fields_to_sync = $this
->config('apigee_edge.sync')
->get('user_fields_to_sync');
$this
->assertEquals(asort($user_fields_to_sync), asort($full_field_names));
}
protected function tearDown() {
$developers_to_delete = array_merge($this->edgeDevelopers, $this->drupalUsers, $this->modifiedEdgeDevelopers, $this->modifiedDrupalUsers);
foreach ($developers_to_delete as $email => $entity) {
try {
if (($developer = Developer::load($email)) !== NULL) {
$developer
->delete();
}
} catch (\Exception $exception) {
$this
->logException($exception);
}
}
try {
if (($developer = Developer::load("{$this->prefix}.reserved@example.com")) !== NULL) {
$developer
->delete();
}
} catch (\Exception $exception) {
$this
->logException($exception);
}
try {
if ($this->inactiveDeveloper !== NULL) {
$this->inactiveDeveloper
->delete();
}
} catch (\Exception $exception) {
$this
->logException($exception);
}
parent::tearDown();
}
protected function verify() {
$developers_to_verify = array_merge($this->edgeDevelopers, $this->drupalUsers, $this->modifiedEdgeDevelopers, $this->modifiedDrupalUsers);
foreach ($developers_to_verify as $email => $entity) {
$user = user_load_by_mail($email);
$developer = Developer::load($email);
$this
->assertNotEmpty($user, 'User found: ' . $email);
$this
->assertNotEmpty($developer, 'Developer found: ' . $email);
$this
->assertEquals($developer
->getUserName(), $user
->getAccountName());
$this
->assertEquals($developer
->getFirstName(), $user
->get('first_name')->value);
$this
->assertEquals($developer
->getLastName(), $user
->get('last_name')->value);
if (array_key_exists($email, $this->modifiedDrupalUsers) || array_key_exists($email, $this->modifiedEdgeDevelopers)) {
$this
->assertEquals($developer
->getAttributeValue('one_track_field'), 'developer');
$this
->assertEquals($user
->get($this->fieldNamePrefix . 'one_track_field')->value, 'user');
foreach ($this->fields as $field_type => $data) {
$formatter = $this->formatManager
->lookupPluginForFieldType($field_type);
if ($formatter instanceof JSON) {
$this
->assertJsonStringEqualsJsonString($developer
->getAttributeValue($data['name']), $formatter
->encode($user
->get($this->fieldNamePrefix . $data['name'])
->getValue()));
$this
->assertJsonStringEqualsJsonString($developer
->getAttributeValue($data['name']), $formatter
->encode($data['data_changed']));
}
elseif ($formatter instanceof CSV) {
$this
->assertEquals($developer
->getAttributeValue($data['name']), $formatter
->encode($user
->get($this->fieldNamePrefix . $data['name'])
->getValue()));
$this
->assertEquals($developer
->getAttributeValue($data['name']), $formatter
->encode($data['data_changed']));
}
}
}
else {
foreach ($this->fields as $field_type => $data) {
$formatter = $this->formatManager
->lookupPluginForFieldType($field_type);
if ($formatter instanceof JSON) {
$this
->assertJsonStringEqualsJsonString($developer
->getAttributeValue($data['name']), $formatter
->encode($user
->get($this->fieldNamePrefix . $data['name'])
->getValue()));
$this
->assertJsonStringEqualsJsonString($developer
->getAttributeValue($data['name']), $formatter
->encode($data['data']));
}
elseif ($formatter instanceof CSV) {
$this
->assertEquals($developer
->getAttributeValue($data['name']), $formatter
->encode($user
->get($this->fieldNamePrefix . $data['name'])
->getValue()));
$this
->assertEquals($developer
->getAttributeValue($data['name']), $formatter
->encode($data['data']));
}
}
}
if ($developer
->hasAttribute('invalid_email')) {
if (array_key_exists($email, $this->edgeDevelopers)) {
$this
->assertNull($user
->get("{$this->fieldNamePrefix}invalid_email")->value);
}
elseif (array_key_exists($email, $this->modifiedEdgeDevelopers)) {
$this
->assertEquals($user
->get("{$this->fieldNamePrefix}invalid_email")->value, 'valid.email@example.com');
}
}
}
$this
->assertFalse(user_load_by_mail("{$this->prefix}.reserved@example.com"));
$active_user = user_load_by_mail($this->inactiveDeveloper
->getEmail());
$this
->assertTrue($active_user
->isActive());
$this
->assertEquals(count(User::loadMultiple()), count($developers_to_verify) + 3);
}
public function testDeveloperSync() {
$this
->drupalGet(Url::fromRoute('apigee_edge.settings.developer.sync'));
$this
->clickLinkProperly('Run developer sync');
$this
->assertSession()
->pageTextContains('Apigee Edge developers are in sync with Drupal users.');
\Drupal::service('entity_type.manager')
->getStorage('user')
->resetCache();
$this
->verify();
}
public function testDeveloperAsync() {
$this
->drupalGet(Url::fromRoute('apigee_edge.settings.developer.sync'));
$this
->clickLinkProperly('Background');
$this
->assertSession()
->pageTextContains('Developer synchronization is scheduled.');
$queue_service = $this->container
->get('queue');
$queue = $queue_service
->get('apigee_edge_job');
$queue_worker_manager = $this->container
->get('plugin.manager.queue_worker');
$worker = $queue_worker_manager
->createInstance('apigee_edge_job');
while ($item = $queue
->claimItem()) {
$worker
->processItem($item->data);
$queue
->deleteItem($item);
}
$this
->verify();
}
public function testCliDeveloperSync() {
$cli_service = $this->container
->get('apigee_edge.cli');
$input = new ArgvInput();
$output = new BufferedOutput();
$cli_service
->sync(new SymfonyStyle($input, $output), 't');
$printed_output = $output
->fetch();
foreach ($this->edgeDevelopers as $email => $developer) {
$this
->assertStringContainsString("Copying developer ({$email}) from Apigee Edge.", $printed_output);
}
foreach ($this->drupalUsers as $email => $user) {
$this
->assertStringContainsString("Copying user ({$email}) to Apigee Edge.", $printed_output);
}
foreach ($this->modifiedEdgeDevelopers as $email => $developer) {
$this
->assertStringContainsString("Updating user ({$email}) from Apigee Edge.", $printed_output);
}
foreach ($this->modifiedDrupalUsers as $email => $user) {
$this
->assertStringContainsString("Updating developer ({$email}) in Apigee Edge.", $printed_output);
}
$this
->verify();
}
}