diff --git a/app/psalm-baseline.xml b/app/psalm-baseline.xml
index e41232884..6cb0b3179 100644
--- a/app/psalm-baseline.xml
+++ b/app/psalm-baseline.xml
@@ -117,11 +117,6 @@
videoHref]]>
-
-
- deleteReplaced]]>
-
-
@@ -161,12 +156,6 @@
status]]>
-
-
- email]]>
- name]]>
-
-
@@ -226,26 +215,6 @@
-
-
- company]]>
- company]]>
- hidden]]>
- hidden]]>
- href ?: null]]>
- href ?: null]]>
- jobTitle ?: null]]>
- jobTitle ?: null]]>
- name]]>
- name]]>
- note ?: null]]>
- note ?: null]]>
- ranking ?: null]]>
- ranking ?: null]]>
- review]]>
- review]]>
-
-
@@ -254,21 +223,9 @@
videoThumbnail]]>
- videoThumbnail]]>
- videoThumbnailAlternative]]>
videoThumbnailAlternative]]>
-
-
-
-
-
-
-
-
-
-
@@ -278,15 +235,6 @@
filename ?? '']]>
filenameAlternative ?? '']]>
- alias]]>
- number]]>
- number]]>
- replace]]>
- replace]]>
- replaceAlternative]]>
- replaceAlternative]]>
- speakerNotes]]>
- title]]>
@@ -294,41 +242,6 @@
-
-
- city]]>
- city]]>
- city]]>
- company]]>
- company]]>
- company]]>
- companyId]]>
- companyId]]>
- companyId]]>
- companyTaxId]]>
- companyTaxId]]>
- companyTaxId]]>
- country]]>
- country]]>
- country]]>
- email]]>
- email]]>
- email]]>
- name]]>
- name]]>
- name]]>
- note]]>
- note]]>
- note]]>
- street]]>
- street]]>
- street]]>
- trainingId]]>
- zip]]>
- zip]]>
- zip]]>
-
-
ranking]]>
diff --git a/app/src/Application/Routing/BlogPostRoute.php b/app/src/Application/Routing/BlogPostRoute.php
index daf0afa86..21c1addf0 100644
--- a/app/src/Application/Routing/BlogPostRoute.php
+++ b/app/src/Application/Routing/BlogPostRoute.php
@@ -31,7 +31,7 @@ public function __construct(
* Maps HTTP request to a Request object.
*
* @param IRequest $httpRequest
- * @return array|null
+ * @return array|null
*/
#[Override]
public function match(IRequest $httpRequest): ?array
diff --git a/app/src/EasterEgg/NetteCve202015227.php b/app/src/EasterEgg/NetteCve202015227.php
index 124130ac5..490589f23 100644
--- a/app/src/EasterEgg/NetteCve202015227.php
+++ b/app/src/EasterEgg/NetteCve202015227.php
@@ -5,6 +5,7 @@
use Nette\Application\BadRequestException;
use Nette\Application\Routers\RouteList;
+use Nette\Application\UI\Component;
/**
* Nette CVE-2020-15227, here to easter-egg some bots
@@ -19,10 +20,7 @@
class NetteCve202015227
{
- /**
- * @param array $params
- */
- public function rce(string $callback, array $params): NetteCve202015227Rce
+ public function rce(string $callback, Component $component): NetteCve202015227Rce
{
$callback = strtolower($callback);
$paramNames = [
@@ -40,7 +38,8 @@ public function rce(string $callback, array $params): NetteCve202015227Rce
$data = [];
- $param = $params[$paramNames[$callback]] ?? null;
+ $param = $component->getParameters()[$paramNames[$callback]] ?? null;
+ assert(is_string($param) || $param === null);
if ($param === null) {
throw new BadRequestException(sprintf("[%s] Empty param '%s' for callback '%s'", __CLASS__, $paramNames[$callback], $callback));
}
diff --git a/app/src/EasterEgg/Presenters/NettePresenter.php b/app/src/EasterEgg/Presenters/NettePresenter.php
index 2d000de53..2ef6f7288 100644
--- a/app/src/EasterEgg/Presenters/NettePresenter.php
+++ b/app/src/EasterEgg/Presenters/NettePresenter.php
@@ -23,7 +23,7 @@ public function __construct(
public function actionMicro(string $callback): void
{
sleep(random_int(5, 20));
- $rce = $this->cve202015227->rce($callback, $this->getParameters());
+ $rce = $this->cve202015227->rce($callback, $this);
$this->setView($rce->view->value);
$this->template->eth0RxPackets = $rce->eth0RxPackets;
$this->template->eth1RxPackets = $rce->eth1RxPackets;
diff --git a/app/src/Form/InterviewFormFactory.php b/app/src/Form/InterviewFormFactory.php
index 43ddba884..370895ac9 100644
--- a/app/src/Form/InterviewFormFactory.php
+++ b/app/src/Form/InterviewFormFactory.php
@@ -121,9 +121,6 @@ public function create(callable $onSuccess, ?Interview $interview = null): UiFor
}
$onSuccess();
};
-
- $this->videoThumbnails->addOnValidateUploads($form, $videoThumbnailFormFields);
-
return $form;
}
diff --git a/app/src/Form/TalkFormFactory.php b/app/src/Form/TalkFormFactory.php
index a024d855a..e1cfd53ba 100644
--- a/app/src/Form/TalkFormFactory.php
+++ b/app/src/Form/TalkFormFactory.php
@@ -182,9 +182,6 @@ public function create(callable $onSuccess, ?Talk $talk = null): UiForm
$message->addHtml(Html::el('a')->href($this->linkGenerator->link('Www:Talks:talk', [$values->action]))->setText('Zobrazit'));
$onSuccess($message);
};
-
- $this->videoThumbnails->addOnValidateUploads($form, $videoThumbnailFormFields);
-
return $form;
}
diff --git a/app/src/Form/TalkSlidesFormFactory.php b/app/src/Form/TalkSlidesFormFactory.php
index ad3c4c0a8..12bb0e9d7 100644
--- a/app/src/Form/TalkSlidesFormFactory.php
+++ b/app/src/Form/TalkSlidesFormFactory.php
@@ -11,6 +11,7 @@
use Nette\Application\Request;
use Nette\Forms\Container;
use Nette\Forms\Form;
+use Nette\Utils\ArrayHash;
use Nette\Utils\Html;
readonly class TalkSlidesFormFactory
@@ -61,6 +62,9 @@ public function create(callable $onSuccess, int $talkId, TalkSlideCollection $sl
$form->onSuccess[] = function (UiForm $form) use ($slides, $onSuccess, $talkId): void {
try {
$values = $form->getFormValues();
+ assert($values->slides instanceof ArrayHash);
+ assert($values->new instanceof ArrayHash);
+ assert(is_bool($values->deleteReplaced));
$this->talkSlides->saveSlides($talkId, $slides, (array)$values->slides, array_values((array)$values->new), $values->deleteReplaced);
$message = $this->texyFormatter->translate('messages.talks.admin.slideadded');
$type = 'info';
@@ -96,7 +100,6 @@ private function addSlideFields(UiForm $form, Container $container, ?int $filena
->setRequired('Zadejte prosím alias')
->addRule(Form::Pattern, 'Alias musí být ve formátu [_.,a-z0-9-]+', '[_.,a-z0-9-]+');
$container->addInteger('number', 'Slajd:')
- ->setHtmlType('number')
->setDefaultValue(1)
->setHtmlAttribute('class', 'right slide-nr')
->setRequired('Zadejte prosím číslo slajdu');
diff --git a/app/src/Form/TrainingApplicationPreliminaryFormFactory.php b/app/src/Form/TrainingApplicationPreliminaryFormFactory.php
index 2c2d8342b..b302c98c2 100644
--- a/app/src/Form/TrainingApplicationPreliminaryFormFactory.php
+++ b/app/src/Form/TrainingApplicationPreliminaryFormFactory.php
@@ -27,8 +27,10 @@ public function create(callable $onSuccess, callable $onError, int $trainingId,
$form->addSubmit('signUp', 'Odeslat');
$form->onSuccess[] = function (UiForm $form) use ($onSuccess, $onError, $trainingId, $action): void {
$values = $form->getFormValues();
+ assert(is_string($values->name));
+ assert(is_string($values->email));
try {
- $this->formSpam->check($values);
+ $this->formSpam->check($values->name);
$this->trainingApplicationStorage->addPreliminaryInvitation($trainingId, $values->name, $values->email);
$onSuccess($action);
} catch (SpammyApplicationException) {
diff --git a/app/src/Form/TrainingReviewFormFactory.php b/app/src/Form/TrainingReviewFormFactory.php
index 22d1c6ce6..379d7b67b 100644
--- a/app/src/Form/TrainingReviewFormFactory.php
+++ b/app/src/Form/TrainingReviewFormFactory.php
@@ -51,9 +51,9 @@ public function create(callable $onSuccess, int $dateId, ?TrainingReview $review
->setRequired(false)
->addRule(Form::MaxLength, 'Maximální délka odkazu je %d znaků', 200);
$form->addCheckbox('hidden', 'Skrýt:');
- $form->addText('ranking', 'Pořadí:')
+ $form->addInteger('ranking', 'Pořadí:')
->setRequired(false)
- ->setHtmlType('number');
+ ->addRule(Form::Min, 'Minimální hodnota pořadí je %d', 0);
$form->addText('note', 'Poznámka:')
->setRequired(false)
->addRule(Form::MaxLength, 'Maximální délka poznámky je %d znaků', 2000);
@@ -64,17 +64,25 @@ public function create(callable $onSuccess, int $dateId, ?TrainingReview $review
$form->onSuccess[] = function (UiForm $form) use ($onSuccess, $review, $dateId): void {
$values = $form->getFormValues();
+ assert(is_string($values->name));
+ assert(is_string($values->company));
+ assert(is_string($values->jobTitle));
+ assert(is_string($values->review));
+ assert(is_string($values->href));
+ assert(is_bool($values->hidden));
+ assert(is_int($values->ranking) || $values->ranking === null);
+ assert(is_string($values->note));
if ($review) {
$this->trainingReviews->updateReview(
$review->getId(),
$dateId,
$values->name,
$values->company,
- $values->jobTitle ?: null,
+ $values->jobTitle !== '' ? $values->jobTitle : null,
$values->review,
- $values->href ?: null,
+ $values->href !== '' ? $values->href : null,
$values->hidden,
- $values->ranking ?: null,
+ $values->ranking !== 0 ? $values->ranking : null,
$values->note ?: null,
);
} else {
@@ -82,11 +90,11 @@ public function create(callable $onSuccess, int $dateId, ?TrainingReview $review
$dateId,
$values->name,
$values->company,
- $values->jobTitle ?: null,
+ $values->jobTitle !== '' ? $values->jobTitle : null,
$values->review,
- $values->href ?: null,
+ $values->href !== '' ? $values->href : null,
$values->hidden,
- $values->ranking ?: null,
+ $values->ranking !== 0 ? $values->ranking : null,
$values->note ?: null,
);
}
diff --git a/app/src/Media/VideoThumbnails.php b/app/src/Media/VideoThumbnails.php
index ec2b2b7fb..c01237e1d 100644
--- a/app/src/Media/VideoThumbnails.php
+++ b/app/src/Media/VideoThumbnails.php
@@ -71,17 +71,14 @@ public function addFormFields(UiForm $form, bool $hasMainVideoThumbnail, bool $h
$videoThumbnailAlternative->addCondition(Form::Filled, true)
->toggle('#currentVideoThumbnailAlternative', false);
}
- return new VideoThumbnailFileUploads($videoThumbnail, $videoThumbnailAlternative, $hasMainVideoThumbnail, $hasAlternativeVideoThumbnail);
- }
-
-
- public function addOnValidateUploads(UiForm $form, VideoThumbnailFileUploads $formFields): void
- {
- $form->onValidate[] = function (UiForm $form) use ($formFields): void {
+ $form->onValidate[] = function (UiForm $form) use ($videoThumbnail, $videoThumbnailAlternative): void {
$values = $form->getFormValues();
- $this->validateUpload($values->videoThumbnail, $formFields->getVideoThumbnail());
- $this->validateUpload($values->videoThumbnailAlternative, $formFields->getVideoThumbnailAlternative());
+ assert($values->videoThumbnail instanceof FileUpload);
+ assert($values->videoThumbnailAlternative instanceof FileUpload);
+ $this->validateUpload($values->videoThumbnail, $videoThumbnail);
+ $this->validateUpload($values->videoThumbnailAlternative, $videoThumbnailAlternative);
};
+ return new VideoThumbnailFileUploads($videoThumbnail, $videoThumbnailAlternative, $hasMainVideoThumbnail, $hasAlternativeVideoThumbnail);
}
diff --git a/app/src/Net/DnsResolver.php b/app/src/Net/DnsResolver.php
index f2a7b1f8f..675ec74d5 100644
--- a/app/src/Net/DnsResolver.php
+++ b/app/src/Net/DnsResolver.php
@@ -23,7 +23,12 @@ public function getRecords(string $hostname, int $type): array
}
$result = [];
foreach ($records as $record) {
- $result[] = new DnsRecord(...$record);
+ assert(is_string($record['host']));
+ assert(is_string($record['class']));
+ assert(is_int($record['ttl']));
+ assert(is_string($record['type']));
+ assert(is_string($record['ip']));
+ $result[] = new DnsRecord($record['host'], $record['class'], $record['ttl'], $record['type'], $record['ip']);
}
return $result;
}
diff --git a/app/src/Talks/Slides/TalkSlides.php b/app/src/Talks/Slides/TalkSlides.php
index 7dda00862..5d90d4f6d 100644
--- a/app/src/Talks/Slides/TalkSlides.php
+++ b/app/src/Talks/Slides/TalkSlides.php
@@ -217,11 +217,14 @@ private function addSlides(int $talkId, array $slides): void
$lastNumber = 0;
try {
foreach ($slides as $slide) {
+ assert($slide->replace instanceof FileUpload);
+ assert($slide->replaceAlternative instanceof FileUpload);
+ assert(is_int($slide->number));
$width = self::SLIDE_MAX_WIDTH;
$height = self::SLIDE_MAX_HEIGHT;
$replace = $this->replaceSlideImage($talkId, $slide->replace, $this->supportedImageFileFormats->getMainExtensionByContentType(...), false, null, $width, $height);
$replaceAlternative = $this->replaceSlideImage($talkId, $slide->replaceAlternative, $this->supportedImageFileFormats->getAlternativeExtensionByContentType(...), false, null, $width, $height);
- $lastNumber = (int)$slide->number;
+ $lastNumber = $slide->number;
$this->database->query(
'INSERT INTO talk_slides',
[
@@ -259,6 +262,14 @@ private function updateSlides(int $talkId, TalkSlideCollection $originalSlides,
}
}
foreach ($slides as $id => $slide) {
+ assert($slide->replace instanceof FileUpload || $slide->replace === null);
+ assert($slide->replaceAlternative instanceof FileUpload || $slide->replaceAlternative === null);
+ assert(is_string($slide->alias));
+ assert(is_int($slide->number));
+ assert(is_string($slide->filename));
+ assert(is_string($slide->filenameAlternative));
+ assert(is_string($slide->title));
+ assert(is_string($slide->speakerNotes));
$width = self::SLIDE_MAX_WIDTH;
$height = self::SLIDE_MAX_HEIGHT;
diff --git a/app/src/Training/ApplicationForm/TrainingApplicationFormDataLogger.php b/app/src/Training/ApplicationForm/TrainingApplicationFormDataLogger.php
index ab8548a54..ca5c94e23 100644
--- a/app/src/Training/ApplicationForm/TrainingApplicationFormDataLogger.php
+++ b/app/src/Training/ApplicationForm/TrainingApplicationFormDataLogger.php
@@ -4,18 +4,20 @@
namespace MichalSpacekCz\Training\ApplicationForm;
use MichalSpacekCz\Training\Applications\TrainingApplicationSessionSection;
-use stdClass;
use Tracy\Debugger;
class TrainingApplicationFormDataLogger
{
- public function log(stdClass $values, string $name, int $dateId, ?TrainingApplicationSessionSection $sessionSection): void
+ /**
+ * @param array $values
+ */
+ public function log(array $values, string $name, int $dateId, ?TrainingApplicationSessionSection $sessionSection): void
{
$applicationId = $sessionSection?->getApplicationIdByDateId($name, $dateId);
$logSession = $applicationId !== null ? "id => '{$applicationId}', dateId => '{$dateId}'" : null;
$logValues = [];
- foreach ((array)$values as $key => $value) {
+ foreach ($values as $key => $value) {
$logValues[] = sprintf('%s => %s', $key, is_string($value) ? "'{$value}'" : get_debug_type($value));
}
$message = sprintf(
diff --git a/app/src/Training/ApplicationForm/TrainingApplicationFormSpam.php b/app/src/Training/ApplicationForm/TrainingApplicationFormSpam.php
index 953658619..8c4ff3115 100644
--- a/app/src/Training/ApplicationForm/TrainingApplicationFormSpam.php
+++ b/app/src/Training/ApplicationForm/TrainingApplicationFormSpam.php
@@ -5,7 +5,6 @@
use Composer\Pcre\Regex;
use MichalSpacekCz\Training\Exceptions\SpammyApplicationException;
-use stdClass;
class TrainingApplicationFormSpam
{
@@ -16,15 +15,18 @@ class TrainingApplicationFormSpam
private const string FIELD_MISSING_VALUE = 'missing';
- public function check(stdClass $values): void
+ /**
+ * @throws SpammyApplicationException
+ */
+ public function check(string $name, ?string $company = null, ?string $companyId = null, ?string $companyTaxId = null, ?string $note = null): void
{
- if (Regex::isMatch('~\s+href="\s*https?://~', $values->note ?? '')) {
+ if (Regex::isMatch('~\s+href="\s*https?://~', $note ?? self::FIELD_MISSING_VALUE)) {
throw new SpammyApplicationException();
} elseif (
- ctype_lower($values->name ?? self::FIELD_MISSING_VALUE)
- && ctype_lower($values->company ?? self::FIELD_MISSING_VALUE)
- && ctype_lower($values->companyId ?? self::FIELD_MISSING_VALUE)
- && ctype_lower($values->companyTaxId ?? self::FIELD_MISSING_VALUE)
+ ctype_lower($name)
+ && ctype_lower($company ?? self::FIELD_MISSING_VALUE)
+ && ctype_lower($companyId ?? self::FIELD_MISSING_VALUE)
+ && ctype_lower($companyTaxId ?? self::FIELD_MISSING_VALUE)
) {
throw new SpammyApplicationException();
}
diff --git a/app/src/Training/ApplicationForm/TrainingApplicationFormSuccess.php b/app/src/Training/ApplicationForm/TrainingApplicationFormSuccess.php
index a853595ad..1bd19f185 100644
--- a/app/src/Training/ApplicationForm/TrainingApplicationFormSuccess.php
+++ b/app/src/Training/ApplicationForm/TrainingApplicationFormSuccess.php
@@ -21,7 +21,6 @@
use ParagonIE\Halite\Alerts\HaliteAlert;
use PDOException;
use SodiumException;
-use stdClass;
use Tracy\Debugger;
readonly class TrainingApplicationFormSuccess
@@ -57,11 +56,22 @@ public function success(
TrainingApplicationSessionSection $sessionSection,
): void {
$values = $form->getFormValues();
+ assert(is_string($values->name));
+ assert(is_string($values->email));
+ assert(is_string($values->company));
+ assert(is_string($values->street));
+ assert(is_string($values->city));
+ assert(is_string($values->zip));
+ assert(is_string($values->country));
+ assert(is_string($values->companyId));
+ assert(is_string($values->companyTaxId));
+ assert(is_string($values->note));
try {
- $this->formSpam->check($values);
+ $this->formSpam->check($values->name, $values->company, $values->companyId, $values->companyTaxId, $values->note);
if ($multipleDates) {
- $this->checkTrainingDate($values, $action, $dates, $sessionSection);
- $date = $dates[$values->trainingId] ?? false;
+ assert(is_int($values->trainingId));
+ $this->checkTrainingDate((array)$values, $action, $values->trainingId, $dates, $sessionSection);
+ $date = $dates[$values->trainingId];
} else {
$date = reset($dates);
}
@@ -153,14 +163,15 @@ public function success(
/**
+ * @param array $values
* @param array $dates
* @throws TrainingDateNotUpcomingException
*/
- private function checkTrainingDate(stdClass $values, string $name, array $dates, TrainingApplicationSessionSection $sessionSection): void
+ private function checkTrainingDate(array $values, string $name, int $dateId, array $dates, TrainingApplicationSessionSection $sessionSection): void
{
- if (!isset($dates[$values->trainingId])) {
- $this->formDataLogger->log($values, $name, $values->trainingId, $sessionSection);
- throw new TrainingDateNotUpcomingException($values->trainingId, $dates);
+ if (!isset($dates[$dateId])) {
+ $this->formDataLogger->log($values, $name, $dateId, $sessionSection);
+ throw new TrainingDateNotUpcomingException($dateId, $dates);
}
}
diff --git a/app/src/Training/Reviews/TrainingReviews.php b/app/src/Training/Reviews/TrainingReviews.php
index ced5fd2a6..a2e3fa675 100644
--- a/app/src/Training/Reviews/TrainingReviews.php
+++ b/app/src/Training/Reviews/TrainingReviews.php
@@ -3,8 +3,8 @@
namespace MichalSpacekCz\Training\Reviews;
-use DateTime;
use MichalSpacekCz\Database\TypedDatabase;
+use MichalSpacekCz\DateTime\DateTimeFactory;
use MichalSpacekCz\Formatter\TexyFormatter;
use MichalSpacekCz\Training\Exceptions\TrainingReviewNotFoundException;
use Nette\Database\Explorer;
@@ -17,6 +17,7 @@ public function __construct(
private Explorer $database,
private TypedDatabase $typedDatabase,
private TexyFormatter $texyFormatter,
+ private DateTimeFactory $dateTimeFactory,
) {
}
@@ -176,7 +177,7 @@ public function updateReview(int $reviewId, int $dateId, string $name, string $c
public function addReview(int $dateId, string $name, string $company, ?string $jobTitle, string $review, ?string $href, bool $hidden, ?int $ranking, ?string $note): void
{
- $datetime = new DateTime();
+ $datetime = $this->dateTimeFactory->create();
$timeZone = $datetime->getTimezone()->getName();
$this->database->query(
'INSERT INTO training_reviews ?',
diff --git a/app/tests/EasterEgg/NetteCve202015227Test.phpt b/app/tests/EasterEgg/NetteCve202015227Test.phpt
index 51258e996..adad7d089 100644
--- a/app/tests/EasterEgg/NetteCve202015227Test.phpt
+++ b/app/tests/EasterEgg/NetteCve202015227Test.phpt
@@ -7,6 +7,7 @@ use MichalSpacekCz\Test\TestCaseRunner;
use Nette\Application\BadRequestException;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
+use Nette\Application\UI\Component;
use Tester\Assert;
use Tester\TestCase;
@@ -25,7 +26,7 @@ class NetteCve202015227Test extends TestCase
public function testRceUnknownCallback(): void
{
Assert::exception(function (): void {
- $this->cve202015227->rce('foo', ['bar' => 'baz']);
+ $this->cve202015227->rce('foo', $this->createComponent(['bar' => 'baz']));
}, BadRequestException::class, "[MichalSpacekCz\EasterEgg\NetteCve202015227] Unknown callback 'foo'");
}
@@ -33,7 +34,7 @@ class NetteCve202015227Test extends TestCase
public function testRceEmptyParam(): void
{
Assert::exception(function (): void {
- $this->cve202015227->rce('exec', ['bar' => 'baz']);
+ $this->cve202015227->rce('exec', $this->createComponent(['bar' => 'baz']));
}, BadRequestException::class, "[MichalSpacekCz\EasterEgg\NetteCve202015227] Empty param 'command' for callback 'exec'");
}
@@ -41,21 +42,21 @@ class NetteCve202015227Test extends TestCase
public function testRceUnknownValue(): void
{
Assert::exception(function (): void {
- $this->cve202015227->rce('exec', ['command' => 'baz']);
+ $this->cve202015227->rce('exec', $this->createComponent(['command' => 'baz']));
}, BadRequestException::class, "[MichalSpacekCz\EasterEgg\NetteCve202015227] Unknown value 'baz' for callback 'exec' and param 'command'");
}
public function testRceLs(): void
{
- $rce = $this->cve202015227->rce('exec', ['command' => 'ls foo']);
+ $rce = $this->cve202015227->rce('exec', $this->createComponent(['command' => 'ls foo']));
Assert::same(NetteCve202015227View::Ls, $rce->view);
}
public function testRceIfconfig(): void
{
- $rce = $this->cve202015227->rce('exec', ['command' => 'ifconfig bar']);
+ $rce = $this->cve202015227->rce('exec', $this->createComponent(['command' => 'ifconfig bar']));
Assert::same(NetteCve202015227View::Ifconfig, $rce->view);
Assert::type('string', $rce->eth0RxPackets);
Assert::type('string', $rce->eth1RxPackets);
@@ -74,7 +75,7 @@ class NetteCve202015227Test extends TestCase
public function testRceWget(): void
{
- $rce = $this->cve202015227->rce('shell_exec', ['cmd' => 'wget example.com']);
+ $rce = $this->cve202015227->rce('shell_exec', $this->createComponent(['cmd' => 'wget example.com']));
Assert::same(NetteCve202015227View::Wget, $rce->view);
}
@@ -82,7 +83,7 @@ class NetteCve202015227Test extends TestCase
/** @dataProvider getCommands */
public function testRceNotFound(NetteCve202015227View $view, string $command, string $cmd): void
{
- $rce = $this->cve202015227->rce('shell_exec', ['cmd' => $cmd]);
+ $rce = $this->cve202015227->rce('shell_exec', $this->createComponent(['cmd' => $cmd]));
Assert::same($view, $rce->view);
Assert::same($command, $rce->command);
}
@@ -141,6 +142,18 @@ class NetteCve202015227Test extends TestCase
];
}
+
+ /**
+ * @param array $params
+ */
+ private function createComponent(array $params): Component
+ {
+ $component = new class extends Component {
+ };
+ $component->loadState($params);
+ return $component;
+ }
+
}
TestCaseRunner::run(NetteCve202015227Test::class);
diff --git a/app/tests/Form/TrainingReviewFormFactoryTest.phpt b/app/tests/Form/TrainingReviewFormFactoryTest.phpt
new file mode 100644
index 000000000..d97968f7c
--- /dev/null
+++ b/app/tests/Form/TrainingReviewFormFactoryTest.phpt
@@ -0,0 +1,119 @@
+setDateTime(new DateTimeImmutable('2020-01-01 12:34:56'));
+ }
+
+
+ #[Override]
+ protected function tearDown(): void
+ {
+ $this->database->reset();
+ $this->resultDateId = null;
+ }
+
+
+ public function testCreateOnSuccessAdd(): void
+ {
+ $form = $this->formFactory->create(
+ function (int $dateId): void {
+ $this->resultDateId = $dateId;
+ },
+ self::DATE_ID,
+ null,
+ );
+ $this->applicationPresenter->anchorForm($form);
+ Arrays::invoke($form->onSuccess, $form);
+ Assert::same(self::DATE_ID, $this->resultDateId);
+ Assert::same([
+ [
+ 'key_date' => self::DATE_ID,
+ 'name' => '',
+ 'company' => '',
+ 'job_title' => null,
+ 'review' => '',
+ 'href' => null,
+ 'added' => '2020-01-01 12:34:56',
+ 'added_timezone' => 'Europe/Prague',
+ 'hidden' => false,
+ 'ranking' => null,
+ 'note' => null,
+ ],
+ ], $this->database->getParamsArrayForQuery('INSERT INTO training_reviews ?'));
+ }
+
+
+ public function testCreateOnSuccessEdit(): void
+ {
+ $form = $this->formFactory->create(
+ function (int $dateId): void {
+ $this->resultDateId = $dateId;
+ },
+ self::DATE_ID,
+ new TrainingReview(
+ 303,
+ 'John Deere',
+ 'Comp Any',
+ 'Team Le-ad',
+ Html::fromHtml('foo'),
+ '**foo**',
+ 'https://example.com',
+ false,
+ 3,
+ 'No tea',
+ self::DATE_ID,
+ ),
+ );
+ $this->applicationPresenter->anchorForm($form);
+ Arrays::invoke($form->onSuccess, $form);
+ Assert::same(self::DATE_ID, $this->resultDateId);
+ Assert::same([
+ [
+ 'key_date' => self::DATE_ID,
+ 'name' => 'John Deere',
+ 'company' => 'Comp Any',
+ 'job_title' => 'Team Le-ad',
+ 'review' => '**foo**',
+ 'href' => 'https://example.com',
+ 'hidden' => false,
+ 'ranking' => 3,
+ 'note' => 'No tea',
+ ],
+ ], $this->database->getParamsArrayForQuery('UPDATE training_reviews SET ? WHERE id_review = ?'));
+ }
+
+}
+
+TestCaseRunner::run(TrainingReviewFormFactoryTest::class);
diff --git a/app/tests/Net/DnsResolverTest.phpt b/app/tests/Net/DnsResolverTest.phpt
new file mode 100644
index 000000000..48f744da8
--- /dev/null
+++ b/app/tests/Net/DnsResolverTest.phpt
@@ -0,0 +1,34 @@
+dnsResolver->getRecords('one.one.one.one', DNS_A);
+ $ips = array_map(fn(DnsRecord $dnsRecord): ?string => $dnsRecord->getIp(), $records);
+ sort($ips);
+ Assert::same(['1.0.0.1', '1.1.1.1'], $ips);
+ }
+
+}
+
+TestCaseRunner::run(DnsResolverTest::class);
diff --git a/app/tests/Training/ApplicationForm/TrainingApplicationFormDataLoggerTest.phpt b/app/tests/Training/ApplicationForm/TrainingApplicationFormDataLoggerTest.phpt
index 0b4b25a66..bc6708e8e 100644
--- a/app/tests/Training/ApplicationForm/TrainingApplicationFormDataLoggerTest.phpt
+++ b/app/tests/Training/ApplicationForm/TrainingApplicationFormDataLoggerTest.phpt
@@ -15,7 +15,6 @@ use MichalSpacekCz\Training\Files\TrainingFiles;
use MichalSpacekCz\Training\Mails\TrainingMailMessageFactory;
use Nette\Utils\Html;
use Override;
-use stdClass;
use Tester\Assert;
use Tester\TestCase;
@@ -50,16 +49,17 @@ class TrainingApplicationFormDataLoggerTest extends TestCase
public function testLogNoValuesNoSession(): void
{
- $this->formDataLogger->log(new stdClass(), 'foo', self::DATE_ID, null);
+ $this->formDataLogger->log([], 'foo', self::DATE_ID, null);
Assert::same(['Application session data for foo: undefined, form values: empty'], $this->logger->getLogged());
}
public function testLogNoSession(): void
{
- $values = new stdClass();
- $values->key1 = 'value1';
- $values->key2 = 'value2';
+ $values = [
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ];
$this->formDataLogger->log($values, 'foo', self::DATE_ID, null);
Assert::same(["Application session data for foo: undefined, form values: key1 => 'value1', key2 => 'value2'"], $this->logger->getLogged());
}
@@ -67,9 +67,10 @@ class TrainingApplicationFormDataLoggerTest extends TestCase
public function testLogEmptySession(): void
{
- $values = new stdClass();
- $values->key1 = 'value1';
- $values->key2 = 'value2';
+ $values = [
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ ];
$this->formDataLogger->log($values, 'foo', self::DATE_ID, $this->getTrainingSessionSection());
Assert::same(["Application session data for foo: empty, form values: key1 => 'value1', key2 => 'value2'"], $this->logger->getLogged());
}
@@ -77,10 +78,11 @@ class TrainingApplicationFormDataLoggerTest extends TestCase
public function testLog(): void
{
- $values = new stdClass();
- $values->key1 = 'value1';
- $values->key2 = 'value2';
- $values->key3 = 1336;
+ $values = [
+ 'key1' => 'value1',
+ 'key2' => 'value2',
+ 'key3' => 1336,
+ ];
$trainingName = 'foo';
$session = $this->getTrainingSessionSection();
diff --git a/app/tests/Training/ApplicationForm/TrainingApplicationFormSpamTest.phpt b/app/tests/Training/ApplicationForm/TrainingApplicationFormSpamTest.phpt
index da7ceb0fa..15edab45c 100644
--- a/app/tests/Training/ApplicationForm/TrainingApplicationFormSpamTest.phpt
+++ b/app/tests/Training/ApplicationForm/TrainingApplicationFormSpamTest.phpt
@@ -5,11 +5,9 @@ declare(strict_types = 1);
namespace MichalSpacekCz\Training\ApplicationForm;
-use Generator;
use MichalSpacekCz\Test\NullLogger;
use MichalSpacekCz\Test\TestCaseRunner;
use MichalSpacekCz\Training\Exceptions\SpammyApplicationException;
-use stdClass;
use Tester\Assert;
use Tester\TestCase;
@@ -26,45 +24,79 @@ class TrainingApplicationFormSpamTest extends TestCase
}
- public function getValues(): Generator
+ /**
+ * @return list
+ */
+ public function getValues(): array
{
- $values = new stdClass();
- $values->note = 'foo href="https:// example" bar baz';
- yield [$values, false];
-
- $values = new stdClass();
- $values->name = 'zggnbijhah';
- $values->companyId = 'vwetyeofcx';
- $values->companyTaxId = 'tyqvukaims';
- $values->company = 'qzpormrfcq';
- yield [$values, false];
-
- $values = new stdClass();
- $values->name = 'zggnbijhah';
- yield [$values, false];
-
- yield [new stdClass(), false];
- $values = new stdClass();
- $values->name = 'foo bar';
- yield [$values, true];
-
- $values = new stdClass();
- $values->companyId = 'foobar1';
- yield [$values, true];
-
- $values = new stdClass();
- $values->companyTaxId = 'foobar1';
- yield [$values, true];
+ return [
+ [
+ 'name' => 'foo bar',
+ 'companyId' => null,
+ 'companyTaxId' => null,
+ 'company' => null,
+ 'note' => 'foo href="https:// example" bar baz',
+ 'isNice' => false,
+ ],
+ [
+ 'name' => 'zggnbijhah',
+ 'companyId' => 'vwetyeofcx',
+ 'companyTaxId' => 'tyqvukaims',
+ 'company' => 'qzpormrfcq',
+ 'note' => null,
+ 'isNice' => false,
+ ],
+ [
+ 'name' => 'zggnbijhah',
+ 'companyId' => null,
+ 'companyTaxId' => null,
+ 'company' => null,
+ 'note' => null,
+ 'isNice' => false,
+ ],
+ [
+ 'name' => 'foo bar',
+ 'companyId' => null,
+ 'companyTaxId' => null,
+ 'company' => null,
+ 'note' => null,
+ 'isNice' => true,
+ ],
+ [
+ 'name' => '',
+ 'companyId' => 'foobar1',
+ 'companyTaxId' => null,
+ 'company' => null,
+ 'note' => null,
+ 'isNice' => true,
+ ],
+ [
+ 'name' => '',
+ 'companyId' => null,
+ 'companyTaxId' => 'foobar1',
+ 'company' => null,
+ 'note' => null,
+ 'isNice' => true,
+ ],
+ [
+ 'name' => '',
+ 'companyId' => null,
+ 'companyTaxId' => null,
+ 'company' => 'comp any',
+ 'note' => null,
+ 'isNice' => true,
+ ],
+ ];
}
/**
* @dataProvider getValues
*/
- public function testIsSpam(stdClass $values, bool $isNice): void
+ public function testIsSpam(string $name, ?string $companyId, ?string $companyTaxId, ?string $company, ?string $note, bool $isNice): void
{
- $check = function () use ($values): void {
- $this->formSpam->check($values);
+ $check = function () use ($name, $company, $companyId, $companyTaxId, $note): void {
+ $this->formSpam->check($name, $company, $companyId, $companyTaxId, $note);
};
if ($isNice) {
Assert::noError($check);