From 31307b8fedea9c2510c80f9cb50919c9dbb7e10e Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Wed, 17 Dec 2014 13:46:48 -0500
Subject: [PATCH] Refactored for clarity/extensibility; added test.

---
 module/VuFind/src/VuFind/SMS/Clickatell.php   | 117 +++++++++++++-----
 .../src/VuFindTest/SMS/ClickatellTest.php     |  21 ++++
 2 files changed, 105 insertions(+), 33 deletions(-)

diff --git a/module/VuFind/src/VuFind/SMS/Clickatell.php b/module/VuFind/src/VuFind/SMS/Clickatell.php
index 875435e68f7..60cf8a2957c 100644
--- a/module/VuFind/src/VuFind/SMS/Clickatell.php
+++ b/module/VuFind/src/VuFind/SMS/Clickatell.php
@@ -73,39 +73,7 @@ class Clickatell extends AbstractBase
      */
     public function text($provider, $to, $from, $message)
     {
-        // Get API settings from config
-        $user = isset($this->smsConfig->Clickatell->user)
-            ? $this->smsConfig->Clickatell->user : null;
-        $password = isset($this->smsConfig->Clickatell->password)
-            ? $this->smsConfig->Clickatell->password : null;
-        $api_id = isset($this->smsConfig->Clickatell->api_id)
-            ? $this->smsConfig->Clickatell->api_id : null;
-        $url = isset($this->smsConfig->Clickatell->url)
-            ? trim($this->smsConfig->Clickatell->url, '?')
-            : "https://api.clickatell.com/http/sendmsg";
-
-        // Clickatell expects UCS-2 encoding:
-        if (!function_exists('iconv')) {
-            throw new MailException('Clickatell requires iconv PHP extension.');
-        }
-        // Normalize UTF-8 if intl extension is installed:
-        if (class_exists('Normalizer')) {
-            $message = \Normalizer::normalize($message);
-        }
-        $message = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $message);
-
-        // We need to trim to 160 bytes (note that we need to use substr and not
-        // mb_substr, because the limit is BYTES not CHARACTERS; this may result
-        // in broken multi-byte characters but it seems unavoidable):
-        $message = substr($message, 0, 160);
-
-        // Add parameters to URL:
-        $url .= "?api_id=" . urlencode($api_id);
-        $url .= "&user=" . urlencode($user);
-        $url .= "&password=" . urlencode($password);
-        $url .= "&to=" . urlencode($this->filterPhoneNumber($to));
-        $url .= "&text=" . urlencode($message);
-
+        $url = $this->getApiUrl($to, $message);
         try {
             $result = $this->client->setMethod('GET')->setUri($url)->send();
         } catch (\Exception $e) {
@@ -134,4 +102,87 @@ class Clickatell extends AbstractBase
             'Clickatell' => array('name' => 'Clickatell', 'domain' => null)
         );
     }
+
+    /**
+     * Get API username.
+     *
+     * @return string
+     */
+    protected function getApiUsername()
+    {
+        return isset($this->smsConfig->Clickatell->user)
+            ? $this->smsConfig->Clickatell->user : null;
+    }
+
+    /**
+     * Get API password.
+     *
+     * @return string
+     */
+    protected function getApiPassword()
+    {
+        return isset($this->smsConfig->Clickatell->password)
+            ? $this->smsConfig->Clickatell->password : null;
+    }
+
+    /**
+     * Get API ID.
+     *
+     * @return string
+     */
+    protected function getApiId()
+    {
+        return isset($this->smsConfig->Clickatell->api_id)
+            ? $this->smsConfig->Clickatell->api_id : null;
+    }
+
+    /**
+     * Get API URL.
+     *
+     * @param string $to      The phone number at the provider
+     * @param string $message The message to send
+     *
+     * @return string
+     */
+    protected function getApiUrl($to, $message)
+    {
+        // Get base URL:
+        $url = isset($this->smsConfig->Clickatell->url)
+            ? trim($this->smsConfig->Clickatell->url, '?')
+            : "https://api.clickatell.com/http/sendmsg";
+
+        // Add parameters to URL:
+        $url .= "?api_id=" . urlencode($this->getApiId());
+        $url .= "&user=" . urlencode($this->getApiUsername());
+        $url .= "&password=" . urlencode($this->getApiPassword());
+        $url .= "&to=" . urlencode($this->filterPhoneNumber($to));
+        $url .= "&text=" . urlencode($this->formatMessage($message));
+
+        return $url;
+    }
+
+    /**
+     * Format message for texting.
+     *
+     * @param string $message Message to format
+     *
+     * @return string
+     */
+    protected function formatMessage($message)
+    {
+        // Clickatell expects UCS-2 encoding:
+        if (!function_exists('iconv')) {
+            throw new MailException('Clickatell requires iconv PHP extension.');
+        }
+        // Normalize UTF-8 if intl extension is installed:
+        if (class_exists('Normalizer')) {
+            $message = \Normalizer::normalize($message);
+        }
+        $message = iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $message);
+
+        // We need to trim to 160 bytes (note that we need to use substr and not
+        // mb_substr, because the limit is BYTES not CHARACTERS; this may result
+        // in broken multi-byte characters but it seems unavoidable):
+        return substr($message, 0, 160);
+    }
 }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
index efedf0a00b0..b4d6e223ae2 100644
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
+++ b/module/VuFind/tests/unit-tests/src/VuFindTest/SMS/ClickatellTest.php
@@ -87,6 +87,27 @@ class ClickatellTest extends \VuFindTest\Unit\TestCase
         );
     }
 
+    /**
+     * Test unexpected response
+     *
+     * @return void
+     * @expectedException VuFind\Exception\Mail
+     * @expectedExceptionMessage badbadbad
+     */
+    public function testUnexpectedResponse()
+    {
+        $client = $this->getMockClient();
+        $expectedUri = 'https://api.clickatell.com/http/sendmsg?api_id=api_id&user=user&password=password&to=1234567890&text=hello';
+        $response = new \Zend\Http\Response();
+        $response->setStatusCode(200);
+        $response->setContent('badbadbad');
+        $client->expects($this->once())->method('setMethod')->with($this->equalTo('GET'))->will($this->returnValue($client));
+        $client->expects($this->once())->method('setUri')->with($this->equalTo($expectedUri))->will($this->returnValue($client));
+        $client->expects($this->once())->method('send')->will($this->returnValue($response));
+        $obj = $this->getClickatell($client);
+        $obj->text('Clickatell', '1234567890', 'test@example.com', 'hello');
+    }
+
     /**
      * Test unsuccessful query
      *
-- 
GitLab