From 7b35553b9b5963fdbcecdd4d75dc4906e0737e07 Mon Sep 17 00:00:00 2001 From: David Mudrak Date: Wed, 21 Mar 2012 22:54:15 +0100 Subject: [PATCH] MDL-20438 Introducing new compare_responses() method --- lib/pluginlib.php | 62 ++++++++++++++- lib/simpletest/testpluginlib.php | 129 +++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) diff --git a/lib/pluginlib.php b/lib/pluginlib.php index 4c47e4153a1..629f65f629e 100644 --- a/lib/pluginlib.php +++ b/lib/pluginlib.php @@ -828,6 +828,60 @@ class available_update_checker { } } + /** + * Compares two raw {@link $recentresponse} records and returns the list of changed updates + * + * This method is used to populate potential update info to be sent to site admins. + * + * @param null|array $old + * @param null|array $new + * @throws available_update_checker_exception + * @return array parts of $new['updates'] that have changed + */ + protected function compare_responses($old, $new) { + + if (is_null($new)) { + return array(); + } + + if (!array_key_exists('updates', $new)) { + throw new available_update_checker_exception('err_response_format'); + } + + if (is_null($old)) { + return $new['updates']; + } + + if (!array_key_exists('updates', $old)) { + throw new available_update_checker_exception('err_response_format'); + } + + $changes = array(); + + foreach ($new['updates'] as $newcomponent => $newcomponentupdates) { + if (empty($old['updates'][$newcomponent])) { + $changes[$newcomponent] = $newcomponentupdates; + continue; + } + foreach ($newcomponentupdates as $newcomponentupdate) { + $inold = false; + foreach ($old['updates'][$newcomponent] as $oldcomponentupdate) { + if ($newcomponentupdate['version'] == $oldcomponentupdate['version']) { + $inold = true; + } + } + if (!$inold) { + if (!isset($changes[$newcomponent])) { + $changes[$newcomponent] = array(); + } + $changes[$newcomponent][] = $newcomponentupdate; + } + } + } + + return $changes; + } + /** * Returns the URL to send update requests to * @@ -1023,7 +1077,13 @@ class available_update_checker { * Fetch available updates info and eventually send notification to site admins */ protected function cron_execute() { - // todo + + $this->restore_response(); + $previous = $this->recentresponse; + $this->fetch(); + $this->restore_response(true); + $current = $this->recentresponse; + $changes = $this->compare_responses($previous, $current); } } diff --git a/lib/simpletest/testpluginlib.php b/lib/simpletest/testpluginlib.php index aaddc5bb422..a9224c0051c 100644 --- a/lib/simpletest/testpluginlib.php +++ b/lib/simpletest/testpluginlib.php @@ -143,6 +143,10 @@ class testable_available_update_checker extends available_update_checker { $this->recentresponse = $this->decode_response($this->get_fake_response()); } + public function compare_responses($old, $new) { + return parent::compare_responses($old, $new); + } + protected function load_current_environment($forcereload=false) { } @@ -357,4 +361,129 @@ class available_update_checker_test extends UnitTestCase { $this->expectException('testable_available_update_checker_cron_executed'); $provider->cron(); } + + public function test_compare_responses_both_null() { + $provider = testable_available_update_checker::instance(); + $old = null; + $new = null; + $cmp = $provider->compare_responses($old, $new); + $this->assertIsA($cmp, 'array'); + $this->assertTrue(empty($cmp)); + } + + public function test_compare_responses_old_null() { + $provider = testable_available_update_checker::instance(); + $old = null; + $new = array( + 'updates' => array( + 'core' => array( + array( + 'version' => 2012060103 + ) + ) + ) + ); + $cmp = $provider->compare_responses($old, $new); + $this->assertIsA($cmp, 'array'); + $this->assertFalse(empty($cmp)); + $this->assertTrue(isset($cmp['core'][0]['version'])); + $this->assertEqual($cmp['core'][0]['version'], 2012060103); + } + + public function test_compare_responses_no_change() { + $provider = testable_available_update_checker::instance(); + $old = $new = array( + 'updates' => array( + 'core' => array( + array( + 'version' => 2012060104 + ), + array( + 'version' => 2012120100 + ) + ), + 'mod_foo' => array( + array( + 'version' => 2011010101 + ) + ) + ) + ); + $cmp = $provider->compare_responses($old, $new); + $this->assertIsA($cmp, 'array'); + $this->assertTrue(empty($cmp)); + } + + public function test_compare_responses_new_and_missing_update() { + $provider = testable_available_update_checker::instance(); + $old = array( + 'updates' => array( + 'core' => array( + array( + 'version' => 2012060104 + ) + ), + 'mod_foo' => array( + array( + 'version' => 2011010101 + ) + ) + ) + ); + $new = array( + 'updates' => array( + 'core' => array( + array( + 'version' => 2012060104 + ), + array( + 'version' => 2012120100 + ) + ) + ) + ); + $cmp = $provider->compare_responses($old, $new); + $this->assertIsA($cmp, 'array'); + $this->assertFalse(empty($cmp)); + $this->assertEqual(count($cmp), 1); + $this->assertEqual(count($cmp['core']), 1); + $this->assertEqual($cmp['core'][0]['version'], 2012120100); + } + + public function test_compare_responses_modified_update() { + $provider = testable_available_update_checker::instance(); + $old = array( + 'updates' => array( + 'mod_foo' => array( + array( + 'version' => 2011010101 + ) + ) + ) + ); + $new = array( + 'updates' => array( + 'mod_foo' => array( + array( + 'version' => 2011010102 + ) + ) + ) + ); + $cmp = $provider->compare_responses($old, $new); + $this->assertIsA($cmp, 'array'); + $this->assertFalse(empty($cmp)); + $this->assertEqual(count($cmp), 1); + $this->assertEqual(count($cmp['mod_foo']), 1); + $this->assertEqual($cmp['mod_foo'][0]['version'], 2011010102); + } + + public function test_compare_responses_invalid_format() { + $provider = testable_available_update_checker::instance(); + $broken = array( + 'status' => 'ERROR' // no 'updates' key here + ); + $this->expectException('available_update_checker_exception'); + $cmp = $provider->compare_responses($broken, $broken); + } }