From 8dcad876310d7e2ccfe2430823cbe4f0f4e9f40d Mon Sep 17 00:00:00 2001 From: Andrew Nicols <andrew@nicols.co.uk> Date: Tue, 15 Oct 2024 22:50:40 +0800 Subject: [PATCH] MDL-81308 core: Update tests to not use withConsecutive --- .upgradenotes/MDL-81308-2024101712591343.yml | 19 +++ .../tests/expired_contexts_test.php | 72 ++++++++--- admin/tool/langimport/tests/locale_test.php | 20 ++- admin/tool/usertours/tests/tour_test.php | 55 +++++++-- .../tests/activity_custom_completion_test.php | 13 +- course/tests/category_hooks_test.php | 23 ++-- files/tests/converter_test.php | 45 ++++--- lib/filestorage/tests/file_system_test.php | 9 +- lib/tests/completionlib_test.php | 97 +++++++++++---- .../exportable_filearea_test.php | 13 +- .../exportable_textarea_test.php | 13 +- repository/dropbox/tests/api_test.php | 116 +++++++++++------- .../tests/googledocs_search_content_test.php | 48 ++++---- .../browser/googledocs_drive_content_test.php | 49 ++++---- 14 files changed, 397 insertions(+), 195 deletions(-) create mode 100644 .upgradenotes/MDL-81308-2024101712591343.yml diff --git a/.upgradenotes/MDL-81308-2024101712591343.yml b/.upgradenotes/MDL-81308-2024101712591343.yml new file mode 100644 index 00000000000..749e120178a --- /dev/null +++ b/.upgradenotes/MDL-81308-2024101712591343.yml @@ -0,0 +1,19 @@ +issueNumber: MDL-81308 +notes: + core: + - message: > + All uses of the following PHPUnit methods have been removed as these + methods are + + deprecated upstream without direct replacement: + + + - `withConsecutive` + + - `willReturnConsecutive` + + - `onConsecutive` + + + Any plugin using these methods must update their uses. + type: changed diff --git a/admin/tool/dataprivacy/tests/expired_contexts_test.php b/admin/tool/dataprivacy/tests/expired_contexts_test.php index daa8cdf4750..ffd5d51a57a 100644 --- a/admin/tool/dataprivacy/tests/expired_contexts_test.php +++ b/admin/tool/dataprivacy/tests/expired_contexts_test.php @@ -1370,12 +1370,20 @@ class expired_contexts_test extends \advanced_testcase { ]) ->getMock(); $mockprivacymanager->expects($this->atLeastOnce())->method('delete_data_for_user'); - $mockprivacymanager->expects($this->exactly(2)) + $deleteinvocations = $this->exactly(2); + $mockprivacymanager->expects($deleteinvocations) ->method('delete_data_for_all_users_in_context') - ->withConsecutive( - [$blockcontext], - [$usercontext] - ); + ->willReturnCallback(function ($context) use ( + $deleteinvocations, + $blockcontext, + $usercontext, + ): void { + match ($deleteinvocations->getInvocationCount()) { + 1 => $this->assertEquals($blockcontext, $context), + 2 => $this->assertEquals($usercontext, $context), + default => $this->fail('Unexpected invocation count'), + }; + }); $manager = $this->getMockBuilder(\tool_dataprivacy\expired_contexts_manager::class) ->onlyMethods(['get_privacy_manager']) @@ -1588,12 +1596,20 @@ class expired_contexts_test extends \advanced_testcase { ]) ->getMock(); $mockprivacymanager->expects($this->atLeastOnce())->method('delete_data_for_user'); - $mockprivacymanager->expects($this->exactly(2)) + $deleteinvocations = $this->exactly(2); + $mockprivacymanager->expects($deleteinvocations) ->method('delete_data_for_all_users_in_context') - ->withConsecutive( - [$blockcontext], - [$usercontext] - ); + ->willReturnCallback(function ($context) use ( + $deleteinvocations, + $blockcontext, + $usercontext, + ): void { + match ($deleteinvocations->getInvocationCount()) { + 1 => $this->assertEquals($blockcontext, $context), + 2 => $this->assertEquals($usercontext, $context), + default => $this->fail('Unexpected invocation count'), + }; + }); $manager = $this->getMockBuilder(\tool_dataprivacy\expired_contexts_manager::class) ->onlyMethods(['get_privacy_manager']) @@ -1641,12 +1657,20 @@ class expired_contexts_test extends \advanced_testcase { ]) ->getMock(); $mockprivacymanager->expects($this->atLeastOnce())->method('delete_data_for_user'); - $mockprivacymanager->expects($this->exactly(2)) + $deleteinvocations = $this->exactly(2); + $mockprivacymanager->expects($deleteinvocations) ->method('delete_data_for_all_users_in_context') - ->withConsecutive( - [$blockcontext], - [$usercontext] - ); + ->willReturnCallback(function ($context) use ( + $deleteinvocations, + $blockcontext, + $usercontext, + ): void { + match ($deleteinvocations->getInvocationCount()) { + 1 => $this->assertEquals($blockcontext, $context), + 2 => $this->assertEquals($usercontext, $context), + default => $this->fail('Unexpected invocation count'), + }; + }); $manager = $this->getMockBuilder(\tool_dataprivacy\expired_contexts_manager::class) ->onlyMethods(['get_privacy_manager']) @@ -1860,12 +1884,20 @@ class expired_contexts_test extends \advanced_testcase { ]) ->getMock(); $mockprivacymanager->expects($this->never())->method('delete_data_for_user'); - $mockprivacymanager->expects($this->exactly(2)) + $deleteinvocations = $this->exactly(2); + $mockprivacymanager->expects($deleteinvocations) ->method('delete_data_for_all_users_in_context') - ->withConsecutive( - [$forumcontext], - [$coursecontext] - ); + ->willReturnCallback(function ($context) use ( + $deleteinvocations, + $forumcontext, + $coursecontext, + ): void { + match ($deleteinvocations->getInvocationCount()) { + 1 => $this->assertEquals($forumcontext, $context), + 2 => $this->assertEquals($coursecontext, $context), + default => $this->fail('Unexpected invocation count'), + }; + }); $manager = $this->getMockBuilder(\tool_dataprivacy\expired_contexts_manager::class) ->onlyMethods(['get_privacy_manager']) diff --git a/admin/tool/langimport/tests/locale_test.php b/admin/tool/langimport/tests/locale_test.php index aab50f7edc3..ad0eed13d77 100644 --- a/admin/tool/langimport/tests/locale_test.php +++ b/admin/tool/langimport/tests/locale_test.php @@ -55,8 +55,14 @@ final class locale_test extends \advanced_testcase { 'set_locale', ]) ->getMock(); - $mock->method('get_locale')->will($this->onConsecutiveCalls('en')); - $mock->method('set_locale')->will($this->onConsecutiveCalls('es', 'en')); + $mock->method('get_locale')->will($this->returnValue('en')); + $setinvocations = $this->exactly(2); + $mock + ->expects($setinvocations) + ->method('set_locale')->willReturnCallback(fn () => match ($setinvocations->getInvocationCount()) { + 1 => 'es', + 2 => 'en', + }); // Test what happen when locale is available on system. $result = $mock->check_locale_availability('en'); @@ -72,8 +78,14 @@ final class locale_test extends \advanced_testcase { 'set_locale', ]) ->getMock(); - $mock->method('get_locale')->will($this->onConsecutiveCalls('en')); - $mock->method('set_locale')->will($this->onConsecutiveCalls(false, 'en')); + $mock->expects($this->exactly(1))->method('get_locale')->will($this->returnValue('en')); + $setinvocations = $this->exactly(2); + $mock + ->expects($setinvocations) + ->method('set_locale')->willReturnCallback(fn () => match ($setinvocations->getInvocationCount()) { + 1 => false, + 2 => 'en', + }); // Test what happen when locale is not available on system. $result = $mock->check_locale_availability('en'); diff --git a/admin/tool/usertours/tests/tour_test.php b/admin/tool/usertours/tests/tour_test.php index 54d0165fa04..ebc27d30702 100644 --- a/admin/tool/usertours/tests/tour_test.php +++ b/admin/tool/usertours/tests/tour_test.php @@ -527,14 +527,30 @@ class tour_test extends \advanced_testcase { // Mock the database. $DB = $this->mock_database(); - $DB->expects($this->exactly(3)) + $deleteinvocations = $this->exactly(3); + $DB->expects($deleteinvocations) ->method('delete_records') - ->withConsecutive( - [$this->equalTo('tool_usertours_tours'), $this->equalTo(['id' => $id])], - [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_LAST_COMPLETED_BY_USER . $id])], - [$this->equalTo('user_preferences'), $this->equalTo(['name' => tour::TOUR_REQUESTED_BY_USER . $id])] - ) - ->willReturn(null); + ->willReturnCallback(function ($table, $conditions) use ($deleteinvocations, $id) { + switch ($deleteinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('tool_usertours_tours', $table); + $this->assertEquals(['id' => $id], $conditions); + return null; + break; + case 2: + $this->assertEquals('user_preferences', $table); + $this->assertEquals(['name' => tour::TOUR_LAST_COMPLETED_BY_USER . $id], $conditions); + return null; + break; + case 3: + $this->assertEquals('user_preferences', $table); + $this->assertEquals(['name' => tour::TOUR_REQUESTED_BY_USER . $id], $conditions); + return null; + break; + default: + $this->fail('Unexpected call to delete_records'); + } + }); $DB->expects($this->once()) ->method('get_records') @@ -554,7 +570,7 @@ class tour_test extends \advanced_testcase { for ($i = 4; $i >= 0; $i--) { $id = rand($i * 10, ($i * 10) + 9); $mockdata[] = (object) ['id' => $id]; - $expectations[] = [$this->equalTo('tool_usertours_steps'), $this->equalTo('sortorder'), 4 - $i, ['id' => $id]]; + $expectations[] = [4 - $i, ['id' => $id]]; } // Mock the database. @@ -563,9 +579,19 @@ class tour_test extends \advanced_testcase { ->method('get_records') ->willReturn($mockdata); - $setfield = $DB->expects($this->exactly(5)) - ->method('set_field'); - call_user_func_array([$setfield, 'withConsecutive'], $expectations); + $setfieldinvocations = $this->exactly(5); + $DB->expects($setfieldinvocations) + ->method('set_field') + ->willReturnCallback(function ($table, $field, $value, $conditions) use ( + $setfieldinvocations, + $expectations, + ): void { + $expectation = $expectations[$setfieldinvocations->getInvocationCount() - 1]; + $this->assertEquals('tool_usertours_steps', $table); + $this->assertEquals('sortorder', $field); + $this->assertEquals($expectation[0], $value); + $this->assertEquals($expectation[1], $conditions); + }); $tour->reset_step_sortorder(); } @@ -764,9 +790,12 @@ class tour_test extends \advanced_testcase { ->getMock(); if ($getconfig) { - $tour->expects($this->exactly(count($getconfig))) + $getinvocations = $this->exactly(count($getconfig)); + $tour->expects($getinvocations) ->method('get_config') - ->will(call_user_func_array([$this, 'onConsecutiveCalls'], $getconfig)); + ->willReturnCallback(function () use ($getinvocations, $getconfig) { + return $getconfig[$getinvocations->getInvocationCount() - 1]; + }); } if ($setconfig) { diff --git a/completion/tests/activity_custom_completion_test.php b/completion/tests/activity_custom_completion_test.php index 07ed75a3fe8..79fc49442ac 100644 --- a/completion/tests/activity_custom_completion_test.php +++ b/completion/tests/activity_custom_completion_test.php @@ -113,13 +113,14 @@ class activity_custom_completion_test extends advanced_testcase { // Mock activity_custom_completion's get_state() method. if ($invokecount > 0) { - $stub->expects($this->exactly($invokecount)) + $stateinvocations = $this->exactly($invokecount); + $stub->expects($stateinvocations) ->method('get_state') - ->withConsecutive( - [$rules[0]], - [$rules[1]] - ) - ->willReturn($rulestates[0], $rulestates[1]); + ->willReturnCallback(function ($rule) use ($stateinvocations, $rules, $rulestates) { + $index = $stateinvocations->getInvocationCount() - 1; + $this->assertEquals($rules[$index], $rule); + return $rulestates[$index]; + }); } else { $stub->expects($this->never()) ->method('get_state'); diff --git a/course/tests/category_hooks_test.php b/course/tests/category_hooks_test.php index 1640e6b4995..a12eb4d92a4 100644 --- a/course/tests/category_hooks_test.php +++ b/course/tests/category_hooks_test.php @@ -186,16 +186,21 @@ class category_hooks_test extends \advanced_testcase { $mockcategory2 = $this->get_mock_category($category2); // Define get_plugins_callback_function use in the mock, it is called twice for different callback in the form. - $mockcategory2->expects($this->exactly(2)) + $callbackinvocations = $this->exactly(2); + $mockcategory2->expects($callbackinvocations) ->method('get_plugins_callback_function') - ->withConsecutive( - [$this->equalTo('can_course_category_delete')], - [$this->equalTo('get_course_category_contents')] - ) - ->willReturn( - ['tool_unittest_can_course_category_delete'], - ['tool_unittest_get_course_category_contents'] - ); + ->willReturnCallback(function ($method) use ($callbackinvocations): array { + switch ($callbackinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('can_course_category_delete', $method); + return ['tool_unittest_can_course_category_delete']; + case 2: + $this->assertEquals('get_course_category_contents', $method); + return ['tool_unittest_get_course_category_contents']; + default: + $this->fail('Unexpected callback invocation'); + } + }); // Now configure fixture to return string for the callback. $content = 'Bunch of test artefacts'; diff --git a/files/tests/converter_test.php b/files/tests/converter_test.php index 94f6209f882..1e866c6762a 100644 --- a/files/tests/converter_test.php +++ b/files/tests/converter_test.php @@ -547,11 +547,14 @@ class converter_test extends advanced_testcase { ]); $converter->method('get_document_converter_classes')->willReturn([]); - $converter->method('get_next_converter') - ->will($this->onConsecutiveCalls( - get_class($converterinstance), - get_class($converterinstance2) - )); + $getinvocations = $this->any(); + $converter + ->expects($getinvocations) + ->method('get_next_converter') + ->willReturnCallback(fn (): string => match ($getinvocations->getInvocationCount()) { + 1 => get_class($converterinstance), + default => get_class($converterinstance2), + }); $file = $this->create_stored_file('example content', 'example', [ 'mimetype' => null, @@ -566,25 +569,31 @@ class converter_test extends advanced_testcase { $conversion->set('status', conversion::STATUS_PENDING); $conversion->create(); - $conversion->method('get_status') - ->will($this->onConsecutiveCalls( + $statusinvocations = $this->atLeast(4); + $conversion + ->expects($statusinvocations) + ->method('get_status') + ->willReturnCallback(fn (): int => match ($statusinvocations->getInvocationCount()) { // Initial status check. - conversion::STATUS_PENDING, + 1 => conversion::STATUS_PENDING, // Second check to make sure it's still pending after polling. - conversion::STATUS_PENDING, + 2 => conversion::STATUS_PENDING, // First one fails. - conversion::STATUS_FAILED, + 3 => conversion::STATUS_FAILED, // Second one succeeds. - conversion::STATUS_COMPLETE, + 4 => conversion::STATUS_COMPLETE, // And the final result checked in this unit test. - conversion::STATUS_COMPLETE - )); + default => conversion::STATUS_COMPLETE, + }); - $conversion->method('get_converter_instance') - ->will($this->onConsecutiveCalls( - $converterinstance, - $converterinstance2 - )); + $instanceinvocations = $this->any(); + $conversion + ->expects($instanceinvocations) + ->method('get_converter_instance') + ->willReturnCallback(fn (): object => match ($instanceinvocations->getInvocationCount()) { + 1 => $converterinstance, + default => $converterinstance2, + }); $converterinstance->expects($this->once()) ->method('start_document_conversion'); diff --git a/lib/filestorage/tests/file_system_test.php b/lib/filestorage/tests/file_system_test.php index a6db36d485d..ecef8f13020 100644 --- a/lib/filestorage/tests/file_system_test.php +++ b/lib/filestorage/tests/file_system_test.php @@ -1218,7 +1218,14 @@ class file_system_test extends \advanced_testcase { ]); $fs->method('is_file_readable_locally_by_hash')->willReturn(false); - $fs->method('get_local_path_from_hash')->will($this->onConsecutiveCalls('/path/to/remote/file', $filepath)); + $getinvocations = $this->exactly(2); + $fs + ->expects($getinvocations) + ->method('get_local_path_from_hash') + ->willReturnCallback(fn () => match ($getinvocations->getInvocationCount()) { + 1 => '/path/to/remote/file', + 2 => $filepath, + }); $file = $this->get_stored_file('example content'); diff --git a/lib/tests/completionlib_test.php b/lib/tests/completionlib_test.php index 77cf230f4c8..6972f59e803 100644 --- a/lib/tests/completionlib_test.php +++ b/lib/tests/completionlib_test.php @@ -247,10 +247,17 @@ class completionlib_test extends advanced_testcase { $c->expects($this->exactly(1)) // Pretend the user has the required capability for overriding completion statuses. ->method('user_can_override_completion') ->will($this->returnValue(true)); - $c->expects($this->exactly(2)) + $getinvocations = $this->exactly(2); + $c->expects($getinvocations) ->method('get_data') ->with($cm, false, 100) - ->willReturnOnConsecutiveCalls($current1, $current2); + ->willReturnCallback(function () use ($getinvocations, $current1, $current2) { + return match ($getinvocations->getInvocationCount()) { + 1 => $current1, + 2 => $current2, + default => $this->fail('Unexpected invocation count'), + }; + }); $changed1 = clone($current1); $changed1->timemodified = time(); $changed1->completionstate = COMPLETION_COMPLETE; @@ -263,12 +270,28 @@ class completionlib_test extends advanced_testcase { $changed2->completionstate = COMPLETION_INCOMPLETE; $comparewith2 = new phpunit_constraint_object_is_equal_with_exceptions($changed2); $comparewith2->add_exception('timemodified', 'assertGreaterThanOrEqual'); - $c->expects($this->exactly(2)) + $setinvocations = $this->exactly(2); + $c->expects($setinvocations) ->method('internal_set_data') - ->withConsecutive( - array($cm, $comparewith1), - array($cm, $comparewith2) - ); + ->willReturnCallback(function ($comparecm, $comparewith) use ( + $setinvocations, + $cm, + $comparewith1, + $comparewith2 + ): void { + switch ($setinvocations->getInvocationCount()) { + case 1: + $this->assertEquals($cm, $comparecm); + $comparewith1->evaluate($comparewith); + break; + case 2: + $this->assertEquals($cm, $comparecm); + $comparewith2->evaluate($comparewith); + break; + default: + $this->fail('Unexpected invocation count'); + } + }); $c->update_state($cm, COMPLETION_COMPLETE, 100, true); // And confirm that the status can be changed back to incomplete without an override. $c->update_state($cm, COMPLETION_INCOMPLETE, 100); @@ -685,13 +708,26 @@ class completionlib_test extends advanced_testcase { (object)array('id' => 100, 'firstname' => 'Woot', 'lastname' => 'Plugh'), (object)array('id' => 201, 'firstname' => 'Vroom', 'lastname' => 'Xyzzy')))); - $c->expects($this->exactly(3)) + $updateinvocations = $this->exactly(3); + $c->expects($updateinvocations) ->method('update_state') - ->withConsecutive( - array($cm, COMPLETION_UNKNOWN, 100), - array($cm, COMPLETION_UNKNOWN, 101), - array($cm, COMPLETION_UNKNOWN, 201) - ); + ->willReturnCallback(function ($comparecm, $state, $userid) use ($updateinvocations, $cm): void { + $this->assertEquals($cm, $comparecm); + $this->assertEquals(COMPLETION_UNKNOWN, $state); + switch ($updateinvocations->getInvocationCount()) { + case 1: + $this->assertEquals(100, $userid); + break; + case 2: + $this->assertEquals(101, $userid); + break; + case 3: + $this->assertEquals(201, $userid); + break; + default: + $this->fail('Unexpected invocation count'); + } + }); $c->reset_all_state($cm); } @@ -1178,20 +1214,31 @@ class completionlib_test extends advanced_testcase { ->method('get_tracked_users') ->with(true, 3, 0, '', '', '', null) ->will($this->returnValue($tracked)); - $DB->expects($this->exactly(2)) + $inorequalsinvocations = $this->exactly(2); + $DB->expects($inorequalsinvocations) ->method('get_in_or_equal') - ->withConsecutive( - array(array_slice($ids, 0, 1000)), - array(array_slice($ids, 1000)) - ) - ->willReturnOnConsecutiveCalls( - array(' IN whatever', array()), - array(' IN whatever2', array())); - $DB->expects($this->exactly(2)) + ->willReturnCallback(function ($paramids) use ($inorequalsinvocations, $ids) { + switch ($inorequalsinvocations->getInvocationCount()) { + case 1: + $this->assertEquals(array_slice($ids, 0, 1000), $paramids); + return [' IN whatever', []]; + case 2: + $this->assertEquals(array_slice($ids, 1000), $paramids); + return [' IN whatever2', []]; + default: + $this->fail('Unexpected invocation count'); + } + }); + $getinvocations = $this->exactly(2); + $DB->expects($getinvocations) ->method('get_recordset_sql') - ->willReturnOnConsecutiveCalls( - new core_completionlib_fake_recordset(array_slice($progress, 0, 1000)), - new core_completionlib_fake_recordset(array_slice($progress, 1000))); + ->willReturnCallback(function () use ($getinvocations, $progress) { + return match ($getinvocations->getInvocationCount()) { + 1 => new core_completionlib_fake_recordset(array_slice($progress, 0, 1000)), + 2 => new core_completionlib_fake_recordset(array_slice($progress, 1000)), + default => $this->fail('Unexpected invocation count'), + }; + }); $result = $c->get_progress_all(true, 3); $resultok = true; diff --git a/lib/tests/content/export/exportable_items/exportable_filearea_test.php b/lib/tests/content/export/exportable_items/exportable_filearea_test.php index d0a71ca124c..f49ca5bedb4 100644 --- a/lib/tests/content/export/exportable_items/exportable_filearea_test.php +++ b/lib/tests/content/export/exportable_items/exportable_filearea_test.php @@ -234,15 +234,18 @@ class exportable_filearea_test extends advanced_testcase { $filepathinzip = $subdir . '/' . $file->get_filearea() . '/' . $file->get_filepath() . $file->get_filename(); $filepathinzip = ltrim(preg_replace('#/+#', '/', $filepathinzip), '/'); $storedfileargs[] = [ - $this->equalTo($context), - $this->equalTo($filepathinzip), - $this->equalTo($file), + $context, + $filepathinzip, + $file, ]; } - $archive->expects($this->exactly(count($expectedfiles))) + $invocations = $this->exactly(count($expectedfiles)); + $archive->expects($invocations) ->method('add_file_from_stored_file') - ->withConsecutive(...$storedfileargs); + ->willReturnCallback(function (...$args) use ($invocations, $storedfileargs) { + $this->assertEquals($storedfileargs[$invocations->getInvocationCount() - 1], $args); + }); return $exportable->add_to_archive($archive); } diff --git a/lib/tests/content/export/exportable_items/exportable_textarea_test.php b/lib/tests/content/export/exportable_items/exportable_textarea_test.php index e3594acf5cc..7a695d6e50c 100644 --- a/lib/tests/content/export/exportable_items/exportable_textarea_test.php +++ b/lib/tests/content/export/exportable_items/exportable_textarea_test.php @@ -320,15 +320,18 @@ EOF; $filepathinzip = dirname($subdir) . $file->get_filearea() . '/' . $file->get_filepath() . $file->get_filename(); $filepathinzip = ltrim(preg_replace('#/+#', '/', $filepathinzip), '/'); $storedfileargs[] = [ - $this->equalTo($context), - $this->equalTo($filepathinzip), - $this->equalTo($file), + $context, + $filepathinzip, + $file, ]; } - $archive->expects($this->exactly(count($expectedfiles))) + $invocations = $this->exactly(count($expectedfiles)); + $archive->expects($invocations) ->method('add_file_from_stored_file') - ->withConsecutive(...$storedfileargs); + ->willReturnCallback(function (...$args) use ($invocations, $storedfileargs) { + $this->assertEquals($storedfileargs[$invocations->getInvocationCount() - 1], $args); + }); $archive->expects($this->never()) ->method('add_file_from_string'); diff --git a/repository/dropbox/tests/api_test.php b/repository/dropbox/tests/api_test.php index 6aec039ce13..7ee672e207b 100644 --- a/repository/dropbox/tests/api_test.php +++ b/repository/dropbox/tests/api_test.php @@ -403,25 +403,37 @@ class api_test extends \advanced_testcase { $endpoint = 'testEndpoint'; - // We can't detect if fetch_dropbox_data was called twice because - // we can' - $mock->expects($this->exactly(3)) + $requestinvocations = $this->exactly(3); + $mock->expects($requestinvocations) ->method('request') - ->will($this->onConsecutiveCalls( - json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['foo', 'bar']]), - json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['baz']]), - json_encode(['has_more' => false, 'cursor' => '', 'matches' => ['bum']]) - )); + ->willReturnCallback(function () use ($requestinvocations): string { + return match ($requestinvocations->getInvocationCount()) { + 1 => json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['foo', 'bar']]), + 2 => json_encode(['has_more' => true, 'cursor' => 'Example', 'matches' => ['baz']]), + 3 => json_encode(['has_more' => false, 'cursor' => '', 'matches' => ['bum']]), + default => $this->fail('Unexpected call to the call() method.'), + }; + }); // We automatically adjust for the /continue endpoint. - $mock->expects($this->exactly(3)) + $apiinvocations = $this->exactly(3); + $mock->expects($apiinvocations) ->method('get_api_endpoint') - ->withConsecutive(['testEndpoint'], ['testEndpoint/continue'], ['testEndpoint/continue']) - ->willReturn($this->onConsecutiveCalls( - 'https://example.com/api/2/testEndpoint', - 'https://example.com/api/2/testEndpoint/continue', - 'https://example.com/api/2/testEndpoint/continue' - )); + ->willReturnCallback(function ($endpoint) use ($apiinvocations): string { + switch ($apiinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('testEndpoint', $endpoint); + return 'https://example.com/api/2/testEndpoint'; + case 2: + $this->assertEquals('testEndpoint/continue', $endpoint); + return 'https://example.com/api/2/testEndpoint/continue'; + case 3: + $this->assertEquals('testEndpoint/continue', $endpoint); + return 'https://example.com/api/2/testEndpoint/continue'; + default: + $this->fail('Unexpected call to the get_api_endpoint() method.'); + } + }); // Make the call. $rc = new \ReflectionClass(\repository_dropbox\dropbox::class); @@ -468,12 +480,21 @@ class api_test extends \advanced_testcase { $mock->expects($this->never()) ->method('get_api_endpoint'); - $mock->expects($this->exactly(2)) + $headerinvocations = $this->exactly(2); + $mock->expects($headerinvocations) ->method('setHeader') - ->withConsecutive( - [$this->equalTo('Content-Type: ')], - [$this->equalTo('Dropbox-API-Arg: ' . json_encode($data))] - ); + ->willReturnCallback(function ($header) use ($data, $headerinvocations): void { + switch ($headerinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('Content-Type: ', $header); + break; + case 2: + $this->assertEquals('Dropbox-API-Arg: ' . json_encode($data), $header); + break; + default: + $this->fail('Unexpected call to the setHeader() method.'); + } + }); // Only one request should be made, and it should forcibly be a POST. $mock->expects($this->once()) @@ -546,21 +567,23 @@ class api_test extends \advanced_testcase { $sharelink = 'https://example.com/share/link'; // Mock fetch_dropbox_data to return an existing file. - $mock->expects($this->exactly(2)) + $fetchinvocations = $this->exactly(2); + $mock->expects($fetchinvocations) ->method('fetch_dropbox_data') - ->withConsecutive( - [$this->equalTo('sharing/list_shared_links'), $this->equalTo(['path' => $id])], - [$this->equalTo('sharing/create_shared_link_with_settings'), $this->equalTo([ - 'path' => $id, - 'settings' => [ - 'requested_visibility' => 'public', - ] - ])] - ) - ->will($this->onConsecutiveCalls( - (object) ['links' => []], - $file - )); + ->willReturnCallback(function ($path, $values) use ($fetchinvocations, $id, $file): object { + switch ($fetchinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('sharing/list_shared_links', $path); + $this->assertEquals(['path' => $id], $values); + return (object) ['links' => []]; + case 2: + $this->assertEquals('sharing/create_shared_link_with_settings', $path); + $this->assertEquals(['path' => $id, 'settings' => ['requested_visibility' => 'public']], $values); + return $file; + default: + $this->fail('Unexpected call to the fetch_dropbox_data() method.'); + } + }); $mock->expects($this->once()) ->method('normalize_file_share_info') @@ -587,19 +610,18 @@ class api_test extends \advanced_testcase { // Mock fetch_dropbox_data to return an existing file. $mock->expects($this->exactly(2)) ->method('fetch_dropbox_data') - ->withConsecutive( - [$this->equalTo('sharing/list_shared_links'), $this->equalTo(['path' => $id])], - [$this->equalTo('sharing/create_shared_link_with_settings'), $this->equalTo([ - 'path' => $id, - 'settings' => [ - 'requested_visibility' => 'public', - ] - ])] - ) - ->will($this->onConsecutiveCalls( - (object) ['links' => []], - null - )); + ->willReturnCallback(function ($path, $values) use ($id): ?object { + switch ($path) { + case 'sharing/list_shared_links': + $this->assertEquals(['path' => $id], $values); + return (object) ['links' => []]; + case 'sharing/create_shared_link_with_settings': + $this->assertEquals(['path' => $id, 'settings' => ['requested_visibility' => 'public']], $values); + return null; + default: + $this->fail('Unexpected call to the fetch_dropbox_data() method.'); + } + }); $mock->expects($this->never()) ->method('normalize_file_share_info'); diff --git a/repository/googledocs/tests/googledocs_search_content_test.php b/repository/googledocs/tests/googledocs_search_content_test.php index e3d807f452f..c39b23abc5c 100644 --- a/repository/googledocs/tests/googledocs_search_content_test.php +++ b/repository/googledocs/tests/googledocs_search_content_test.php @@ -64,28 +64,34 @@ class googledocs_search_content_test extends \googledocs_content_testcase { // instance it is being called to fetch the shared drives (shared_drives_list), while in the second instance // to fetch the relevant drive contents (list) that match the search criteria. Also, define the returned // data objects by these calls. - $servicemock->expects($this->exactly(2)) + $callinvocations = $this->exactly(2); + $servicemock->expects($callinvocations) ->method('call') - ->withConsecutive( - [ - 'shared_drives_list', - [], - ], - [ - 'list', - $searchparams, - ] - ) - ->willReturnOnConsecutiveCalls( - (object)[ - 'kind' => 'drive#driveList', - 'nextPageToken' => 'd838181f30b0f5', - 'drives' => $shareddrives, - ], - (object)[ - 'files' => $searccontents, - ] - ); + ->willReturnCallback(function(string $method, array $params) use ( + $callinvocations, + $shareddrives, + $searccontents, + $searchparams, + ) { + switch ($callinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('shared_drives_list', $method); + + $this->assertEmpty($params); + return (object) [ + 'kind' => 'drive#driveList', + 'nextPageToken' => 'd838181f30b0f5', + 'drives' => $shareddrives, + ]; + case 2: + $this->assertEquals('list', $method); + $this->assertEquals($searchparams, $params); + + return (object) [ + 'files' => $searccontents, + ]; + } + }); // Construct the node path. $path = \repository_googledocs::REPOSITORY_ROOT_ID . '|' . urlencode('Google Drive') . '/' . diff --git a/repository/googledocs/tests/local/browser/googledocs_drive_content_test.php b/repository/googledocs/tests/local/browser/googledocs_drive_content_test.php index a5aa162009f..6a84a2a4994 100644 --- a/repository/googledocs/tests/local/browser/googledocs_drive_content_test.php +++ b/repository/googledocs/tests/local/browser/googledocs_drive_content_test.php @@ -63,28 +63,35 @@ class googledocs_drive_content_test extends \googledocs_content_testcase { // Assert that the call() method is being called twice with the given arguments consecutively. In the first // instance it is being called to fetch the shared drives (shared_drives_list), while in the second instance // to fetch the relevant drive contents (list). Also, define the returned data objects by these calls. - $servicemock->expects($this->exactly(2)) + $callinvocations = $this->exactly(2); + $servicemock->expects($callinvocations) ->method('call') - ->withConsecutive( - [ - 'shared_drives_list', - [], - ], - [ - 'list', - $listparams, - ] - ) - ->willReturnOnConsecutiveCalls( - (object)[ - 'kind' => 'drive#driveList', - 'nextPageToken' => 'd838181f30b0f5', - 'drives' => $shareddrives, - ], - (object)[ - 'files' => $drivecontents, - ] - ); + ->willReturnCallback(function(string $method, array $params) use ( + $callinvocations, + $shareddrives, + $listparams, + $drivecontents, + ) { + switch ($callinvocations->getInvocationCount()) { + case 1: + $this->assertEquals('shared_drives_list', $method); + $this->assertEquals([], $params); + + return (object) [ + 'kind' => 'drive#driveList', + 'nextPageToken' => 'd838181f30b0f5', + 'drives' => $shareddrives, + ]; + case 2: + $this->assertEquals('list', $method); + $this->assertEquals($listparams, $params); + return (object)[ + 'files' => $drivecontents, + ]; + default: + $this->fail('Unexpected call to the call() method.'); + } + }); // Set the disallowed file types (extensions). $this->disallowedextensions = $filterextensions;