Skip to content

Commit

Permalink
add course_category_manager.php (create course cat and assign role to…
Browse files Browse the repository at this point in the history
… user on that cat)
  • Loading branch information
Glutamat42 committed Apr 2, 2024
1 parent 4d860ba commit b9140bf
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 0 deletions.
47 changes: 47 additions & 0 deletions classes/local/course_category_manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace local_adler\local;

use local_adler\local\db\moodle_core_repository;
use local_adler\moodle_core;
use moodle_exception;

class course_category_manager {
public static function create_category_user_can_create_courses_in(string $username, string $role, string|null $category_path = Null) {
$moodle_core_repository = new moodle_core_repository();

// handle category path (default value and parsing)
if ($category_path === Null || strlen($category_path) === 0) {
$category_path = "adler/{$username}";
}
$category_path = new course_category_path($category_path);


// validate input
if (!$moodle_core_repository->get_user_id_by_username($username)) {
throw new moodle_exception('user_not_found', 'local_adler');
}
if (!$moodle_core_repository->get_role_id_by_shortname($role)) {
throw new moodle_exception('role_not_found', 'local_adler');
}
if ($category_path->exists()) {
throw new moodle_exception('category_already_exists', 'local_adler');
}


// create category and assign user to role
$category_id = $category_path->create();
self::assign_user_to_role_in_category($username, $role, $category_id);

return $category_id;
}

private static function assign_user_to_role_in_category(string $username, string $role, int $category_id) {
$moodle_core_repository = new moodle_core_repository();

$user_id = $moodle_core_repository->get_user_id_by_username($username);
$role_id = $moodle_core_repository->get_role_id_by_shortname($role);
$context = moodle_core::context_coursecat_instance($category_id);
moodle_core::role_assign($role_id, $user_id, $context->id);
}
}
16 changes: 16 additions & 0 deletions classes/local/db/base_repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace local_adler\local\db;

abstract class base_repository {
protected $db;

public function __construct($db = null) {
if (is_null($db)) {
global $DB;
$this->db = $DB;
} else {
$this->db = $db;
}
}
}
16 changes: 16 additions & 0 deletions classes/local/db/moodle_core_repository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace local_adler\local\db;


class moodle_core_repository extends base_repository {
public function get_role_id_by_shortname(string $shortname): int {
global $DB;
return (int)$DB->get_field('role', 'id', array('shortname' => $shortname));
}

public function get_user_id_by_username(string $username): int {
global $DB;
return (int)$DB->get_field('user', 'id', array('username' => $username));
}
}
19 changes: 19 additions & 0 deletions classes/moodle_core.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace local_adler;

use context_coursecat;

/**
* This class contains aliases for moodle core functions to allow mocking them.
*/
class moodle_core {
public static function role_assign(...$args): int {
return role_assign(...$args);
}

/** alias for context_coursecat::instance */
public static function context_coursecat_instance(...$args): object {
return context_coursecat::instance(...$args);
}
}
95 changes: 95 additions & 0 deletions tests/local/course_category_manager_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace local_adler\local;

use context_coursecat;
use local_adler\lib\adler_testcase;
use local_adler\local\db\moodle_core_repository;
use local_adler\moodle_core;
use Mockery;
use moodle_exception;

global $CFG;
require_once($CFG->dirroot . '/local/adler/tests/lib/adler_testcase.php');

/**
* @runTestsInSeparateProcesses
*/
class course_category_manager_test extends adler_testcase {
private $mockRepo;

public function setUp(): void {
$this->mockRepo = Mockery::mock('overload:' . moodle_core_repository::class);
}

public function test_username_doesnt_exist() {
// Arrange
$this->mockRepo->shouldReceive('get_user_id_by_username')->andReturn(false);

// Act and Assert
$this->expectException(moodle_exception::class);
$this->expectExceptionMessage('user_not_found');
course_category_manager::create_category_user_can_create_courses_in('non_existing_username', 'role', 'category_path');
}

public function test_role_doesnt_exist() {
// Arrange
$this->mockRepo->shouldReceive('get_user_id_by_username')->andReturn(1); // return a valid user ID
$this->mockRepo->shouldReceive('get_role_id_by_shortname')->andReturn(false);

// Act and Assert
$this->expectException(moodle_exception::class);
$this->expectExceptionMessage('role_not_found');
course_category_manager::create_category_user_can_create_courses_in('username', 'non_existing_role', 'category_path');
}

public function test_category_already_exists() {
// Arrange
$this->mockRepo->shouldReceive('get_user_id_by_username')->andReturn(1); // return a valid user ID
$this->mockRepo->shouldReceive('get_role_id_by_shortname')->andReturn(1); // return a valid role ID

$mockPath = Mockery::mock('overload:local_adler\local\course_category_path');
$mockPath->shouldReceive('exists')->andReturn(true);

// Act and Assert
$this->expectException(moodle_exception::class);
$this->expectExceptionMessage('category_already_exists');
course_category_manager::create_category_user_can_create_courses_in('valid_username', 'valid_role', 'existing_category_path');
}

/**
* @dataProvider providerTestValidUsernameRoleAndCategoryPath
*/
public function test_valid_username_role_and_category_path($category_path, $expected_result) {
// Arrange
$this->mockRepo->shouldReceive('get_user_id_by_username')->andReturn(1); // return a valid user ID
$this->mockRepo->shouldReceive('get_role_id_by_shortname')->andReturn(1); // return a valid role ID

$mockPath = Mockery::mock('overload:' . course_category_path::class);
$mockPath->shouldReceive('exists')->andReturn(false);
$mockPath->shouldReceive('create')->andReturn(42);

$moodle_core_mock = Mockery::mock('alias:' . moodle_core::class)
->shouldReceive('context_coursecat_instance')
->andReturn(Mockery::mock(context_coursecat::class));

$moodle_core_mock
->shouldReceive('role_assign')
->withArgs([1, 1, null])
->andReturn(true);

// Act
$result = course_category_manager::create_category_user_can_create_courses_in('valid_username', 'valid_role', $category_path);

// Assert
$this->assertEquals($expected_result, $result);
}

public function providerTestValidUsernameRoleAndCategoryPath() {
return [
'null category path' => [null, 42],
'empty category path' => ['', 42],
'non-existing category path' => ['non_existing_category_path', 42]
];
}
}

0 comments on commit b9140bf

Please sign in to comment.