View source
<?php
namespace Drupal\Tests\webform_scheduled_tasks\Kernel;
use Drupal\Core\Archiver\ArchiveTar;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\file\Entity\File;
use Drupal\KernelTests\Core\File\FileTestBase;
use Drupal\webform\Entity\Webform;
use Drupal\webform\Entity\WebformSubmission;
use Drupal\webform_scheduled_tasks\Entity\WebformScheduledTask;
use Drupal\webform_scheduled_tasks\Plugin\WebformScheduledTasks\Task\EmailedExport;
class EmailedExportTest extends FileTestBase {
use AssertMailTrait;
protected $strictConfigSchema = FALSE;
public static $modules = [
'system',
'user',
'file',
'webform',
'webform_scheduled_tasks',
'webform_scheduled_tasks_test_types',
];
protected $testWebform;
protected function setUp() {
parent::setUp();
$this
->installSchema('webform', [
'webform',
]);
$this
->installSchema('file', [
'file_usage',
]);
$this
->installEntitySchema('webform_submission');
$this
->installEntitySchema('file');
$this
->installEntitySchema('user');
$this
->setSetting('file_private_path', $this->container
->get('site.path') . '/private');
$this->testWebform = $this
->createTestWebform();
}
public function testFileSystemExport() {
$scheduled_task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'include_attachments' => FALSE,
'delete_submissions' => FALSE,
]);
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$mail = $this
->getMails();
$this
->assertCount(2, $mail);
$this
->assertEquals($mail[0]['to'], 'foo@example.com');
$this
->assertEquals($mail[1]['to'], 'bar@example.com');
$this
->assertStringContainsString('system/files/scheduled-exports/foo.webform_scheduled_task.foo.csv', $mail[0]['body']);
$this
->assertEquals($mail[0]['subject'], 'Export generated for Test form');
$this
->assertFileExists('private://scheduled-exports/foo.webform_scheduled_task.foo.csv');
$file_contents = file_get_contents('private://scheduled-exports/foo.webform_scheduled_task.foo.csv');
$this
->assertStringContainsString('|"FOO SUBMISSION CONTENT"', $file_contents);
$this
->assertStringContainsString('|"BAR SUBMISSION CONTENT"', $file_contents);
$file = File::load(3);
$this
->assertEquals(TRUE, $file
->isPermanent());
$this
->assertEquals('private://scheduled-exports/foo.webform_scheduled_task.foo.csv', $file
->getFileUri());
$this
->assertCount(1, $this->container
->get('file.usage')
->listUsage($file));
$scheduled_task
->setNextTaskRunDate(1);
webform_scheduled_tasks_cron();
$file = File::load(4);
$this
->assertEquals('private://scheduled-exports/foo.webform_scheduled_task.foo_0.csv', $file
->getFileUri());
$this
->assertCount(1, $this->container
->get('file.usage')
->listUsage($file));
}
public function testExportRetainedSubmissions() {
$this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'include_attachments' => FALSE,
]);
$submissions = $this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$this
->assertCount(2, $this
->getMails());
foreach ($submissions as $submission) {
$this
->assertNotNull(WebformSubmission::load($submission
->id()));
}
}
public function testExportSubmissionsDelete() {
$this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'delete_submissions' => TRUE,
'include_attachments' => FALSE,
]);
$submissions = $this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$this
->assertCount(2, $this
->getMails());
foreach ($submissions as $submission) {
$this
->assertNull(WebformSubmission::load($submission
->id()));
}
}
public function testBadExportsAreNotCompleted() {
$task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'delete_submissions' => TRUE,
'include_attachments' => FALSE,
]);
$submissions = $this
->createTestSubmissions();
$this
->setSetting('file_private_path', '/not-a-writeable-dir');
webform_scheduled_tasks_cron();
$this
->assertTrue($task
->isHalted());
$this
->assertEquals('An error was encountered when running the task: Could not create a directory for the exported files to be written to.', $task
->getHaltedReason());
foreach ($submissions as $submission) {
$this
->assertNotNull(WebformSubmission::load($submission
->id()));
}
}
public function testArchiveBasedExport() {
$task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'json',
'exporter_settings' => [
'file_name' => 'submission-[webform_submission:serial]',
],
'delete_submissions' => TRUE,
'include_attachments' => FALSE,
]);
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$this
->assertFalse($task
->isHalted());
$file = File::load(3);
$this
->assertEquals('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz', $file
->getFileUri());
$archive = new ArchiveTar('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz');
$this
->assertEquals('submission-1.json', $archive
->listContent()[0]['filename']);
$this
->assertEquals('submission-2.json', $archive
->listContent()[1]['filename']);
$this
->assertStringContainsString('FOO SUBMISSION CONTENT', $archive
->extractInString('submission-1.json'));
$this
->assertStringContainsString('BAR SUBMISSION CONTENT', $archive
->extractInString('submission-2.json'));
}
public function testSubmissionsExceedingBatchLimit() {
$this->container
->get('config.factory')
->getEditable('webform.settings')
->set('batch.default_batch_export_size', 2);
$this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'json',
'exporter_settings' => [
'file_name' => 'submission-[webform_submission:serial]',
],
'delete_submissions' => TRUE,
'include_attachments' => FALSE,
]);
$this
->createTestSubmissions();
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$file = File::load(5);
$this
->assertEquals('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz', $file
->getFileUri());
$archive = new ArchiveTar('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz');
$this
->assertCount(4, $archive
->listContent());
$this
->assertStringContainsString('FOO SUBMISSION CONTENT', $archive
->extractInString('submission-1.json'));
$this
->assertStringContainsString('BAR SUBMISSION CONTENT', $archive
->extractInString('submission-2.json'));
$this
->assertStringContainsString('FOO SUBMISSION CONTENT', $archive
->extractInString('submission-3.json'));
$this
->assertStringContainsString('BAR SUBMISSION CONTENT', $archive
->extractInString('submission-4.json'));
}
public function testTaskWithEmptyResultSet() {
$task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'json',
'exporter_settings' => [
'file_name' => 'submission-[webform_submission:serial]',
],
'delete_submissions' => TRUE,
'include_attachments' => FALSE,
]);
webform_scheduled_tasks_cron();
$this
->assertFalse($task
->isHalted());
$this
->assertCount(0, $this
->getMails());
}
public function testIncludeAttachedFilesWithNativeArchive() {
$task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'json',
'exporter_settings' => [
'file_name' => 'submission-[webform_submission:serial]',
],
'delete_submissions' => TRUE,
'include_attachments' => TRUE,
]);
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$this
->assertFalse($task
->isHalted());
$this
->assertCount(2, $this
->getMails());
$archive = new ArchiveTar('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz');
$contents = $archive
->listContent();
$this
->assertCount(4, $contents);
$this
->assertEquals('submission-1/test.pdf', $contents[0]['filename']);
$this
->assertEquals('submission-1.json', $contents[1]['filename']);
$this
->assertEquals('submission-2/test.pdf', $contents[2]['filename']);
$this
->assertEquals('submission-2.json', $contents[3]['filename']);
}
public function testIncludeAttachedFilesWithNativeFile() {
$task = $this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_FILESYSTEM,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'delete_submissions' => TRUE,
'include_attachments' => TRUE,
]);
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$this
->assertFalse($task
->isHalted());
$this
->assertCount(2, $this
->getMails());
$archive = new ArchiveTar('private://scheduled-exports/foo.webform_scheduled_task.foo.tar.gz');
$contents = $archive
->listContent();
$this
->assertCount(3, $contents);
$this
->assertEquals('submission-1/test.pdf', $contents[0]['filename']);
$this
->assertEquals('submission-2/test.pdf', $contents[1]['filename']);
$this
->assertEquals('foo.webform_scheduled_task.foo/foo.webform_scheduled_task.foo.csv', $contents[2]['filename']);
$this
->assertStringContainsString('FOO SUBMISSION CONTENT', $archive
->extractInString('foo.webform_scheduled_task.foo/foo.webform_scheduled_task.foo.csv'));
$this
->assertStringContainsString('BAR SUBMISSION CONTENT', $archive
->extractInString('foo.webform_scheduled_task.foo/foo.webform_scheduled_task.foo.csv'));
}
public function testSendExportAsEmailAttachment() {
$this
->createTestTask([
'email_addresses' => 'foo@example.com, bar@example.com',
'storage_type' => EmailedExport::STORAGE_TYPE_EMAIL,
'exporter' => 'delimited_text',
'exporter_settings' => [
'delimiter' => '|',
'excel' => TRUE,
],
'include_attachments' => FALSE,
'delete_submissions' => FALSE,
]);
$this
->createTestSubmissions();
webform_scheduled_tasks_cron();
$mail = $this
->getMails();
$this
->assertCount(2, $mail);
$this
->assertEquals('foo.webform_scheduled_task.foo.csv', $mail[0]['params']['attachments'][0]['filename']);
$this
->assertEquals('text/csv', $mail[0]['params']['attachments'][0]['filemime']);
$this
->assertStringContainsString('scheduled-exports/foo.webform_scheduled_task.foo.csv', $mail[0]['params']['attachments'][0]['filepath']);
$this
->assertStringContainsString('FOO SUBMISSION CONTENT', $mail[0]['params']['attachments'][0]['filecontent']);
$this
->assertStringContainsString('BAR SUBMISSION CONTENT', $mail[0]['params']['attachments'][0]['filecontent']);
$this
->assertFileExists('private://scheduled-exports/foo.webform_scheduled_task.foo.csv');
}
protected function createTestSubmissions() {
$submissions = [];
foreach ([
'FOO SUBMISSION CONTENT',
'BAR SUBMISSION CONTENT',
] as $submission_content) {
$test_file = $this->container
->get('plugin.manager.webform.element')
->createInstance('managed_file')
->getTestValues([
'#webform_key' => 'test',
'#file_extensions' => 'pdf',
], $this->testWebform, []);
$submission = WebformSubmission::create([
'webform_id' => 'foo',
'data' => [
'name' => $submission_content,
'test_file' => array_shift($test_file),
],
]);
$submission
->save();
$submissions[] = $submission;
}
return $submissions;
}
protected function createTestWebform(array $values = []) {
$webform = Webform::create($values + [
'id' => 'foo',
'title' => 'Test form',
]);
$webform
->save();
$elements = [
'name' => [
'#type' => 'textfield',
'#title' => 'name',
],
'test_file' => [
'#type' => 'managed_file',
'#title' => 'Important file',
],
];
$webform
->setElements($elements);
$webform
->save();
return $webform;
}
protected function createTestTask(array $settings = []) {
$scheduled_task = WebformScheduledTask::create([
'id' => 'foo',
'result_set_type' => 'all_submissions',
'webform' => 'foo',
'interval' => [
'amount' => 1,
'multiplier' => 60,
],
'task_type' => 'export_email_results',
'task_settings' => $settings,
]);
$scheduled_task
->save();
$scheduled_task
->setNextTaskRunDate(10);
return $scheduled_task;
}
}