*/ declare(strict_types = 1); use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Medium; use PHPUnit\Framework\Attributes\DataProvider; require_once __DIR__ . '/../../MDMysqli/test_connections.conf.php'; require_once __DIR__ . '/../src/NodaWikidataFetcherDisambiguationIsDisallowedException.php'; /** * This script contains tests for the Wikidata fetcher. */ #[medium] #[CoversClass(\NodaWikidataFetcher::class)] final class NodaWikidataFetcherTest extends TestCase { // Test for getting translations: Telugu public const TEST_LANG = 'te'; /** * Test to check whether the HTML page is correctly generated. * * @author Joshua Ramon Enslin * @group ValidOutput * * @return void */ public function testWikidataIdFromLink():void { self::assertEquals(NodaWikidataFetcher::getWikidataIdFromLink("https://www.wikidata.org/wiki/Q106697"), 'Q106697'); self::assertEquals(NodaWikidataFetcher::getWikidataIdFromLink("https://de.wikipedia.org/wiki/Fedor_Jagor"), 'Q106697'); } /** * Data provider providing a Wikidata ID for a dedicated wikidata item for disambiguation pages. * * @return array */ public static function disambiguationPageProvider():array { return [ 'Disambiguation page for "Mochi" - Q6916210' => ['Q6916210'], ]; } /** * Throw error when attempting to load a dedicated wikidata entry for a disambiguation page. * * @param string $wikidata_id Wikidata ID. * * @return void */ #[DataProvider('disambiguationPageProvider')] public function testWikidataIdFromLinkFailsForDisambiguationPages(string $wikidata_id):void { self::expectException(NodaWikidataFetcherDisambiguationIsDisallowedException::class); NodaWikidataFetcher::getWikidataEntity($wikidata_id); } /** * Test to check whether the HTML page is correctly generated. * * @author Joshua Ramon Enslin * @group ValidOutput * * @return void */ public function testWikidataIdFromWikipediaRequiresWikipediaLink():void { self::assertEquals(NodaWikidataFetcher::getWikidataIdFromWikipedia("https://en.about.museum-digital.org/"), ''); } /** * Test to check whether the HTML page is correctly generated. * * @group ValidOutput * * @return void */ public function testCanGetWikidataIdByWikidataId():void { self::assertEquals(NodaWikidataFetcher::getWikidataIdFromWikidataLink("https://www.wikidata.org/wiki/Q106697"), "Q106697"); } /** * Data provider for an actor that has a wikidata link and a Telugu translation. * * @return array */ public static function actorWithTlAndWikidataLinkProvider():array { $mysqli = md_main_mysqli_connect(); $result = $mysqli->do_read_query("SELECT `persinst_id`, `noda_nrinsource` FROM `" . DATABASENAME_NODA . "`.`noda` WHERE `noda_source` = 'Wikidata' AND EXISTS (SELECT 1 FROM `" . DATABASENAME_NODA . "`.`persinst_translation` WHERE `persinst_translation`.`persinst_id` = `noda`.`persinst_id` AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "')"); if (!$cur = $result->fetch_row()) { throw new Exception("Failed to identify an entry that has a wikidata entry and a translation for language " . self::TEST_LANG); } $result->close(); $mysqli->close(); return [ 'Actor with wikidata and translation' => [$cur[0], $cur[1]], ]; } /** * Data provider for a place that has a wikidata link and a Telugu translation. * * @return array */ public static function placeWithTlAndWikidataLinkProvider():array { $mysqli = md_main_mysqli_connect(); $result = $mysqli->do_read_query("SELECT `ort_id`, `noda_nrinsource` FROM `" . DATABASENAME_NODA . "`.`noda_orte` WHERE `noda_source` = 'Wikidata' AND EXISTS (SELECT 1 FROM `" . DATABASENAME_NODA . "`.`ort_translation` WHERE `ort_translation`.`ort_id` = `noda_orte`.`ort_id` AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "')"); if (!$cur = $result->fetch_row()) { throw new Exception("Failed to identify an entry that has a wikidata entry and a translation for language " . self::TEST_LANG); } $result->close(); $mysqli->close(); return [ 'Place with wikidata and translation' => [$cur[0], $cur[1]], ]; } /** * Data provider for an tag that has a wikidata link and a Telugu translation. * * @return array */ public static function tagWithTlAndWikidataLinkProvider():array { $mysqli = md_main_mysqli_connect(); $result = $mysqli->do_read_query("SELECT `tag_id`, `noda_nrinsource` FROM `" . DATABASENAME_NODA . "`.`noda_tag` WHERE `noda_source` = 'Wikidata' AND EXISTS (SELECT 1 FROM `" . DATABASENAME_NODA . "`.`tag_translation` WHERE `tag_translation`.`tag_id` = `noda_tag`.`tag_id` AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "')"); if (!$cur = $result->fetch_row()) { throw new Exception("Failed to identify an entry that has a wikidata entry and a translation for language " . self::TEST_LANG); } $result->close(); $mysqli->close(); return [ 'Tag with wikidata and translation' => [$cur[0], $cur[1]], ]; } /** * Test for fetching and recording translations for an actor. * * @param integer $actor_id Actor ID. * @param string $wikidata_id Wikidata ID. * * @return void */ #[DataProvider('actorWithTlAndWikidataLinkProvider')] public function testFetchingTranslationForPersinst(int $actor_id, string $wikidata_id):void { $mysqli = md_main_mysqli_connect(); $mysqli->do_update_query("DELETE FROM `" . DATABASENAME_NODA . "`.`persinst_translation` WHERE `persinst_id` = " . $actor_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'"); self::assertEquals(0, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`persinst_translation` WHERE `persinst_id` = " . $actor_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $data = NodaWikidataFetcher::getWikidataEntity($wikidata_id); $fetcher = new NodaWikidataFetcher($mysqli); $fetcher->getWikidataTranslationsForPersinst($data, $actor_id, [self::TEST_LANG]); self::assertEquals(1, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`persinst_translation` WHERE `persinst_id` = " . $actor_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $mysqli->close(); } /** * Test for fetching and recording translations for an place. * * @param integer $place_id Place ID. * @param string $wikidata_id Wikidata ID. * * @return void */ #[DataProvider('placeWithTlAndWikidataLinkProvider')] public function testFetchingTranslationForPlace(int $place_id, string $wikidata_id):void { $mysqli = md_main_mysqli_connect(); $mysqli->do_update_query("DELETE FROM `" . DATABASENAME_NODA . "`.`ort_translation` WHERE `ort_id` = " . $place_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'"); self::assertEquals(0, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`ort_translation` WHERE `ort_id` = " . $place_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $data = NodaWikidataFetcher::getWikidataEntity($wikidata_id); $fetcher = new NodaWikidataFetcher($mysqli); $fetcher->getWikidataTranslationsForPlace($data, $place_id, [self::TEST_LANG]); self::assertEquals(1, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`ort_translation` WHERE `ort_id` = " . $place_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $mysqli->close(); } /** * Test for fetching and recording translations for an tag. * * @param integer $tag_id Tag ID. * @param string $wikidata_id Wikidata ID. * * @return void */ #[DataProvider('tagWithTlAndWikidataLinkProvider')] public function testFetchingTranslationForTag(int $tag_id, string $wikidata_id):void { $mysqli = md_main_mysqli_connect(); $mysqli->do_update_query("DELETE FROM `" . DATABASENAME_NODA . "`.`tag_translation` WHERE `tag_id` = " . $tag_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'"); self::assertEquals(0, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`tag_translation` WHERE `tag_id` = " . $tag_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $data = NodaWikidataFetcher::getWikidataEntity($wikidata_id); $fetcher = new NodaWikidataFetcher($mysqli); $fetcher->getWikidataTranslationsForTag($data, $tag_id, [self::TEST_LANG]); self::assertEquals(1, MDMysqliTesting::queryNumRows($mysqli, " FROM `" . DATABASENAME_NODA . "`.`tag_translation` WHERE `tag_id` = " . $tag_id . " AND `trans_language` = '" . $mysqli->escape_string(self::TEST_LANG) . "'")); $mysqli->close(); } /** * Test that fetching translation from Wikidata returns the title of the wikipedia page, * not the wikidata title. * * @return void */ public function testListTranslationsFromWikidataWikipediaReturnsWikipediaTitle():void { $data = NodaWikidataFetcher::getWikidataEntity("Q33550"); $output = NodaWikidataFetcher::listTranslationsFromWikidataWikipedia(["de"], $data); self::assertNotEmpty($output['de']); self::assertEquals("Friedrich II. (Preußen)", $output['de']['label']); } }