acquia_connector-8.x-1.22/tests/src/Functional/AcquiaTelemetryTest.php

tests/src/Functional/AcquiaTelemetryTest.php
<?php

namespace Drupal\Tests\acquia_connector\Functional;

use Drupal\acquia_connector\EventSubscriber\KernelTerminate\AcquiaTelemetry;
use Drupal\acquia_connector\Services\AcquiaTelemetryService;
use Drupal\Component\Uuid\Php as PhpUuid;
use Drupal\Core\Database\Database;
use Drupal\Tests\BrowserTestBase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\KernelEvent;

/**
 * @coversDefaultClass \Drupal\acquia_connector\EventSubscriber\KernelTerminate\AcquiaTelemetry
 * @group acquia_connector
 */
final class AcquiaTelemetryTest extends BrowserTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'dblog',
    'system',
    'user',
    'acquia_connector',
    'acquia_connector_test',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * The telemetry Service.
   *
   * @var \Drupal\acquia_connector\Services\AcquiaTelemetryService
   */
  protected $acquiaTelemetry;

  /**
   * The Event Type machine name.
   *
   * @var string
   */
  protected $eventTypeMachine;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();
    $this->config('system.site')
      ->set('uuid', (new PhpUuid())->generate())
      ->save();

    // Enable acquia_connector module.
    $this->container->get('module_installer')->install(['acquia_connector']);
    $this->resetAll();

    $this->acquiaTelemetry = new AcquiaTelemetryService(
      $this->container->get('extension.list.module'),
      $this->container->get('config.factory'),
      $this->container->get("state"),
      $this->container->get("logger.factory"),
    );
    $this->eventTypeMachine = preg_replace('@[^a-z0-9-]+@', '_', strtolower('Drupal Module Statistics'));
  }

  /**
   * Tests the sendTelemetry() method of AcquiaCmsTelemetry class for prod env.
   */
  public function testTelemetryLogs(): void {
    $count = 0;
    $telemetry_service = new AcquiaTelemetry(
      $this->container->get('acquia_connector.telemetry_service'),
    );
    $send_request = function () use ($telemetry_service) {
      $telemetry_service->onTerminateEvent(new KernelEvent(
        $this->container->get('http_kernel'),
        Request::create('/'),
        1
      ));
    };

    // Fake Acquia dev environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=dev");
    // Invoke Acquia Temletry event.
    $send_request();
    $query_count = $this->getLogEntry();
    // Assert log entry does not exist.
    $this->assertSame($count, $query_count, 'Telemetry data should not be send as on Acquia dev environment.');

    // Fake Acquia stage environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=stage");
    // Invoke Acquia Temletry event.
    $send_request();
    $query_count = $this->getLogEntry();
    // Assert log entry does not exist.
    $this->assertSame($count, $query_count, 'Telemetry data should not be send as on Acquia stage environment.');

    // Fake Acquia IDE environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=IDE");
    // Invoke Acquia Temletry event.
    $send_request();
    $query_count = $this->getLogEntry();
    // Assert log entry does not exist.
    $this->assertSame($count, $query_count, 'Telemetry data should not be send as on Acquia IDE environment.');

    // Fake Acquia ODE environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=ODE");
    // Invoke Acquia Temletry event.
    $send_request();
    $query_count = $this->getLogEntry();
    // Assert log entry does not exist.
    $this->assertSame($count, $query_count, 'Telemetry data should not be send as on Acquia ODE environment.');

    // Fake Acquia prod environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=prod");
    // Invoke Acquia Temletry event.
    $send_request();
    $query_count = $this->getLogEntry();
    // Assert log entry does exist.
    $this->assertEquals(1, $query_count, 'Telemetry data should send as on Acquia prod environment.');

    // Check the log format is what we expect.
    $message = unserialize($this->getLogData()[0]->variables, ['allowed_classes' => FALSE]);
    $data = json_decode($message['@message'], TRUE);

    // Check acquia_connector exists and is enabled.
    $this->assertArrayHasKey('acquia_connector', $data['event_properties']['extensions']);
    $this->assertEquals('enabled', $data['event_properties']['extensions']['acquia_connector']['status']);

    // Check there are core modules
    $this->assertNotEmpty($data['event_properties']['drupal']['core_enabled']);

    // Check there are profiles
    $this->assertNotEmpty($data['event_properties']['profiles']);
  }

  /**
   * Tests the Telemetry sending log when module installed/uninstalled.
   */
  public function testTelemetryModuleInstallUninstallLogEntry(): void {
    // Fake Acquia prod environment and then send data.
    putenv("AH_SITE_ENVIRONMENT=prod");

    $this->container->get('module_installer')->install(['acquia_connector_subdata_test']);
    $query_count = $this->getLogEntry('acquia_extensions_installed');
    // Assert log entry exist.
    $this->assertEquals(1, $query_count, 'Telemetry data should send as on Acquia prod environment when module installed.');

    $this->container->get('module_installer')->uninstall(['acquia_connector_subdata_test']);
    $query_count = $this->getLogEntry('acquia_extensions_uninstalled');
    // Assert log entry exist.
    $this->assertEquals(1, $query_count, 'Telemetry data should send as on Acquia prod environment when module uninstalled.');

  }

  /**
   * Tests the telemetry data sent.
   */
  public function testTelemetry(): void {
    $get_telemetry_method = $this->getAcquiaTelemetryMethod("getTelemetryData");
    $actual_telemetry_data = $get_telemetry_method->invokeArgs($this->acquiaTelemetry, ['Drupal Module Statistics', []]);

    $this->assertArrayHasKey('event_type', $actual_telemetry_data, "Telemetry data does not contain event_type key.");
    $this->assertArrayHasKey('user_id', $actual_telemetry_data, "Telemetry data does not contain user_id key.");
    $this->assertNotEmpty($actual_telemetry_data['user_id'], "Site UUID is empty.");

    $this->assertArrayHasKey('event_properties', $actual_telemetry_data, "Telemetry data does not contain event_properties key.");

    $this->assertArrayHasKey('extensions', $actual_telemetry_data['event_properties'], "Telemetry data event_properties does not contain extensions key.");
    $this->assertArrayHasKey('php', $actual_telemetry_data['event_properties'], "Telemetry data event_properties does not contain php key.");
    $this->assertArrayHasKey('drupal', $actual_telemetry_data['event_properties'], "Telemetry data event_properties does not contain drupal key.");

    $this->assertContains('acquia_connector', array_keys($actual_telemetry_data['event_properties']['extensions']));
    $this->assertEquals(['version'], array_keys($actual_telemetry_data['event_properties']['php']));
    $this->assertEquals(PHP_VERSION, $actual_telemetry_data['event_properties']['php']['version']);
    $this->assertEquals(['version', 'core_enabled'], array_keys($actual_telemetry_data['event_properties']['drupal']));
    $this->assertContains('user', array_keys($actual_telemetry_data['event_properties']['drupal']['core_enabled']));

  }

  /**
   * Tests the shouldSendTelemetryData() method of AcquiaCmsTelemetry class.
   *
   * @throws \ReflectionException
   *
   * @dataProvider telemetryTestData
   */
  public function testIfTelemetryDataShouldSend($env, bool $should_send): void {
    $get_telemetry_method = $this->getAcquiaTelemetryMethod("getTelemetryData");
    $actual_telemetry_data = $get_telemetry_method->invokeArgs($this->acquiaTelemetry, [$this->eventTypeMachine, []]);
    $should_send_method = $this->getAcquiaTelemetryMethod("shouldSendTelemetryData");
    $env_check_method = $this->getAcquiaTelemetryMethod("isAcquiaProdEnv");
    $state_service = $this->container->get("state");
    $parameters = [
      $this->eventTypeMachine,
      [
        'extensions' => $actual_telemetry_data['event_properties']['extensions'],
        'php' => $actual_telemetry_data['event_properties']['php'],
        'drupal' => $actual_telemetry_data['event_properties']['drupal'],
      ],
    ];

    if ($env) {
      putenv("AH_SITE_ENVIRONMENT=$env");
    }
    $should_send_data = $env_check_method->invoke($this->acquiaTelemetry);
    $should_send_msg = !$should_send ? 'not' : '';
    $this->assertEquals($should_send, $should_send_data, "Should $should_send_msg send telemetry data.");

    $method_hash = $this->getAcquiaTelemetryMethod("getHash");
    $state_service->set(
      "acquia_connector.telemetry.$this->eventTypeMachine.hash",
      $method_hash->invoke($this->acquiaTelemetry, [
        'extensions' => $actual_telemetry_data['event_properties']['extensions'],
        'php' => $actual_telemetry_data['event_properties']['php'],
        'drupal' => $actual_telemetry_data['event_properties']['drupal'],
      ]),
    );

    if ($should_send) {
      $should_send_data = $should_send_method->invokeArgs($this->acquiaTelemetry, $parameters);
      $this->assertFalse($should_send_data, "Should not send telemetry data, if current telemetry data is same as data already sent.");

      $state_service->set("acquia_connector.telemetry.$this->eventTypeMachine.hash", 'O2X4mf9Csg8KLOIqNlUqc9dqXdsL_JE5hjKh4dRPemQ');
      $should_send_data = $should_send_method->invokeArgs($this->acquiaTelemetry, $parameters);
      $this->assertTrue($should_send_data, "Should send telemetry data, if current telemetry data has changed from data already sent.");
    }
  }

  /**
   * Data for testing embed codes.
   *
   * @return \Generator
   *   The test data.
   */
  public static function telemetryTestData(): \Generator {
    yield 'Non Acquia Environment' => [
      NULL,
      FALSE,
    ];
    yield 'Dev Acquia Environment' => [
      'dev',
      FALSE,
    ];
    yield 'Stage Acquia Environment' => [
      'stage',
      FALSE,
    ];
    yield 'Prod Acquia Environment' => [
      'prod',
      TRUE,
    ];
    yield 'IDE Acquia Environment' => [
      'IDE',
      FALSE,
    ];
    yield 'ODE Acquia Environment' => [
      'ODE',
      FALSE,
    ];
  }

  /**
   * Returns the AcquiaTelemetry ReflectionMethod object.
   *
   * @throws \ReflectionException
   */
  protected function getAcquiaTelemetryMethod(string $method_name): \ReflectionMethod {
    $class = new \ReflectionClass($this->acquiaTelemetry);
    $method = $class->getMethod($method_name);
    $method->setAccessible(TRUE);
    return $method;
  }

  /**
   * Get database log for Drupal Module Statistics entry.
   *
   * @param string $event_type
   *   The event type.
   *
   * @return array
   *   Array of log entries.
   */
  protected function getLogData(string $event_type = 'drupal_module_statistics'): array {
    $query = Database::getConnection()
      ->select('watchdog')
      ->fields('watchdog', ['variables'])
      ->condition('type', $event_type)
      ->execute();
    return $query->fetchAll();
  }

  /**
   * Get database log count for Drupal Module Statistics entry.
   *
   * @param string $event_type
   *   The event type.
   *
   * @return int
   *   The log count.
   */
  public function getLogEntry(string $event_type = 'drupal_module_statistics'): int {
    $data = $this->getLogData($event_type);
    return count($data);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc