Skip to content

Commit

Permalink
MDL-63303 core_favourites: add get and count functions
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanwyllie committed Nov 15, 2018
1 parent c2fc2c2 commit 9e189a9
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 9 deletions.
45 changes: 45 additions & 0 deletions favourites/classes/local/service/user_favourite_service.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,49 @@ public function favourite_exists(string $component, string $itemtype, int $itemi
]
);
}

/**
* Get the favourite.
*
* @param string $component the frankenstyle component name.
* @param string $itemtype the type of the favourited item.
* @param int $itemid the id of the item which was favourited (not the favourite's id).
* @param \context $context the context of the item which was favourited.
* @return favourite|null
*/
public function get_favourite(string $component, string $itemtype, int $itemid, \context $context) {
try {
return $this->repo->find_favourite(
$this->userid,
$component,
$itemtype,
$itemid,
$context->id
);
} catch (\dml_missing_record_exception $e) {
return null;
}
}

/**
* Count the favourite by item type.
*
* @param string $component the frankenstyle component name.
* @param string $itemtype the type of the favourited item.
* @param \context|null $context the context of the item which was favourited.
* @return favourite|null
*/
public function count_favourites_by_type(string $component, string $itemtype, \context $context = null) {
$criteria = [
'userid' => $this->userid,
'component' => $component,
'itemtype' => $itemtype
];

if ($context) {
$criteria['contextid'] = $context->id;
}

return $this->repo->count_by($criteria);
}
}
85 changes: 81 additions & 4 deletions favourites/tests/service_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ protected function get_mock_repository(array $mockstore) {
return $fakerow;
}
}
throw new \moodle_exception("Item not found");
throw new \dml_missing_record_exception("Item not found");
})
);
$mockrepo->expects($this->any())
Expand All @@ -127,16 +127,17 @@ protected function get_mock_repository(array $mockstore) {
})
);
$mockrepo->expects($this->any())
->method('exists_by')
->method('count_by')
->will($this->returnCallback(function(array $criteria) use (&$mockstore) {
$count = 0;
// Check the mockstore for all objects with properties matching the key => val pairs in $criteria.
foreach ($mockstore as $index => $mockrow) {
$mockrowarr = (array)$mockrow;
if (array_diff($criteria, $mockrowarr) == []) {
return true;
$count++;
}
}
return false;
return $count;
})
);
$mockrepo->expects($this->any())
Expand All @@ -149,6 +150,19 @@ protected function get_mock_repository(array $mockstore) {
}
})
);
$mockrepo->expects($this->any())
->method('exists_by')
->will($this->returnCallback(function(array $criteria) use (&$mockstore) {
// Check the mockstore for all objects with properties matching the key => val pairs in $criteria.
foreach ($mockstore as $index => $mockrow) {
$mockrowarr = (array)$mockrow;
if (array_diff($criteria, $mockrowarr) == []) {
return true;
}
}
return false;
})
);
return $mockrepo;
}

Expand Down Expand Up @@ -352,4 +366,67 @@ public function test_favourite_exists() {
)
);
}

/**
* Test confirming the behaviour of the get_favourite() method.
*/
public function test_get_favourite() {
list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses();

// Get a user_favourite_service for the user.
$repo = $this->get_mock_repository([]);
$service = new \core_favourites\local\service\user_favourite_service($user1context, $repo);

// Favourite a course.
$fav1 = $service->create_favourite('core_course', 'course', $course1context->instanceid, $course1context);

$result = $service->get_favourite(
'core_course',
'course',
$course1context->instanceid,
$course1context
);
// Verify we can get the favourite.
$this->assertEquals($fav1->id, $result->id);

// And one that we know doesn't exist.
$this->assertNull(
$service->get_favourite(
'core_course',
'someothertype',
$course1context->instanceid,
$course1context
)
);
}

/**
* Test confirming the behaviour of the count_favourites_by_type() method.
*/
public function test_count_favourites_by_type() {
list($user1context, $user2context, $course1context, $course2context) = $this->setup_users_and_courses();

// Get a user_favourite_service for the user.
$repo = $this->get_mock_repository([]);
$service = new \core_favourites\local\service\user_favourite_service($user1context, $repo);

$this->assertEquals(0, $service->count_favourites_by_type('core_course', 'course', $course1context));
// Favourite a course.
$service->create_favourite('core_course', 'course', $course1context->instanceid, $course1context);

$this->assertEquals(1, $service->count_favourites_by_type('core_course', 'course', $course1context));

// Favourite another course.
$service->create_favourite('core_course', 'course', $course2context->instanceid, $course1context);

$this->assertEquals(2, $service->count_favourites_by_type('core_course', 'course', $course1context));

// Favourite a course in another context.
$service->create_favourite('core_course', 'course', $course2context->instanceid, $course2context);

// Doesn't affect original context.
$this->assertEquals(2, $service->count_favourites_by_type('core_course', 'course', $course1context));
// Gets counted if we include all contexts.
$this->assertEquals(3, $service->count_favourites_by_type('core_course', 'course'));
}
}
2 changes: 2 additions & 0 deletions lib/db/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,7 @@
'classpath' => 'message/externallib.php',
'description' => 'Mark a conversation or group of conversations as favourites/starred conversations.',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_message_unset_favourite_conversations' => array(
Expand All @@ -1265,6 +1266,7 @@
'classpath' => 'message/externallib.php',
'description' => 'Unset a conversation or group of conversations as favourites/starred conversations.',
'type' => 'write',
'ajax' => true,
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
'core_notes_create_notes' => array(
Expand Down
7 changes: 6 additions & 1 deletion message/classes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -813,8 +813,13 @@ public static function set_favourite_conversation(int $conversationid, int $user
if (!self::is_user_in_conversation($userid, $conversationid)) {
throw new \moodle_exception("Conversation doesn't exist or user is not a member");
}
$systemcontext = \context_system::instance();
$ufservice = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($userid));
return $ufservice->create_favourite('core_message', 'message_conversations', $conversationid, \context_system::instance());
if ($favourite = $ufservice->get_favourite('core_message', 'message_conversations', $conversationid, $systemcontext)) {
return $favourite;
} else {
return $ufservice->create_favourite('core_message', 'message_conversations', $conversationid, $systemcontext);
}
}

/**
Expand Down
8 changes: 4 additions & 4 deletions message/tests/api_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -950,17 +950,17 @@ public function test_set_favourite_conversation() {

// Favourite the first conversation as user 1.
$conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
\core_message\api::set_favourite_conversation($conversationid1, $user1->id);
$favourite = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);

// Verify we have a single favourite conversation a user 1.
$this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));

// Verify we have no favourites as user2, despite being a member in that conversation.
$this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));

// Try to favourite the same conversation again.
$this->expectException(\moodle_exception::class);
\core_message\api::set_favourite_conversation($conversationid1, $user1->id);
// Try to favourite the same conversation again should just return the existing favourite.
$repeatresult = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
$this->assertEquals($favourite->id, $repeatresult->id);
}

/**
Expand Down

0 comments on commit 9e189a9

Please sign in to comment.