Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 116 additions & 1 deletion modules/sms_devel/src/Form/SmsDevelMessageForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public function getFormId() {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$results = $form_state->getTemporaryValue('results');

if ($results) {
$form = array_merge($form, $this->verboseResults($results));
}

$form['number'] = [
'#type' => 'tel',
'#title' => $this->t('Phone number'),
Expand Down Expand Up @@ -99,13 +105,25 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#title' => $this->t('Force skip queue'),
'#description' => $this->t('Send or receive the message immediately. If the gateway-specific skip queue setting is turned on, then this option is already applied.'),
'#default_value' => TRUE,
'#name' => 'skip_queue',
];
$form['options']['automated'] = [
'#type' => 'checkbox',
'#title' => $this->t('Automated'),
'#description' => $this->t('Flag this message as automated.'),
'#default_value' => TRUE,
];
$form['options']['verbose'] = [
'#type' => 'checkbox',
'#title' => $this->t('Verbose output'),
'#description' => $this->t('Show full details of messages.'),
'#default_value' => TRUE,
'#states' => [
'visible' => [
':input[name="' . $form['options']['skip_queue']['#name'] . '"]' => ['checked' => TRUE],
],
],
];
$form['options']['send_on'] = [
'#type' => 'datetime',
'#title' => $this->t('Send on'),
Expand Down Expand Up @@ -204,12 +222,18 @@ public function submitSend(array &$form, FormStateInterface $form_state) {
$this->message->setDirection(Direction::OUTGOING);

try {
if ($form_state->getValue('skip_queue')) {
$skip_queue = $form_state->getValue('skip_queue');
$verbose = $form_state->getValue('verbose');
if ($verbose && $skip_queue) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we can't queue verbose messages?

Copy link
Owner Author

@dpi dpi Dec 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cant verbose queue messages, because they arnt handled in the same request as devel. There is no result yet.

$messages = $this->smsProvider->send($this->message);
$results = [];
foreach ($messages as $message) {
$result = $message->getResult();
$this->resultMessage($result);
$results[] = $result;
}
$form_state->setTemporaryValue('results', $results);
$form_state->setRebuild();
}
else {
$this->smsProvider->queue($this->message);
Expand Down Expand Up @@ -252,4 +276,95 @@ protected function resultMessage(SmsMessageResultInterface $result) {
}
}

/**
* Render message results as a HTML table.
*
* @param \Drupal\sms\Message\SmsMessageResultInterface[] $results
*
* @return array
* A render array.
*/
protected function verboseResults(array $results) {
$render = [];

// Renders plain text, or 'Undefined' message if falsey.
$renderString = function($value) {
return !empty($value) ? ['#plain_text' => $value] : ['#markup' => $this->t('<em>Undefined</em>')];
};

// Renders a date text, or 'Undefined' message if falsey.
$renderDate = function($timestamp) {
if ($timestamp) {
$date = DrupalDateTime::createFromTimestamp($timestamp);
return ['#plain_text' => $date->format('c')];
}
else {
return ['#markup' => $this->t('<em>Undefined</em>')];
}
};

$render['results'] = [
'#type' => 'table',
'#caption' => [
'heading' => [
'#type' => 'inline_template',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be '#type' => 'markup' since you're not using any twig placeholders. Inline template has a bit of twig overhead to it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Results" should be a translatable/placeholder.

Overhead isnt really a problem given its renderred once.

'#template' => '<h2>Results</h2>',
]
],
'#header' => [
$this->t('Result'),
$this->t('Error'),
$this->t('Error Message'),
$this->t('Credits Used'),
$this->t('Credits Balance'),
],
];

foreach ($results as $i => $result) {
$row = [];
$row[]['#plain_text'] = $this->t("#@number", ['@number' => $i]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't need to be translatable, we could use new FormattableMarkup('#@number', ['@number' => $i]); here.


$error = $result->getError();
$row[] = $error ? ['#plain_text' => $error] : ['#markup' => $this->t('<em>Success</em>')];
$row[] = $renderString($result->getErrorMessage());
$row[] = $renderString($result->getCreditsUsed());
$row[] = $renderString($result->getCreditsBalance());

$render['results'][] = $row;

$reports_cell = [
'#type' => 'table',
'#header' => [
$this->t('Recipient'),
$this->t('Message ID'),
$this->t('Status'),
$this->t('Status Message'),
$this->t('Time Delivered'),
$this->t('Time Queued'),
],
];
foreach ($result->getReports() as $report) {
$row = [];

$row[] = $renderString($report->getRecipient());
$row[] = $renderString($report->getMessageId());
$row[] = $renderString($report->getStatus());
$row[] = $renderString($report->getStatusMessage());
$row[] = $renderDate($report->getTimeDelivered());
$row[] = $renderDate($report->getTimeQueued());

$reports_cell[] = $row;
}

$render['results'][][] = [
'#wrapper_attributes' => [
'colspan' => count($render['results']['#header']),
],
'data' => $reports_cell,
];
}

return $render;
}

}
115 changes: 92 additions & 23 deletions modules/sms_devel/tests/src/Functional/SmsDevelMessageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ public function testSendSkipQueue() {
$edit['skip_queue'] = TRUE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertResponse(200);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's ok to remove deprecated code usages even though it introduces scope creep.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can commit the deprecation commit separately instead of squashing the whole thing.

$this->assertRaw('Message was processed, 1 delivery reports were generated.');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message was processed, 1 delivery reports were generated.');

$messages = $this->getTestMessages($this->gateway);
$this->assertEqual(1, count($messages));
$this->assertEqual($edit['message'], $messages[0]->getMessage());
$this->assertEquals(1, count($messages));
$this->assertEquals($edit['message'], $messages[0]->getMessage());
}

/**
Expand All @@ -63,13 +63,13 @@ public function testSendNoSkipQueue() {
$edit['skip_queue'] = FALSE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertResponse(200);
$this->assertRaw('Message added to the outgoing queue.');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message added to the outgoing queue.');

$messages = SmsMessage::loadMultiple();
$message = reset($messages);
$this->assertEqual($edit['message'], $message->getMessage(), 'Message is same');
$this->assertEqual(Direction::OUTGOING, $message->getDirection(), 'Message is outgoing');
$this->assertEquals($edit['message'], $message->getMessage(), 'Message is same');
$this->assertEquals(Direction::OUTGOING, $message->getDirection(), 'Message is outgoing');
}

/**
Expand All @@ -82,10 +82,10 @@ public function testReceiveSkipQueue() {
$edit['skip_queue'] = TRUE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Receive'));
$this->assertResponse(200);
$this->assertRaw('Message was processed, 1 delivery reports were generated.');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message was processed, 1 delivery reports were generated.');

$this->assertEqual($edit['message'], sms_test_gateway_get_incoming()['message']);
$this->assertEquals($edit['message'], sms_test_gateway_get_incoming()['message']);
}

/**
Expand All @@ -98,13 +98,13 @@ public function testReceiveNoSkipQueue() {
$edit['skip_queue'] = FALSE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Receive'));
$this->assertResponse(200);
$this->assertRaw('Message added to the incoming queue.');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message added to the incoming queue.');

$messages = SmsMessage::loadMultiple();
$message = reset($messages);
$this->assertEqual($edit['message'], $message->getMessage(), 'Message is same');
$this->assertEqual(Direction::INCOMING, $message->getDirection(), 'Message is incoming');
$this->assertEquals($edit['message'], $message->getMessage(), 'Message is same');
$this->assertEquals(Direction::INCOMING, $message->getDirection(), 'Message is incoming');
}

/**
Expand All @@ -114,8 +114,8 @@ public function testReceiveGatewayInvalid() {
$edit['gateway'] = '';

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Receive'));
$this->assertResponse(200);
$this->assertRaw('Gateway must be selected if receiving a message.');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Gateway must be selected if receiving a message.');
}

/**
Expand All @@ -128,7 +128,7 @@ public function testAutomated() {
$edit['automated'] = FALSE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertResponse(200);
$this->assertSession()->statusCodeEquals(200);

$messages = SmsMessage::loadMultiple();
$message = reset($messages);
Expand All @@ -152,11 +152,11 @@ public function testDate() {
$edit['send_on[date]'] = $date_user->format('Y-m-d');
$edit['send_on[time]'] = $date_user->format('H:i:s');
$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertResponse(200);
$this->assertSession()->statusCodeEquals(200);

$messages = SmsMessage::loadMultiple();
$message = reset($messages);
$this->assertEqual($date->format('U'), $message->getSendTime(), 'Message has send time.');
$this->assertEquals($date->format('U'), $message->getSendTime(), 'Message has send time.');
}

/**
Expand All @@ -170,11 +170,80 @@ public function testNoFallbackGateway() {
$edit['skip_queue'] = TRUE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertResponse(200);
$this->assertRaw('Message could not be sent');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message could not be sent');

$messages = $this->getTestMessages($this->gateway);
$this->assertEqual(0, count($messages), 'No messages sent.');
$this->assertEquals(0, count($messages), 'No messages sent.');
}

/**
* Tests verbose message output.
*/
function testVerboseReports() {
$edit['gateway'] = $this->gateway->id();
$edit['number'] = $this->randomPhoneNumbers(1)[0];
$edit['message'] = $this->randomString();
$edit['skip_queue'] = TRUE;
$edit['verbose'] = TRUE;

$this->drupalPostForm(Url::fromRoute('sms_devel.message'), $edit, t('Send'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->responseContains('Message was processed, 1 delivery reports were generated.');

$first_row = '#edit-results > tbody > tr:nth-child(1)';

// Result.
$selector = $first_row . ' > td:nth-child(1)';
$this->assertSession()->elementTextContains('css', $selector, '#0');

// Error.
$selector = $first_row . ' > td:nth-child(2)';
$this->assertSession()->elementTextContains('css', $selector, 'Success');

// Error Message.
$selector = $first_row . ' > td:nth-child(3)';
$this->assertSession()->elementTextContains('css', $selector, 'Undefined');

// Credits Used.
$selector = $first_row . ' > td:nth-child(4)';
$this->assertSession()->elementTextContains('css', $selector, 'Undefined');

// Credits Balance.
$selector = $first_row . ' > td:nth-child(5)';
$this->assertSession()->elementTextContains('css', $selector, 'Undefined');

$message = $this->getLastTestMessage($this->gateway);
$report = $message->getReports()[0];
$this->assertEquals($edit['number'], $report->getRecipient());

$first_row_first_report = '#edit-results > tbody > tr:nth-child(2) > td > table > tbody > tr:nth-child(1)';

// Recipient.
$selector = $first_row_first_report . ' > td:nth-child(1)';
$this->assertSession()->elementTextContains('css', $selector, $report->getRecipient());

// Message ID.
$selector = $first_row_first_report . ' > td:nth-child(2)';
$this->assertSession()->elementTextContains('css', $selector, $report->getMessageId());

// Status.
$selector = $first_row_first_report . ' > td:nth-child(3)';
$this->assertSession()->elementTextContains('css', $selector, $report->getStatus());

// Status Message.
$selector = $first_row_first_report . ' > td:nth-child(4)';
$this->assertSession()->elementTextContains('css', $selector, $report->getStatusMessage());

// Time Delivered.
$date = DrupalDateTime::createFromTimestamp($report->getTimeDelivered());
$selector = $first_row_first_report . ' > td:nth-child(5)';
$this->assertSession()->elementTextContains('css', $selector, $date->format('c'));

// Time Queued.
$date = DrupalDateTime::createFromTimestamp($report->getTimeQueued());
$selector = $first_row_first_report . ' > td:nth-child(6)';
$this->assertSession()->elementTextContains('css', $selector, $date->format('c'));
}

}
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<testsuite name="SMS Framework">
<directory>./tests</directory>
<directory>./modules/sms_user/tests</directory>
<directory>./modules/sms_devel/tests</directory>
</testsuite>
</testsuites>
<!-- Filter for coverage reports. -->
Expand Down