Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Exanlv committed Feb 28, 2024
1 parent 9f2c413 commit c46816d
Show file tree
Hide file tree
Showing 5 changed files with 428 additions and 21 deletions.
1 change: 0 additions & 1 deletion fakes/DiscordFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public static function get(): Mock|Discord

$discord->rest = RestFake::get();
$discord->gateway = GatewayFake::get();
$discord->interaction = InteractionHandlerFake::get();

return $discord;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Command/CommandExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ private function registerListener(Discord $discord): void
$discord->gateway->events,
Events::INTERACTION_CREATE,
fn (InteractionCreate $interactionCreate) =>
$interactionCreate?->type === InteractionType::APPLICATION_COMMAND
isset($interactionCreate->type)
&& $interactionCreate->type === InteractionType::APPLICATION_COMMAND
&& isset($this->commandMappings[$interactionCreate->data->id])
);

Expand Down
19 changes: 0 additions & 19 deletions tests/Command/CommandExtensionTest.php

This file was deleted.

213 changes: 213 additions & 0 deletions tests/Command/GlobalCommandExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<?php

declare(strict_types=1);

namespace Tests\Ragnarok\Fenrir\Command;

use Fakes\Ragnarok\Fenrir\DiscordFake;
use Fakes\Ragnarok\Fenrir\PromiseFake;
use PHPUnit\Framework\TestCase;
use Ragnarok\Fenrir\Command\GlobalCommandExtension;
use Ragnarok\Fenrir\Constants\Events;
use Ragnarok\Fenrir\Discord;
use Ragnarok\Fenrir\Enums\ApplicationCommandOptionType;
use Ragnarok\Fenrir\Enums\InteractionType;
use Ragnarok\Fenrir\Gateway\Events\InteractionCreate;
use Ragnarok\Fenrir\Interaction\CommandInteraction;
use Ragnarok\Fenrir\Parts\ApplicationCommand;
use Ragnarok\Fenrir\Parts\ApplicationCommandOptionStructure;
use Ragnarok\Fenrir\Parts\InteractionData;

class GlobalCommandExtensionTest extends TestCase
{
private Discord $discord;

protected function setUp(): void
{
$this->discord = DiscordFake::get();
}

public function testItEmitsEventsForApplicationCommands()
{
$commands = [new ApplicationCommand(), new ApplicationCommand()];

$commands[0]->id = '::application command 1::';
$commands[0]->name = 'command-1';

$commands[1]->id = '::application command 2::';
$commands[1]->name = 'command-2';

$this->discord->rest->globalCommand->shouldReceive()
->getCommands('::application id::')
->andReturns(PromiseFake::get($commands));

$extension = new GlobalCommandExtension('::application id::');
$extension->initialize($this->discord);

$hasRun = [false, false];

$extension->on('command-1', function (CommandInteraction $firedCommand) use (&$hasRun) {
$hasRun[0] = true;
});

$extension->on('command-2', function (CommandInteraction $firedCommand) use (&$hasRun) {
$hasRun[1] = true;
});

$interaction = new InteractionCreate();
$interaction->type = InteractionType::APPLICATION_COMMAND;
$interaction->data = new InteractionData();
$interaction->data->id = '::application command 1::';

$this->discord->gateway->events->emit(
Events::INTERACTION_CREATE,
[$interaction]
);

$interaction->data->id = '::application command 2::';

$this->discord->gateway->events->emit(
Events::INTERACTION_CREATE,
[$interaction]
);

$this->assertTrue($hasRun[0], 'Command 1 did not run');
$this->assertTrue($hasRun[1], 'Command 2 did not run');
}

public function testItDoesNotEmitCommandIfDifferentInteractionOccured()
{
$command = new ApplicationCommand();

$command->id = '::application command::';
$command->name = 'command';

$this->discord->rest->globalCommand->shouldReceive()
->getCommands('::application id::')
->andReturns(PromiseFake::get([$command]));

$extension = new GlobalCommandExtension('::application id::');
$extension->initialize($this->discord);

$hasRun = false;

$extension->on('command', function (CommandInteraction $firedCommand) use (&$hasRun) {
$hasRun = true;
});

$interaction = new InteractionCreate();
$interaction->type = InteractionType::PING;
$interaction->data = new InteractionData();
$interaction->data->id = '::application command::';

$this->discord->gateway->events->emit(
Events::INTERACTION_CREATE,
[$interaction]
);

$this->assertFalse($hasRun, 'Command was emitted wrongfully');
}

/**
* @dataProvider nameMappingProvider
* @depends testItEmitsEventsForApplicationCommands
*/
public function testItMapsNamesCorrectly(ApplicationCommand $command, string $expectedName)
{
$command->id = '::application command::';

$this->discord->rest->globalCommand->shouldReceive()
->getCommands('::application id::')
->andReturns(PromiseFake::get([$command]));

$extension = new GlobalCommandExtension('::application id::');
$extension->initialize($this->discord);

$hasRun = false;

$extension->on($expectedName, function (CommandInteraction $firedCommand) use (&$hasRun) {
$hasRun = true;
});

$interaction = new InteractionCreate();
$interaction->type = InteractionType::APPLICATION_COMMAND;
$interaction->data = new InteractionData();
$interaction->data->id = '::application command::';

$this->discord->gateway->events->emit(
Events::INTERACTION_CREATE,
[$interaction]
);

$this->assertTrue($hasRun, 'Command was emitted wrongfully');
}

public static function nameMappingProvider(): array
{
return [
'Plain name' => [
'command' => (function () {
$command = new ApplicationCommand();
$command->name = 'command-name';

return $command;
})(),
'expectedName' => 'command-name'
],

'Nested 1 layer' => [
'command' => (function () {
$command = new ApplicationCommand();
$command->name = 'command-name';

$command->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->name = 'sub';
$command->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND;

return $command;
})(),
'expectedName' => 'command-name.sub'
],

'Nested 2 layer' => [
'command' => (function () {
$command = new ApplicationCommand();
$command->name = 'command-name';

$command->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->name = 'double';
$command->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND_GROUP;

$command->options[0]->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->options[0]->name = 'sub';
$command->options[0]->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND_GROUP;

return $command;
})(),
'expectedName' => 'command-name.double.sub'
],

'Nested 3 layer' => [ // NOTE: Not supported by Discord
'command' => (function () {
$command = new ApplicationCommand();
$command->name = 'command-name';

$command->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->name = 'double';
$command->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND_GROUP;

$command->options[0]->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->options[0]->name = 'sub';
$command->options[0]->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND_GROUP;

$command->options[0]->options[0]->options = [new ApplicationCommandOptionStructure()];
$command->options[0]->options[0]->options[0]->name = 'dub';
$command->options[0]->options[0]->options[0]->type = ApplicationCommandOptionType::SUB_COMMAND_GROUP;

return $command;
})(),
'expectedName' => 'command-name.double.sub.dub'
],
];
}
}
Loading

0 comments on commit c46816d

Please sign in to comment.