From 4c15e4a0b73718b7109596b7c09d7da3cb093f73 Mon Sep 17 00:00:00 2001 From: Stephan Robotta Date: Fri, 20 Dec 2024 15:34:38 +0100 Subject: [PATCH] Adjust code issues and unit tests for font class. --- classes/api.php | 2 +- classes/model/report.php | 2 - .../model/report_criterion_view_model.php | 2 + classes/service/report_service.php | 2 +- classes/utils/font.php | 22 +- report_download.php | 2 +- templates/report_download.mustache | 12 + tests/font_test.php | 208 ++++++++++++++++++ 8 files changed, 235 insertions(+), 17 deletions(-) create mode 100644 tests/font_test.php diff --git a/classes/api.php b/classes/api.php index c2e5002..bdc313e 100644 --- a/classes/api.php +++ b/classes/api.php @@ -87,7 +87,7 @@ public static function get_instance($verbalfeedbackid) { global $DB; $id = (int)$verbalfeedbackid; - if (!array_key_exists($id, static::$instances) && !PHPUNIT_TEST) { + if (!array_key_exists($id, static::$instances) || PHPUNIT_TEST) { static::$instances[$id] = $DB->get_record(tables::INSTANCE_TABLE, ['id' => $id], '*', MUST_EXIST); } return static::$instances[$id]; diff --git a/classes/model/report.php b/classes/model/report.php index 745b04d..75aac0a 100644 --- a/classes/model/report.php +++ b/classes/model/report.php @@ -23,8 +23,6 @@ */ namespace mod_verbalfeedback\model; -use mod_verbalfeedback\utils\instance_utils; - /** * The report class */ diff --git a/classes/output/model/report_criterion_view_model.php b/classes/output/model/report_criterion_view_model.php index 688a971..4bdea79 100644 --- a/classes/output/model/report_criterion_view_model.php +++ b/classes/output/model/report_criterion_view_model.php @@ -38,6 +38,8 @@ class report_criterion_view_model { public $averagerating; /** @var string The multiplier */ public $multiplier; + /** @var string[] */ + public $comments; /** * The report criterion view model class constructor diff --git a/classes/service/report_service.php b/classes/service/report_service.php index 142ebef..bb3f057 100644 --- a/classes/service/report_service.php +++ b/classes/service/report_service.php @@ -53,7 +53,7 @@ public function __construct() { * * @param int $instanceid The instance id. * @param int $touserid The user id of the participant for which the report shall be created. - * @return int The id of the submission. + * @return report The report model of the submission. * @throws dml_exception A DML specific exception is thrown for any errors. */ public function create_report(int $instanceid, int $touserid): report { diff --git a/classes/utils/font.php b/classes/utils/font.php index 8f5b5bf..14eb3ae 100644 --- a/classes/utils/font.php +++ b/classes/utils/font.php @@ -24,6 +24,7 @@ namespace mod_verbalfeedback\utils; +use mod_verbalfeedback\model\report; /** @@ -49,8 +50,6 @@ class font { /** @var object The report object. */ protected $report; - /** @var object The user object where the report is printed for. */ - protected $touser; /** @var string The selected font for the entire document. */ protected $font_base; @@ -62,12 +61,10 @@ class font { /** * Constructor. * - * @param object $course The report object. - * @param object $touser The user object where the report is printed for. + * @param report $course The report object. */ - public function __construct($report, $touser) { + public function __construct(report $report) { $this->report = $report; - $this->touser = $touser; } /** @@ -98,8 +95,9 @@ public function get_font_base() { */ public function get_font_student() { if (!$this->font_student) { - $font = $this->eval_string(fullname($this->touser)); - $this->font_student = $font === static::FONT_BASE ? 'inherit' : $font; + $touser = \core_user::get_user($this->report->get_to_user_id()); + $font = $this->eval_string(fullname($touser)); + $this->font_student = $font === $this->get_font_base() ? 'inherit' : $font; } return $this->font_student; } @@ -115,7 +113,7 @@ public function get_font_teacher() { foreach ($this->report->get_from_user_ids() as $fromuserid) { $fromuser = \core_user::get_user($fromuserid); $font = $this->eval_string(fullname($fromuser)); - $this->font_teacher = $font === static::FONT_BASE ? 'inherit' : $font; + $this->font_teacher = $font === $this->get_font_base() ? 'inherit' : $font; break; } } @@ -155,10 +153,10 @@ public function set_font_for_pdf(\pdf $pdf) { global $CFG; $toload = [$this->get_font_base()]; - if ($this->get_font_student() !== 'inherit' && $this->get_font_student() !== $this->get_font_base()) { + if ($this->get_font_student() !== 'inherit') { $toload[] = $this->get_font_student(); } - if ($this->get_font_teacher() !== 'inherit' && $this->get_font_teacher() !== $this->get_font_base()) { + if ($this->get_font_teacher() !== 'inherit') { $toload[] = $this->get_font_teacher(); } foreach ($toload as $font) { @@ -182,7 +180,7 @@ public function set_font_for_pdf(\pdf $pdf) { } /** - * Helper function to set the font for the PDF that only has regular and bold. + * Helper function to set the font for the PDF that only supports regular and bold style. * * @param \pdf $pdf The pdf object. * @param string $name The name of the font. diff --git a/report_download.php b/report_download.php index ebfcc08..a7a9e9d 100644 --- a/report_download.php +++ b/report_download.php @@ -81,7 +81,7 @@ $reportservice = new report_service(); $report = $reportservice->create_report($instanceid, $touserid); -$fonthandler = new font($report, $touser); +$fonthandler = new font($report); $templatedata = new mod_verbalfeedback\output\report_download($report, $course->fullname, $course->startdate, $course->enddate, $instancename, $touser, $fonthandler); diff --git a/templates/report_download.mustache b/templates/report_download.mustache index 9668783..1a89ffd 100644 --- a/templates/report_download.mustache +++ b/templates/report_download.mustache @@ -32,6 +32,18 @@ Example context (json): { + "lang": "en", + "coursestart": 1734704760, + "courseend": 0, + "instancename": "Test Verbal Feedback", + "teachers": "John Doe", + "student": "Mel Foo", + "font_base": "Noto_Sans", + "font_student": "inherit", + "font_teacher": "inherit", + "report": [ + "categories": [] + ] } }} diff --git a/tests/font_test.php b/tests/font_test.php new file mode 100644 index 0000000..8a171d1 --- /dev/null +++ b/tests/font_test.php @@ -0,0 +1,208 @@ +. + +namespace mod_verbalfeedback; + +use mod_verbalfeedback\api; +use mod_verbalfeedback\repository\submission_repository; +use mod_verbalfeedback\service\report_service; +use mod_verbalfeedback\utils\font; +use pdf; + +/** + * Unit tests for classes/font.php + * + * @package mod_verbalfeedback + * @copyright 2024 Stephan Robotta + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class font_test extends \advanced_testcase { + + /** @var stdClass */ + protected $course; + /** @var array */ + protected $students; + /** @var stdClass the verval feedback course module. */ + protected $cm; + + /** + * Setup verbalfeedback. + */ + public function setUp(): void { + $category = $this->getDataGenerator()->create_category(); + $this->course = $this->getDataGenerator()->create_course(['category' => $category->id]); + $this->cm = $this->getDataGenerator()->create_module('verbalfeedback', ['course' => $this->course->id]); + + $this->students = []; + foreach ($this->getStudents() as $name) { + $this->students[] = $this->getDataGenerator()->create_and_enrol($this->course, 'student', $name); + } + } + + /** + * Get teachers with different names. + * + * @return array + */ + protected function getTeachers(): array { + return [ + ['firstname' => 'John', 'lastname' => 'White'], + ['firstname' => 'Eliška', 'lastname' => 'Němcová'], + ['firstname' => 'Даниил', 'lastname' => 'Кузнецов'], + ['firstname' => 'פרס', 'lastname' => 'שמעון'], + ['firstname' => 'اللطيف رشيد', 'lastname' => 'عبد'], + ['firstname' => '拓海', 'lastname' => '田中'], + ['firstname' => 'さくら', 'lastname' => '伊藤'], + ]; + } + + /** + * Get students with different names. + * + * @return array + */ + protected function getStudents(): array { + return [ + ['firstname' => 'John', 'lastname' => 'Doe'], + ['firstname' => 'Matěj', 'lastname' => 'Černý'], + ['firstname' => 'Albrecht', 'lastname' => 'Dürer'], + ['firstname' => 'محمد', 'lastname' => 'علي'], + ['firstname' => 'מאיר', 'lastname' => 'גולדה'], + ['firstname' => 'Артем', 'lastname' => 'Иванов'], + ['firstname' => '羽', 'lastname' => '周'], + ['firstname' => '美玲', 'lastname' => '王'], + ['firstname' => 'さくら', 'lastname' => '小林'], + ]; + } + + /** + * Test get_font_base(). + * + * @covers font::get_font_base + */ + public function test_get_font_base() { + global $SESSION; + + $this->resetAfterTest(); + $reportservice = new report_service(); + + $tests = [ + ['lang' => 'en', 'expected' => font::FONT_BASE], + ['lang' => 'ar', 'expected' => font::FONT_ARABIC], + ['lang' => 'he', 'expected' => font::FONT_HEBREW], + ['lang' => 'ja', 'expected' => font::FONT_JAPANESE], + ['lang' => 'zh', 'expected' => font::FONT_CHINESE], + ['lang' => 'fr_ca', 'expected' => font::FONT_BASE], + ['lang' => 'zh_tw_wp', 'expected' => font::FONT_CHINESE], + ]; + foreach ($tests as $test) { + $SESSION->forcelang = $test['lang']; + $report = $reportservice->create_report($this->cm->id, $this->students[0]->id); + $font = new font($report); + $this->assertEquals($test['expected'], $font->get_font_base(), "Font for language {$test['lang']} is not {$test['expected']}."); + } + } + + /** + * Test get_font_student(). + * + * @covers font::get_font_student + */ + public function test_get_font_student() { + $this->getDataGenerator()->create_and_enrol($this->course, 'editingteacher', $this->getTeachers()[0]); + $this->resetAfterTest(); + $expected = [ + 'inherit', + 'inherit', + 'inherit', + font::FONT_ARABIC, + font::FONT_HEBREW, + 'inherit', + font::FONT_CHINESE, + font::FONT_CHINESE, + font::FONT_JAPANESE, + ]; + foreach ($this->students as $key => $student) { + $reportservice = new report_service(); + $report = $reportservice->create_report($this->cm->id, $student->id); + $font = new font($report); + $this->assertEquals($expected[$key], $font->get_font_student(), "Font for student {$key} is not {$expected[$key]}."); + } + } + + /** + * Test get_font_teacher. + * + * @covers font::get_font_teacher + */ + public function test_get_font_teacher() { + $this->resetAfterTest(); + $expected = [ + 'inherit', + 'inherit', + 'inherit', + font::FONT_HEBREW, + font::FONT_ARABIC, + font::FONT_CHINESE, + font::FONT_JAPANESE, + ]; + $enroledTeachers = []; + foreach ($this->getTeachers() as $key => $teacher) { + $enroledTeachers[] = $this->getDataGenerator()->create_and_enrol($this->course, 'editingteacher', $teacher); + api::generate_verbalfeedback_feedback_states($this->cm->id, $enroledTeachers[$key]->id); + $reportservice = new report_service(); + $report = $reportservice->create_report($this->cm->id, $this->students[0]->id); + $font = new font($report); + // Because looking at the first teacher only, the result here is always the same. + $this->assertEquals('inherit', $font->get_font_teacher(), "Font for teacher {$key} is not inherit."); + } + // Now delete all submissions skeletons from teachers. + (new submission_repository())->delete_by_instance($this->cm->id); + + foreach ($this->getTeachers() as $key => $teacher) { + api::generate_verbalfeedback_feedback_states($this->cm->id, $enroledTeachers[$key]->id); + $reportservice = new report_service(); + $report = $reportservice->create_report($this->cm->id, $this->students[3]->id); + $font = new font($report); + $this->assertEquals($expected[$key], $font->get_font_teacher(), "Did not get font {$expected[$key]} for teacher {$key}."); + // Remove submission skeletons by current teacher. + (new submission_repository())->delete_by_instance($this->cm->id); + } + } + + /** + * Test set_font_for_pdf. + * + * @covers font::set_font_for_pdf + */ + public function test_set_font_for_pdf() { + global $CFG; + + require_once($CFG->libdir . '/pdflib.php'); + + $this->resetAfterTest(); + + foreach ($this->students as $student) { + $pdf = new pdf(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); + $font = new font((new report_service())->create_report($this->cm->id, $student->id)); + $font->set_font_for_pdf($pdf); + $charfist = mb_substr($student->firstname, 0, 1); + $charlast = mb_substr($student->lastname, 0, 1); + $this->assertTrue($pdf->isCharDefined($charfist), "char $charfist not defined"); + $this->assertTrue($pdf->isCharDefined($charlast), "char $charlast not defined"); + } + } +} \ No newline at end of file