DownloadTest.php 4.21 KB
Newer Older
1
2
<?php

3
namespace Drupal\Tests\migrate\Kernel\process;
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

use Drupal\Core\StreamWrapper\StreamWrapperInterface;
use Drupal\KernelTests\Core\File\FileTestBase;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Plugin\migrate\process\Download;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;

/**
 * Tests the download process plugin.
 *
 * @group migrate
 */
class DownloadTest extends FileTestBase {

  /**
   * {@inheritdoc}
   */
  public static $modules = ['system'];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->container->get('stream_wrapper_manager')->registerWrapper('temporary', 'Drupal\Core\StreamWrapper\TemporaryStream', StreamWrapperInterface::LOCAL_NORMAL);
  }

  /**
   * Tests a download that overwrites an existing local file.
   */
  public function testOverwritingDownload() {
    // Create a pre-existing file at the destination, to test overwrite behavior.
    $destination_uri = $this->createUri('existing_file.txt');

    // Test destructive download.
    $actual_destination = $this->doTransform($destination_uri);
    $this->assertSame($destination_uri, $actual_destination, 'Import returned a destination that was not renamed');
    $this->assertFileNotExists('public://existing_file_0.txt', 'Import did not rename the file');
  }

  /**
   * Tests a download that renames the downloaded file if there's a collision.
   */
  public function testNonDestructiveDownload() {
    // Create a pre-existing file at the destination, to test overwrite behavior.
    $destination_uri = $this->createUri('another_existing_file.txt');

    // Test non-destructive download.
    $actual_destination = $this->doTransform($destination_uri, ['rename' => TRUE]);
    $this->assertSame('public://another_existing_file_0.txt', $actual_destination, 'Import returned a renamed destination');
    $this->assertFileExists($actual_destination, 'Downloaded file was created');
  }

  /**
   * Tests that an exception is thrown if the destination URI is not writable.
   */
63
  public function testWriteProtectedDestination() {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    // Create a pre-existing file at the destination, to test overwrite behavior.
    $destination_uri = $this->createUri('not-writable.txt');

    // Make the destination non-writable.
    $this->container
      ->get('file_system')
      ->chmod($destination_uri, 0444);

    // Pass or fail, we'll need to make the file writable again so the test
    // can clean up after itself.
    $fix_permissions = function () use ($destination_uri) {
      $this->container
        ->get('file_system')
        ->chmod($destination_uri, 0755);
    };

    try {
      $this->doTransform($destination_uri);
      $fix_permissions();
      $this->fail('MigrateException was not thrown for non-writable destination URI.');
    }
    catch (MigrateException $e) {
      $this->assertTrue(TRUE, 'MigrateException was thrown for non-writable destination URI.');
      $fix_permissions();
    }
  }

  /**
   * Runs an input value through the download plugin.
   *
   * @param string $destination_uri
   *   The destination URI to download to.
   * @param array $configuration
   *   (optional) Configuration for the download plugin.
   *
   * @return string
   *   The local URI of the downloaded file.
   */
  protected function doTransform($destination_uri, $configuration = []) {
    // The HTTP client will return a file with contents 'It worked!'
    $body = fopen('data://text/plain;base64,SXQgd29ya2VkIQ==', 'r');

    // Prepare a mock HTTP client.
    $this->container->set('http_client', $this->getMock(Client::class));
    $this->container->get('http_client')
      ->method('get')
      ->willReturn(new Response(200, [], $body));

    // Instantiate the plugin statically so it can pull dependencies out of
    // the container.
    $plugin = Download::create($this->container, $configuration, 'download', []);

    // Execute the transformation.
    $executable = $this->getMock(MigrateExecutableInterface::class);
    $row = new Row([], []);

    // Return the downloaded file's local URI.
    $value = [
      'http://drupal.org/favicon.ico',
      $destination_uri,
    ];
    return $plugin->transform($value, $executable, $row, 'foobaz');
  }

}