diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e69de29bb..595c34207 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -0,0 +1,6 @@ +parameters: + ignoreErrors: + - + message: "#^Strict comparison using \\=\\=\\= between null and string will always evaluate to false\\.$#" + count: 1 + path: src/ParamConverter/UsernameFeedTokenConverter.php diff --git a/phpstan.neon b/phpstan.neon index ae2046019..ad809211c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,7 +2,7 @@ includes: - phpstan-baseline.neon parameters: - level: 3 + level: 4 paths: - src - tests diff --git a/src/Controller/Api/EntryRestController.php b/src/Controller/Api/EntryRestController.php index a7dac9b07..ae28f236a 100644 --- a/src/Controller/Api/EntryRestController.php +++ b/src/Controller/Api/EntryRestController.php @@ -554,7 +554,7 @@ class EntryRestController extends WallabagRestController $this->entityManager->persist($entry); $this->entityManager->flush(); - $results[$key]['entry'] = $entry instanceof Entry ? $entry->getId() : false; + $results[$key]['entry'] = $entry->getId(); // entry saved, dispatch event about it! $eventDispatcher->dispatch(new EntrySavedEvent($entry), EntrySavedEvent::NAME); @@ -734,7 +734,7 @@ class EntryRestController extends WallabagRestController 'html' => !empty($data['content']) ? $data['content'] : $entry->getContent(), 'url' => $entry->getUrl(), 'language' => !empty($data['language']) ? $data['language'] : $entry->getLanguage(), - 'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt(), + 'date' => !empty($data['publishedAt']) ? $data['publishedAt'] : $entry->getPublishedAt()?->format('Y-m-d H:i:s') ?? '', // faking the open graph preview picture 'image' => !empty($data['picture']) ? $data['picture'] : $entry->getPreviewPicture(), 'authors' => \is_string($data['authors']) ? explode(',', $data['authors']) : $entry->getPublishedBy(), diff --git a/src/Controller/FeedController.php b/src/Controller/FeedController.php index cd5adf24f..3b69d6c47 100644 --- a/src/Controller/FeedController.php +++ b/src/Controller/FeedController.php @@ -125,10 +125,6 @@ class FeedController extends AbstractController $perPage = $user->getConfig()->getFeedLimit() ?: $this->getParameter('wallabag.feed_limit'); $entries->setMaxPerPage($perPage); - if (null === $entries) { - throw $this->createNotFoundException('No entries found?'); - } - try { $entries->setCurrentPage($page); } catch (OutOfRangeCurrentPageException) { diff --git a/src/Controller/Import/PocketController.php b/src/Controller/Import/PocketController.php index 2970f5472..543f867aa 100644 --- a/src/Controller/Import/PocketController.php +++ b/src/Controller/Import/PocketController.php @@ -61,10 +61,10 @@ class PocketController extends AbstractController return $this->redirect($this->generateUrl('import_pocket')); } - $form = $request->request->get('form'); + $form = $request->request->all('form'); $this->session->set('import.pocket.code', $requestToken); - if (null !== $form && \array_key_exists('mark_as_read', $form)) { + if (\array_key_exists('mark_as_read', $form)) { $this->session->set('mark_as_read', $form['mark_as_read']); } diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php index 187fb1f24..8554b26b7 100644 --- a/src/Entity/Entry.php +++ b/src/Entity/Entry.php @@ -3,6 +3,7 @@ namespace Wallabag\Entity; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Hateoas\Configuration\Annotation as Hateoas; use JMS\Serializer\Annotation\Exclude; @@ -233,11 +234,14 @@ class Entry #[Groups(['export_all'])] private $user; + /** + * @var Collection + */ #[ORM\JoinTable(name: 'entry_tag')] #[ORM\JoinColumn(name: 'entry_id', referencedColumnName: 'id', onDelete: 'cascade')] #[ORM\InverseJoinColumn(name: 'tag_id', referencedColumnName: 'id', onDelete: 'cascade')] #[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'entries', cascade: ['persist'])] - private $tags; + private Collection $tags; /* * @param User $user @@ -589,7 +593,7 @@ class Entry } /** - * @return string + * @return string|null */ public function getDomainName() { @@ -597,7 +601,7 @@ class Entry } /** - * @param string $domainName + * @param string|null $domainName */ public function setDomainName($domainName) { @@ -605,7 +609,7 @@ class Entry } /** - * @return ArrayCollection + * @return Collection */ public function getTags() { @@ -696,7 +700,7 @@ class Entry /** * Get previewPicture. * - * @return string + * @return string|null */ public function getPreviewPicture() { @@ -706,7 +710,7 @@ class Entry /** * Set language. * - * @param string $language + * @param string|null $language * * @return Entry */ @@ -720,7 +724,7 @@ class Entry /** * Get language. * - * @return string + * @return string|null */ public function getLanguage() { @@ -808,7 +812,7 @@ class Entry } /** - * @return \DateTimeInterface + * @return \DateTimeInterface|null */ public function getPublishedAt() { diff --git a/src/Entity/Tag.php b/src/Entity/Tag.php index 2de5381b1..94737d759 100644 --- a/src/Entity/Tag.php +++ b/src/Entity/Tag.php @@ -3,6 +3,7 @@ namespace Wallabag\Entity; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; use JMS\Serializer\Annotation\ExclusionPolicy; @@ -41,8 +42,11 @@ class Tag implements \Stringable #[Expose] private $slug; + /** + * @var Collection + */ #[ORM\ManyToMany(targetEntity: Entry::class, mappedBy: 'tags', cascade: ['persist'])] - private $entries; + private Collection $entries; public function __construct() { @@ -121,7 +125,7 @@ class Tag implements \Stringable /** * Get entries for this tag. * - * @return ArrayCollection + * @return Collection */ public function getEntries() { diff --git a/src/Entity/User.php b/src/Entity/User.php index 50fde090a..fc48d8737 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -3,6 +3,7 @@ namespace Wallabag\Entity; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use FOS\UserBundle\Model\User as BaseUser; use JMS\Serializer\Annotation\Accessor; @@ -117,16 +118,16 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI protected $config; /** - * @var ArrayCollection&iterable + * @var Collection */ #[ORM\OneToMany(targetEntity: SiteCredential::class, mappedBy: 'user', cascade: ['remove'])] - protected $siteCredentials; + protected Collection $siteCredentials; /** - * @var ArrayCollection&iterable + * @var Collection */ #[ORM\OneToMany(targetEntity: Client::class, mappedBy: 'user', cascade: ['remove'])] - protected $clients; + protected Collection $clients; /** * @see getFirstClient() below @@ -162,6 +163,8 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI { parent::__construct(); $this->entries = new ArrayCollection(); + $this->siteCredentials = new ArrayCollection(); + $this->clients = new ArrayCollection(); $this->roles = ['ROLE_USER']; } @@ -216,7 +219,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI } /** - * @return ArrayCollection + * @return Collection */ public function getEntries() { @@ -338,13 +341,15 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI */ public function addClient(Client $client) { - $this->clients[] = $client; + if (!$this->clients->contains($client)) { + $this->clients->add($client); + } return $this; } /** - * @return ArrayCollection + * @return Collection */ public function getClients() { @@ -358,7 +363,7 @@ class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorI */ public function getFirstClient() { - if (!empty($this->clients)) { + if (!$this->clients->isEmpty()) { return $this->clients->first(); } diff --git a/src/Event/Subscriber/DownloadImagesSubscriber.php b/src/Event/Subscriber/DownloadImagesSubscriber.php index 5324f449c..2becf355f 100644 --- a/src/Event/Subscriber/DownloadImagesSubscriber.php +++ b/src/Event/Subscriber/DownloadImagesSubscriber.php @@ -79,7 +79,7 @@ class DownloadImagesSubscriber implements EventSubscriberInterface * * @todo If we want to add async download, it should be done in that method * - * @return string|false False in case of async + * @return string */ private function downloadImages(Entry $entry) { diff --git a/src/Form/DataTransformer/StringToListTransformer.php b/src/Form/DataTransformer/StringToListTransformer.php index 32867d76a..148203317 100644 --- a/src/Form/DataTransformer/StringToListTransformer.php +++ b/src/Form/DataTransformer/StringToListTransformer.php @@ -3,6 +3,7 @@ namespace Wallabag\Form\DataTransformer; use Symfony\Component\Form\DataTransformerInterface; +use Symfony\Component\Form\Exception\UnexpectedTypeException; /** * Transforms a comma-separated list to a proper PHP array. @@ -21,8 +22,6 @@ class StringToListTransformer implements DataTransformerInterface /** * Transforms a list to a string. * - * @param array|null $list - * * @return string */ public function transform($list) @@ -31,14 +30,16 @@ class StringToListTransformer implements DataTransformerInterface return ''; } + if (!\is_array($list)) { + throw new UnexpectedTypeException($list, 'array'); + } + return implode($this->separator, $list); } /** * Transforms a string to a list. * - * @param string $string - * * @return array|null */ public function reverseTransform($string) @@ -47,6 +48,10 @@ class StringToListTransformer implements DataTransformerInterface return null; } + if (!\is_string($string)) { + throw new UnexpectedTypeException($string, 'string'); + } + return array_values(array_filter(array_map('trim', explode($this->separator, $string)))); } } diff --git a/src/Helper/ContentProxy.php b/src/Helper/ContentProxy.php index af66abf7f..0533b2cfe 100644 --- a/src/Helper/ContentProxy.php +++ b/src/Helper/ContentProxy.php @@ -143,11 +143,8 @@ class ContentProxy } try { - // is it already a DateTime? // (it's inside the try/catch in case of fail to be parse time string) - if (!$date instanceof \DateTime) { - $date = new \DateTime($date); - } + $date = new \DateTime($date); $entry->setPublishedAt($date); } catch (\Exception $e) { diff --git a/src/Helper/DownloadImages.php b/src/Helper/DownloadImages.php index 156100dc4..e46f8289e 100644 --- a/src/Helper/DownloadImages.php +++ b/src/Helper/DownloadImages.php @@ -98,10 +98,10 @@ class DownloadImages * - re-saved it (for security reason) * - return the new local path. * - * @param int $entryId ID of the entry - * @param string $imagePath Path to the image to retrieve - * @param string $url Url from where the image were found - * @param string $relativePath Relative local path to saved the image + * @param int $entryId ID of the entry + * @param string|null $imagePath Path to the image to retrieve + * @param string $url Url from where the image were found + * @param string $relativePath Relative local path to saved the image * * @return string|false Relative url to access the image from the web */ @@ -136,7 +136,7 @@ class DownloadImages } $ext = $this->getExtensionFromResponse($res, $imagePath); - if (false === $res) { + if (false === $ext) { return false; } diff --git a/src/Helper/Redirect.php b/src/Helper/Redirect.php index 77aec7ab4..7ac2f2fc8 100644 --- a/src/Helper/Redirect.php +++ b/src/Helper/Redirect.php @@ -20,8 +20,8 @@ class Redirect } /** - * @param string $url URL to redirect - * @param bool $ignoreActionMarkAsRead Ignore configured action when mark as read + * @param string|null $url URL to redirect + * @param bool $ignoreActionMarkAsRead Ignore configured action when mark as read * * @return string */ diff --git a/src/Helper/RuleBasedTagger.php b/src/Helper/RuleBasedTagger.php index d40604d50..de5dbea20 100644 --- a/src/Helper/RuleBasedTagger.php +++ b/src/Helper/RuleBasedTagger.php @@ -129,7 +129,8 @@ class RuleBasedTagger private function fixEntry(Entry $entry) { $clonedEntry = clone $entry; - $clonedEntry->setReadingTime($entry->getReadingTime() / $entry->getUser()->getConfig()->getReadingSpeed() * 200); + $newReadingTime = (int) ($entry->getReadingTime() / $entry->getUser()->getConfig()->getReadingSpeed() * 200); + $clonedEntry->setReadingTime($newReadingTime); return $clonedEntry; } diff --git a/src/Import/PinboardImport.php b/src/Import/PinboardImport.php index fa0bcfe3d..d0e78ef42 100644 --- a/src/Import/PinboardImport.php +++ b/src/Import/PinboardImport.php @@ -95,7 +95,7 @@ class PinboardImport extends AbstractImport 'is_archived' => ('no' === $importedEntry['toread']) || $this->markAsRead, 'is_starred' => false, 'created_at' => $importedEntry['time'], - 'tags' => explode(' ', (string) $importedEntry['tags']), + 'tags' => array_filter(explode(' ', (string) $importedEntry['tags'])), ]; $entry = new Entry($this->user); diff --git a/src/Mailer/AuthCodeMailer.php b/src/Mailer/AuthCodeMailer.php index 858ba547f..2626fc369 100644 --- a/src/Mailer/AuthCodeMailer.php +++ b/src/Mailer/AuthCodeMailer.php @@ -52,7 +52,7 @@ class AuthCodeMailer implements AuthCodeMailerInterface ]); $email = (new Email()) - ->from(new Address($this->senderEmail, $this->senderName ?? $this->senderEmail)) + ->from(new Address($this->senderEmail, $this->senderName ?: $this->senderEmail)) ->to($user->getEmailAuthRecipient()) ->subject($subject) ->text($bodyText) diff --git a/src/Tools/Utils.php b/src/Tools/Utils.php index f45bcec45..65cb8d7ee 100644 --- a/src/Tools/Utils.php +++ b/src/Tools/Utils.php @@ -24,10 +24,10 @@ class Utils * * @param string $text * - * @return float + * @return int */ public static function getReadingTime($text) { - return floor(\count(preg_split('~([^\p{L}\p{N}\']+|(\p{Han}|\p{Hiragana}|\p{Katakana}|\p{Hangul}){1,2})~u', strip_tags($text))) / 200); + return (int) floor(\count(preg_split('~([^\p{L}\p{N}\']+|(\p{Han}|\p{Hiragana}|\p{Katakana}|\p{Hangul}){1,2})~u', strip_tags($text))) / 200); } } diff --git a/tests/Controller/Api/WallabagRestControllerTest.php b/tests/Controller/Api/WallabagRestControllerTest.php index d73115cd6..46d18d325 100644 --- a/tests/Controller/Api/WallabagRestControllerTest.php +++ b/tests/Controller/Api/WallabagRestControllerTest.php @@ -43,8 +43,6 @@ class WallabagRestControllerTest extends WallabagApiTestCase if (!$client->getContainer()->getParameter('fosuser_registration')) { $this->markTestSkipped('fosuser_registration is not enabled.'); - - return; } $client->getContainer()->get(Config::class)->set('api_user_registration', 1); diff --git a/tests/Controller/ExportControllerTest.php b/tests/Controller/ExportControllerTest.php index 0a5c56c2e..40adc896d 100644 --- a/tests/Controller/ExportControllerTest.php +++ b/tests/Controller/ExportControllerTest.php @@ -11,8 +11,6 @@ class ExportControllerTest extends WallabagTestCase { private $adminEntry; private $bobEntry; - private $sameDomainEntry; - private $sameDomainEntry2; public function testLogin() { diff --git a/tests/Controller/SecurityControllerTest.php b/tests/Controller/SecurityControllerTest.php index 3ff4c57bf..3a90b1337 100644 --- a/tests/Controller/SecurityControllerTest.php +++ b/tests/Controller/SecurityControllerTest.php @@ -88,8 +88,6 @@ class SecurityControllerTest extends WallabagTestCase if (!$client->getContainer()->getParameter('fosuser_registration')) { $this->markTestSkipped('fosuser_registration is not enabled.'); - - return; } $client->followRedirects(); diff --git a/tests/Helper/ContentProxyTest.php b/tests/Helper/ContentProxyTest.php index 075c66cf7..37cc72fc4 100644 --- a/tests/Helper/ContentProxyTest.php +++ b/tests/Helper/ContentProxyTest.php @@ -55,7 +55,7 @@ class ContentProxyTest extends TestCase $this->assertEmpty($entry->getPreviewPicture()); $this->assertEmpty($entry->getMimetype()); $this->assertEmpty($entry->getLanguage()); - $this->assertSame(0.0, $entry->getReadingTime()); + $this->assertSame(0, $entry->getReadingTime()); $this->assertNull($entry->getDomainName()); $this->assertTrue($entry->isNotParsed()); } @@ -95,7 +95,7 @@ class ContentProxyTest extends TestCase $this->assertEmpty($entry->getPreviewPicture()); $this->assertEmpty($entry->getMimetype()); $this->assertEmpty($entry->getLanguage()); - $this->assertSame(0.0, $entry->getReadingTime()); + $this->assertSame(0, $entry->getReadingTime()); $this->assertSame('0.0.0.0', $entry->getDomainName()); $this->assertTrue($entry->isNotParsed()); } @@ -138,7 +138,7 @@ class ContentProxyTest extends TestCase $this->assertEmpty($entry->getLanguage()); $this->assertEmpty($entry->getHttpStatus()); $this->assertEmpty($entry->getMimetype()); - $this->assertSame(0.0, $entry->getReadingTime()); + $this->assertSame(0, $entry->getReadingTime()); $this->assertSame('domain.io', $entry->getDomainName()); $this->assertTrue($entry->isNotParsed()); } @@ -184,7 +184,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -230,7 +230,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -275,7 +275,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(0.0, $entry->getReadingTime()); + $this->assertSame(0, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -320,7 +320,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(0.0, $entry->getReadingTime()); + $this->assertSame(0, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -368,7 +368,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertNull($entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -422,7 +422,7 @@ class ContentProxyTest extends TestCase $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); $this->assertSame('200', $entry->getHttpStatus()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertFalse($entry->isNotParsed()); } @@ -461,7 +461,7 @@ class ContentProxyTest extends TestCase $this->assertStringContainsString('content', $entry->getContent()); $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertSame('24/03/2014', $entry->getPublishedAt()->format('d/m/Y')); $this->assertContains('Jeremy', $entry->getPublishedBy()); @@ -505,7 +505,7 @@ class ContentProxyTest extends TestCase $this->assertStringContainsString('content', $entry->getContent()); $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertSame('08/09/2016', $entry->getPublishedAt()->format('d/m/Y')); $this->assertFalse($entry->isNotParsed()); @@ -545,7 +545,7 @@ class ContentProxyTest extends TestCase $this->assertStringContainsString('content', $entry->getContent()); $this->assertSame('text/html', $entry->getMimetype()); $this->assertSame('fr', $entry->getLanguage()); - $this->assertSame(4.0, $entry->getReadingTime()); + $this->assertSame(4, $entry->getReadingTime()); $this->assertSame('1.1.1.1', $entry->getDomainName()); $this->assertNull($entry->getPublishedAt()); $this->assertFalse($entry->isNotParsed()); @@ -883,42 +883,42 @@ class ContentProxyTest extends TestCase */ $this->markTestSkipped('Encoding issue in PHP >= 8.1'); - // See http://graphemica.com for more info about the characters - // '😻ℤ�z' (U+1F63B or F09F98BB; U+2124 or E284A4; invalid character 81; U+007A or 7A) in hexadecimal and UTF-8 - // 0x81 is not a valid character for UTF16, UTF8 and WINDOWS-1252 - $actualTitle = $this->hexToStr('F09F98BB' . 'E284A4' . '81' . '7A'); - - $tagger = $this->getTaggerMock(); - $tagger->expects($this->once()) - ->method('tag'); - - $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); - - $graby = $this->getMockBuilder(Graby::class) - ->onlyMethods(['fetchContent']) - ->disableOriginalConstructor() - ->getMock(); - - $graby->expects($this->any()) - ->method('fetchContent') - ->willReturn([ - 'html' => false, - 'title' => $actualTitle, - 'url' => '', - 'headers' => [ - 'content-type' => 'application/pdf', - ], - 'language' => '', - ]); - - $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage); - $entry = new Entry(new User()); - $proxy->updateEntry($entry, 'http://0.0.0.0'); - - // '😻ℤz' (U+1F63B or F09F98BB; U+2124 or E284A4; U+007A or 7A) in hexadecimal and UTF-8 - // the 0x81 (represented by �) is invalid for UTF16, UTF8 and WINDOWS-1252 and is removed - $expectedTitle = 'F09F98BB' . 'E284A4' . '7A'; - $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle())); + // // See http://graphemica.com for more info about the characters + // // '😻ℤ�z' (U+1F63B or F09F98BB; U+2124 or E284A4; invalid character 81; U+007A or 7A) in hexadecimal and UTF-8 + // // 0x81 is not a valid character for UTF16, UTF8 and WINDOWS-1252 + // $actualTitle = $this->hexToStr('F09F98BB' . 'E284A4' . '81' . '7A'); + // + // $tagger = $this->getTaggerMock(); + // $tagger->expects($this->once()) + // ->method('tag'); + // + // $ruleBasedIgnoreOriginProcessor = $this->getRuleBasedIgnoreOriginProcessorMock(); + // + // $graby = $this->getMockBuilder(Graby::class) + // ->onlyMethods(['fetchContent']) + // ->disableOriginalConstructor() + // ->getMock(); + // + // $graby->expects($this->any()) + // ->method('fetchContent') + // ->willReturn([ + // 'html' => false, + // 'title' => $actualTitle, + // 'url' => '', + // 'headers' => [ + // 'content-type' => 'application/pdf', + // ], + // 'language' => '', + // ]); + // + // $proxy = new ContentProxy($graby, $tagger, $ruleBasedIgnoreOriginProcessor, $this->getValidator(), $this->getLogger(), $this->fetchingErrorMessage); + // $entry = new Entry(new User()); + // $proxy->updateEntry($entry, 'http://0.0.0.0'); + // + // // '😻ℤz' (U+1F63B or F09F98BB; U+2124 or E284A4; U+007A or 7A) in hexadecimal and UTF-8 + // // the 0x81 (represented by �) is invalid for UTF16, UTF8 and WINDOWS-1252 and is removed + // $expectedTitle = 'F09F98BB' . 'E284A4' . '7A'; + // $this->assertSame($expectedTitle, $this->strToHex($entry->getTitle())); } /** diff --git a/tests/Tools/UtilsTest.php b/tests/Tools/UtilsTest.php index 0925a4c0e..e80ee2bd4 100644 --- a/tests/Tools/UtilsTest.php +++ b/tests/Tools/UtilsTest.php @@ -13,7 +13,7 @@ class UtilsTest extends TestCase */ public function testCorrectWordsCountForDifferentLanguages($filename, $text, $expectedCount) { - static::assertSame((float) $expectedCount, Utils::getReadingTime($text), 'Reading time for: ' . $filename); + static::assertSame($expectedCount, Utils::getReadingTime($text), 'Reading time for: ' . $filename); } public function examples() @@ -30,7 +30,7 @@ class UtilsTest extends TestCase $examples[] = [ $file->getRelativePathname(), $match[1], // content - $match[2], // reading time + (int) $match[2], // reading time ]; }