MDL-49497 curl: keep api private and test it using reflection.
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 23 Jun 2015 13:34:19 +0000 (15:34 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Tue, 23 Jun 2015 15:20:20 +0000 (17:20 +0200)
While strictly we should not be testing private APIs, in order
to get this backported to stables without changing visibility
we use reflection to access to such private properties and methods.

Also added one exttest to verify user agent is properly sent.

Finally, fix some wrong whitespace and changed the helper class name
to better alternative.

lib/filelib.php
lib/tests/filelib_test.php

index 423e475..6375faf 100644 (file)
@@ -2683,7 +2683,7 @@ class curl {
     public $emulateredirects = null;
 
     /** @var array cURL options */
-    protected $options;
+    private $options;
 
     /** @var string Proxy host */
     private $proxy_host = '';
@@ -2976,7 +2976,7 @@ class curl {
      * @param array $options
      * @return resource The curl handle
      */
-    protected function apply_opt($curl, $options) {
+    private function apply_opt($curl, $options) {
         // Clean up
         $this->cleanopt();
         // set cookie
index f74e655..b32c328 100644 (file)
@@ -883,7 +883,7 @@ EOF;
      * Test curl agent settings.
      */
     public function test_curl_useragent() {
-        $curl = new curl_extended();
+        $curl = new testable_curl();
         $options = $curl->get_options();
         $this->assertNotEmpty($options);
 
@@ -910,30 +910,65 @@ EOF;
         $curl->unset_option('CURLOPT_USERAGENT');
         $curl->call_apply_opt();
         $this->assertTrue(in_array('User-Agent: MoodleBot/1.0', $curl->header));
+
+        // Finally, test it via exttests, to ensure the agent is sent properly.
+        // Matching.
+        $testurl = $this->getExternalTestFileUrl('/test_agent.php');
+        $extcurl = new curl();
+        $contents = $extcurl->get($testurl, array(), array('CURLOPT_USERAGENT' => 'AnotherUserAgent/1.2'));
+        $response = $extcurl->getResponse();
+        $this->assertSame('200 OK', reset($response));
+        $this->assertSame(0, $extcurl->get_errno());
+        $this->assertSame('OK', $contents);
+        // Not matching.
+        $contents = $extcurl->get($testurl, array(), array('CURLOPT_USERAGENT' => 'NonMatchingUserAgent/1.2'));
+        $response = $extcurl->getResponse();
+        $this->assertSame('200 OK', reset($response));
+        $this->assertSame(0, $extcurl->get_errno());
+        $this->assertSame('', $contents);
     }
 }
 
 /**
  * Test-specific class to allow easier testing of curl functions.
- * 
- * @copyright 2015 Dave Cooper 
+ *
+ * @copyright 2015 Dave Cooper
  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class curl_extended extends curl {
+class testable_curl extends curl {
     /**
-     * Accessor for options array.
+     * Accessor for private options array using reflection.
+     *
+     * @return array
      */
     public function get_options() {
-        return $this->options;
+        // Access to private property.
+        $rp = new ReflectionProperty('curl', 'options');
+        $rp->setAccessible(true);
+        return $rp->getValue($this);
+    }
+
+    /**
+     * Setter for private options array using reflection.
+     *
+     * @param array $options
+     */
+    public function set_options($options) {
+        // Access to private property.
+        $rp = new ReflectionProperty('curl', 'options');
+        $rp->setAccessible(true);
+        $rp->setValue($this, $options);
     }
 
     /**
-     * Setter for options array.
+     * Setter for individual option.
      * @param string $option
      * @param string $value
      */
     public function set_option($option, $value) {
-        $this->options[$option] = $value;
+        $options = $this->get_options();
+        $options[$option] = $value;
+        $this->set_options($options);
     }
 
     /**
@@ -941,17 +976,22 @@ class curl_extended extends curl {
      * @param string $option
      */
     public function unset_option($option) {
-        unset($this->options[$option]);
+        $options = $this->get_options();
+        unset($options[$option]);
+        $this->set_options($options);
     }
 
     /**
-     * Wrapper to access the curl::apply_opt() function
+     * Wrapper to access the private curl::apply_opt() method using reflection.
      *
      * @param array $options
      * @return resource The curl handle
      */
     public function call_apply_opt($options = null) {
+        // Access to private method.
+        $rm = new ReflectionMethod('curl', 'apply_opt');
+        $rm->setAccessible(true);
         $ch = curl_init();
-        return $this->apply_opt($ch, $options);
+        return $rm->invoke($this, $ch, $options);
     }
 }