Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/YOURLS/YOURLS.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOzh <ozh@ozh.org>2022-04-15 15:59:49 +0300
committerOzh <ozh@ozh.org>2022-04-15 15:59:49 +0300
commit6ad19996319ae361a98600437928153e6afa884e (patch)
tree0f8f996fd47d2bb20a6e1dbaf1dd005080dc6c25
parenta1ce6306c52d211ce8c674b1eef30524f8618e59 (diff)
More checks with new version noticesayo_version_checks
WIP & ugly mess for the moment, full of var_dumps, will fix later next week * Motivations : * add unit tests to make sure running 1.8.3-dev will trigger a new version notice when 1.8.3 is out (I think it already works this way) * more validation of the api core/update response * Current problems : * http/api-check.php tests are not dependent from each other: resetting options in setUp/tearDown as we should raises errors * in http/api-check.php::test_api_failed_request_server_error() the yourls_get_option() returns false despite yourls_check_core_version() correct yourls_update_option(), wtf
-rw-r--r--includes/functions-html.php8
-rw-r--r--includes/functions-http.php39
-rw-r--r--includes/functions.php2
-rw-r--r--tests/bootstrap.php13
-rw-r--r--tests/tests/http/api-check.php134
5 files changed, 180 insertions, 16 deletions
diff --git a/includes/functions-html.php b/includes/functions-html.php
index 667cbe40..2ae620f8 100644
--- a/includes/functions-html.php
+++ b/includes/functions-html.php
@@ -918,13 +918,16 @@ function yourls_l10n_calendar_strings() {
* Display a notice if there is a newer version of YOURLS available
*
* @since 1.7
+ * @param string $compare_with Optional, YOURLS version to compare to
*/
-function yourls_new_core_version_notice() {
+function yourls_new_core_version_notice($compare_with = false) {
+ $compare_with = $compare_with ?: YOURLS_VERSION;
$checks = yourls_get_option( 'core_version_checks' );
$latest = isset($checks->last_result->latest) ? yourls_sanitize_version($checks->last_result->latest) : false;
- if( $latest AND version_compare( $latest, YOURLS_VERSION, '>' ) ) {
+ if( $latest AND version_compare( $latest, $compare_with, '>' ) ) {
+ yourls_do_action('new_core_version_notice', $latest);
$msg = yourls_s( '<a href="%s">YOURLS version %s</a> is available. Please update!', 'http://yourls.org/download', $latest );
yourls_add_notice( $msg );
}
@@ -986,4 +989,3 @@ function yourls_html_favicon() {
printf( '<link rel="shortcut icon" href="%s" />', yourls_get_yourls_favicon_url(false) );
}
-
diff --git a/includes/functions-http.php b/includes/functions-http.php
index 12e953bd..3756250d 100644
--- a/includes/functions-http.php
+++ b/includes/functions-http.php
@@ -328,6 +328,7 @@ function yourls_check_core_version() {
if( is_string( $req ) or !$req->success ) {
$checks->failed_attempts = $checks->failed_attempts + 1;
yourls_update_option( 'core_version_checks', $checks );
+ yourls_ut_var_dump( $checks );
if( is_string($req) ) {
yourls_debug_log('Version check failed: ' . $req);
}
@@ -353,9 +354,11 @@ function yourls_check_core_version() {
/**
* Make sure response from api.yourls.org is valid
*
- * we should get a json object with two following properties:
+ * 1) we should get a json object with two following properties:
* 'latest' => a string representing a YOURLS version number, eg '1.2.3'
* 'zipurl' => a string for a zip package URL, from github, eg 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3'
+ * 2) 'latest' and version extracted from 'zipurl' should match
+ * 3) the object should not contain any other key
*
* @since 1.7.7
* @param $json JSON object to check
@@ -365,8 +368,10 @@ function yourls_validate_core_version_response($json) {
return (
isset($json->latest)
&& isset($json->zipurl)
+ && yourls_validate_core_version_response_keys($json)
&& $json->latest === yourls_sanitize_version($json->latest)
&& $json->zipurl === yourls_sanitize_url($json->zipurl)
+ && $json->latest === yourls_get_version_from_zipball_url($json->zipurl)
&& join('.',array_slice(explode('.',parse_url($json->zipurl, PHP_URL_HOST)), -2, 2)) === 'github.com'
// this last bit get the host ('api.github.com'), explodes on '.' (['api','github','com']) and keeps the last two elements
// to make sure domain is either github.com or one of its subdomain (api.github.com for instance)
@@ -375,6 +380,37 @@ function yourls_validate_core_version_response($json) {
}
/**
+ * Get version number from Github zipball URL (last part of URL, really)
+ * @since 1.8.3
+ * @param string $zipurl eg 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3'
+ * @return string
+ */
+function yourls_get_version_from_zipball_url($zipurl) {
+ $version = '';
+ $parts = explode('/', parse_url(yourls_sanitize_url($zipurl), PHP_URL_PATH));
+ // expect at least 1 slash in path, return last part
+ if( count($parts) > 1 ) {
+ $version = end($parts);
+ }
+ return $version;
+}
+
+/**
+ * Check if object has only expected keys 'latest' and 'zipurl'
+ * @since 1.8.3
+ * @param object $json
+ * @return bool
+ */
+function yourls_validate_core_version_response_keys($json) {
+ $keys = array('latest', 'zipurl');
+ return (
+ count(array_diff(array_keys((array)$json), $keys)) === 0
+ && isset($json->latest)
+ && isset($json->zipurl)
+ );
+}
+
+/**
* Determine if we want to check for a newer YOURLS version (and check if applicable)
*
* Currently checks are performed every 24h and only when someone is visiting an admin page.
@@ -457,4 +493,3 @@ function yourls_can_http_over_ssl() {
return ( $ssl_curl OR $ssl_socket );
}
-
diff --git a/includes/functions.php b/includes/functions.php
index 62141243..55860ea2 100644
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -1267,5 +1267,5 @@ function yourls_set_url_scheme( $url, $scheme = false ) {
*/
function yourls_tell_if_new_version() {
yourls_debug_log( 'Check for new version: '.( yourls_maybe_check_core_version() ? 'yes' : 'no' ) );
- yourls_new_core_version_notice();
+ yourls_new_core_version_notice(YOURLS_VERSION);
}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index c4320a58..aaa06693 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -48,4 +48,17 @@ yourls_get_all_options();
yourls_load_plugins();
// At this point, tests will start
+
+// Simplify yourls_die() when running unit tests
+yourls_add_action( 'pre_yourls_die', function($params) {
+ printf("\n\nCalling yourls_die(). %s : %s (%s)\n\n", $params[1], $params[0], $params[2]);
+ echo "Last 10 Backtrace:\n";
+ $trace = debug_backtrace();
+ foreach( array_slice($trace, 0, 10) as $t ) {
+ printf("** %s:%d %s() with args\n%s\n", $t['file'], $t['line'], $t['function'], var_export($t['args'], true));
+ }
+
+ die(1);
+} );
+
echo "YOURLS installed, starting PHPUnit\n\n";
diff --git a/tests/tests/http/api-check.php b/tests/tests/http/api-check.php
index 5455b7bf..7b714165 100644
--- a/tests/tests/http/api-check.php
+++ b/tests/tests/http/api-check.php
@@ -9,9 +9,20 @@
*/
class HTTP_AYO_Tests extends PHPUnit\Framework\TestCase {
+ protected $actions, $core_version_checks;
+
+ protected function setUp(): void {
+ global $yourls_actions;
+ $this->actions = $yourls_actions;
+ $this->core_version_checks = yourls_get_option( 'core_version_checks' );
+ }
+
protected function tearDown(): void {
yourls_remove_all_filters( 'is_admin' );
yourls_remove_all_filters( 'shunt_yourls_http_request' );
+ global $yourls_actions;
+ $yourls_actions = $this->actions;
+ yourls_update_option( 'core_version_checks', $this->core_version_checks );
}
/**
@@ -76,6 +87,7 @@ class HTTP_AYO_Tests extends PHPUnit\Framework\TestCase {
$this->assertFalse( yourls_check_core_version() );
$checks = yourls_get_option( 'core_version_checks' );
+ yourls_ut_var_dump( $checks );
$after_check = $checks->failed_attempts;
$this->assertEquals( $after_check, $before_check + 1 );
@@ -294,44 +306,56 @@ class HTTP_AYO_Tests extends PHPUnit\Framework\TestCase {
public function json_responses() {
$return = array();
- // expected
- $return[] = array(
+ $return['expected'] = array(
(object)array(
'latest' => '1.2.3',
'zipurl' => 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3',
),
true);
- // incorrect version number
- $return[] = array(
+ $return['unexpected version number format'] = array(
(object)array(
'latest' => '1.2.3-something',
'zipurl' => 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3',
),
false);
- // url not part of github.com
- $return[] = array(
+ $return['version mismatch'] = array(
+ (object)array(
+ 'latest' => '1.2.3',
+ 'zipurl' => 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.4',
+ ),
+ false);
+
+ $return['url not part of github.com'] = array(
(object)array(
'latest' => '1.2.3',
'zipurl' => 'https://notgithub.com/repos/YOURLS/YOURLS/zipball/1.2.3',
),
false);
- // no version
- $return[] = array(
+ $return['no version'] = array(
(object)array(
'zipurl' => 'https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3',
),
false);
- // no URL
- $return[] = array(
+ $return['no URL'] = array(
(object)array(
'latest' => '1.2.3',
),
false);
+ $return['nothing 1'] = array(
+ (object)[],
+ false);
+
+ $return['nothing 2'] = array([],
+ false);
+
+ $return['nothing 3'] = array(false,
+ false);
+
return $return;
}
@@ -345,4 +369,94 @@ class HTTP_AYO_Tests extends PHPUnit\Framework\TestCase {
$this->assertSame( $expected, yourls_validate_core_version_response($json) );
}
+ /**
+ * Provide various scenarios for version reported by api.yourls.org / current version
+ */
+ public function new_version_scenarios() {
+ $return = array();
+
+ // AYO current notice
+ $return[] = ['1.2.3', '1.2.2', true]; // new version - display notice
+/* $return[] = ['1.3', '1.2.2', true]; // new version - display notice
+ $return[] = ['1.3', '1.22', true]; // older version - don't display version
+ $return[] = ['1.8.22', '1.8.3', true]; // new version - display notice
+ $return[] = ['1.2.3', '1.2.3-beta', true]; // new version - display notice
+ $return[] = ['1.2.2', '1.2.2', false]; // same version - don't display notice
+ $return[] = ['1.2.2', '1.2.3', false]; // older version - don't display version
+ $return[] = ['99.9.9', false, false]; // newer version compared to actual current YOURLS version - display notice*/
+
+ return $return;
+ }
+
+ /**
+ * Test various YOURLS version strings from api.yourls.org, compare them to the actual version
+ * and make sure we display the correct update notice
+ *
+ * @dataProvider new_version_scenarios
+ */
+ public function test_new_version_notice( $api_version, $current_version, $expected ) {
+ // fake the api response
+ $check = (object)array(
+ 'last_result' => (object)array(
+ 'latest' => $api_version,
+ ),
+ );
+ yourls_add_option('core_version_checks', $check);
+
+ // trigger yourls_core_version_notice() and check we had expected action
+ yourls_new_core_version_notice($current_version);
+ $this->assertSame($expected, yourls_did_action('new_core_version_notice'));
+ }
+
+ /**
+ * Test various zipball URLs and get version number from it
+ */
+ function various_zipball_url_version() {
+ $return = [];
+
+ $return[] = ['https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3', '1.2.3'];
+ $return[] = ['https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3-beta', '1.2.3-beta'];
+ $return[] = ['https://api.github.com/repos/YOURLS/YOURLS/zipball/1.2.3/lol', 'lol'];
+ $return[] = ['http://hey', ''];
+ $return[] = ['lol', ''];
+ $return[] = ['', ''];
+
+ return $return;
+ }
+
+ /**
+ * Test various zipball URLs and get version number from it
+ *
+ * @dataProvider various_zipball_url_version
+ */
+ public function test_get_version_from_zipball_url($url, $expected) {
+ $this->assertSame($expected, yourls_get_version_from_zipball_url($url));
+ }
+
+
+ /**
+ * test various core version JSON responses from api.yourls.org
+ */
+ function get_various_json_response_keys() {
+ $return = [];
+
+ $return['latest & zipurl'] = [['latest' => 'ok', 'zipurl' => 'ok'], true];
+ $return['no latest'] = [['zipurl' => 'ok'], false];
+ $return['no zipurl'] = [['latest' => 'ok'], false];
+ $return['latest & other key'] = [['latest' => 'ok', 'other' => 'oops'], false];
+ $return['zipurl & other key'] = [['zipurl' => 'ok', 'other' => 'oops'], false];
+ $return['nothing'] = [[], false];
+ $return['extra key'] = [['latest' => 'ok', 'zipurl' => 'ok', 'extra' => 'oops'], false];
+
+ return $return;
+ }
+
+ /**
+ * Check yourls_validate_core_version_response_keys() works as expected
+ * @dataProvider get_various_json_response_keys
+ */
+ function test_yourls_validate_core_version_response_keys($json, $expected) {
+ $this->assertSame(yourls_validate_core_version_response_keys((object)$json), $expected);
+ }
+
}