Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .env.testing.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug

DB_CONNECTION=testing
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=dev_he4rtbot
DB_USERNAME=root
DB_PASSWORD=root
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=test_he4rtbot
DB_USERNAME=postgres
DB_PASSWORD=postgres

BROADCAST_DRIVER=log
CACHE_DRIVER=file
Expand Down
17 changes: 17 additions & 0 deletions .github/workflows/_pest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ jobs:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-tests
cancel-in-progress: true

services:
postgres:
image: postgres:18-alpine
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: test_he4rtbot
ports:
- 5432/tcp
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Expand Down Expand Up @@ -70,5 +86,6 @@ jobs:
- name: Run Tests
env:
XDEBUG_MODE: coverage
DB_PORT: ${{ job.services.postgres.ports['5432'] }}
run: |
vendor/bin/pest --ci --parallel
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
id: setup
run: |
echo "PHP_VERSION=8.4" >> "$GITHUB_OUTPUT"
echo "PHP_EXTENSIONS=mbstring,pdo,xml,ctype,fileinfo,json,curl,openssl,dom,zip" >> "$GITHUB_OUTPUT"
echo "PHP_EXTENSIONS=mbstring,pdo,pdo_pgsql,xml,ctype,fileinfo,json,curl,openssl,dom,zip" >> "$GITHUB_OUTPUT"
echo "PHP_INI_PROPERTIES=post_max_size=256M,upload_max_filesize=256M" >> "$GITHUB_OUTPUT"
echo "COMPOSER_FLAGS=--prefer-dist --optimize-autoloader" >> "$GITHUB_OUTPUT"

Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,22 @@ check: test-rector test-pint test-phpstan ## Run Pint, PHPStan with Rector in dr

.PHONY: test
test: ## Run all tests
@$(CURDIR)/vendor/bin/pest --parallel --compact
@$(CURDIR)/vendor/bin/pest --compact

.PHONY: t
t: test ## Alias for test

.PHONY: test-unit
test-unit: ## Run unit tests
@$(CURDIR)/vendor/bin/pest --parallel --compact --group=unit
@$(CURDIR)/vendor/bin/pest --compact --group=unit

.PHONY: test-feature
test-feature: ## Run feature tests
@$(CURDIR)/vendor/bin/pest --parallel --compact --group=feature
@$(CURDIR)/vendor/bin/pest --compact --group=feature

.PHONY: setup-test-db
setup-test-db: ## Create the testing database for running tests
@PGHOST=localhost PGUSER=postgres PGPASSWORD=postgres createdb test_he4rtbot 2>/dev/null || echo "Database test_he4rtbot already exists"

.PHONY: migrate-fresh
migrate-fresh: ## Run migrations and seed the database
Expand Down Expand Up @@ -89,6 +93,10 @@ setup: ## Setup the project
@php artisan storage:link --ansi
@composer run-script ide-helper

.PHONY: import-db
import-db: ## Import a PostgreSQL dump file (usage: make import-db file=path/to/dump)
@PGHOST=localhost PGUSER=postgres PGPASSWORD=postgres pg_restore -x -O -cC -j 8 -d postgres $(file)

.PHONY: bot
bot: ## Run the Discord bot
@php artisan bot:boot
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# He4rtBot Discord API
# he4rtdevs.com

<p align="center">
<a href="https://discord.gg/he4rt">
Expand Down
2 changes: 1 addition & 1 deletion app-modules/activity/src/Actions/NewMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function persist(NewMessageDTO $messageDTO): void
'tenant_id' => $messageDTO->tenantId,
'provider' => $messageDTO->provider,
'external_account_id' => $messageDTO->externalAccountId,
'model_type' => User::class,
'model_type' => (new User)->getMorphClass(),
'username' => $messageDTO->providerUsername,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public function handle(Message $message, Discord $discord): void

try {
$tenantProvider = ExternalIdentity::query()
->where('model_type', Tenant::class)
->where('model_type', (new Tenant)->getMorphClass())
->where('external_account_id', (string) $message->guild_id)
->firstOrFail();

Expand Down
4 changes: 2 additions & 2 deletions app-modules/bot-discord/src/Events/WelcomeMember.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function handle(Member $member, Discord $discord): void
$channelId = config('bot-discord.channels.auto-report');

$tenantProvider = ExternalIdentity::query()
->where('model_type', Tenant::class)
->where('model_type', (new Tenant)->getMorphClass())
->where('external_account_id', (string) $member->guild_id)
->firstOrFail();

Expand All @@ -34,7 +34,7 @@ public function handle(Member $member, Discord $discord): void
'tenant_id' => $tenantProvider->tenant_id,
'provider' => $tenantProvider->provider,
'external_account_id' => $member->user->id,
'model_type' => User::class,
'model_type' => (new User)->getMorphClass(),
'username' => $member->user->username,
'avatar' => $member->user->avatar,
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,21 @@ protected function getMemberProviderQuery(): Builder
{
return ExternalIdentity::query()
->where('tenant_id', $this->tenantProvider->tenant_id)
->where('model_type', User::class)
->where('model_type', (new User)->getMorphClass())
->where('provider', IdentityProvider::Discord);
}

private function beforePipeline(Interaction $interaction): void
{
$this->tenantProvider = ExternalIdentity::query()
->where('model_type', Tenant::class)
->where('model_type', (new Tenant)->getMorphClass())
->where('provider', IdentityProvider::Discord)
->where('external_account_id', $interaction->guild_id)
->first();

$this->memberProvider = ExternalIdentity::query()
->where('tenant_id', $this->tenantProvider->tenant_id)
->where('model_type', User::class)
->where('model_type', (new User)->getMorphClass())
->where('provider', IdentityProvider::Discord)
->where('external_account_id', $interaction->user->id)
->first();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ public function handle(Interaction $interaction): void
private function persistData(Interaction $interaction, Collection $components): void
{
$tenantProvider = ExternalIdentity::query()
->where('model_type', Tenant::class)
->where('model_type', (new Tenant)->getMorphClass())
->where('external_account_id', (string) $interaction->guild_id)
->firstOrFail();

$userDto = ResolveUserProviderDTO::make([
'tenant_id' => $tenantProvider->tenant_id,
'provider' => $tenantProvider->provider,
'external_account_id' => $interaction->user->id,
'model_type' => User::class,
'model_type' => (new User)->getMorphClass(),
'username' => $interaction->user->username,
'avatar' => $interaction->user->avatar,
]);
Expand Down
2 changes: 1 addition & 1 deletion app-modules/economy/database/factories/WalletFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ final class WalletFactory extends Factory
public function definition(): array
{
return [
'owner_type' => Character::class,
'owner_type' => (new Character)->getMorphClass(),
'owner_id' => Character::factory(),
'currency' => Currency::Coin,
'balance' => 0,
Expand Down
2 changes: 1 addition & 1 deletion app-modules/economy/tests/Feature/EconomyFlowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

expect($wallet->balance)->toBe(0)
->and($wallet->currency)->toBe(Currency::Coin)
->and($wallet->owner_type)->toBe(Character::class)
->and($wallet->owner_type)->toBe('character')
->and($wallet->owner_id)->toBe($character->id);

resolve(Credit::class)->handle(new CreditDTO(
Expand Down
4 changes: 2 additions & 2 deletions app-modules/events/database/factories/EventAgendaFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ public function definition(): array
public function forSegment(?EventSegment $segment = null)
{
return $this->state(fn () => [
'schedulable_type' => EventSegment::class,
'schedulable_type' => (new EventSegment)->getMorphClass(),
'schedulable_id' => $segment ?? EventSegment::query()->inRandomOrder()->first()->getKey(),
]);
}

public function forTalk(?EventSubmission $talk = null)
{
return $this->state(fn () => [
'schedulable_type' => EventSubmission::class,
'schedulable_type' => (new EventSubmission)->getMorphClass(),
'schedulable_id' => $talk ?? EventSubmission::factory(),
]);
}
Expand Down
6 changes: 2 additions & 4 deletions app-modules/events/src/Enums/SchedulableTypeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
use BackedEnum;
use Filament\Support\Contracts\HasIcon;
use Filament\Support\Icons\Heroicon;
use He4rt\Events\Models\EventSegment;
use He4rt\Events\Models\EventSubmission;

enum SchedulableTypeEnum: string implements HasIcon
{
case Submission = EventSubmission::class;
case Submission = 'event_submission';

case Segment = EventSegment::class;
case Segment = 'event_segment';

public function getIcon(): BackedEnum
{
Expand Down
2 changes: 2 additions & 0 deletions app-modules/events/src/Models/Sponsor.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class Sponsor extends Model implements HasMedia

protected $table = 'sponsors';

protected $keyType = 'string';

protected $fillable = [
'name',
'logo_path',
Expand Down
10 changes: 10 additions & 0 deletions app-modules/events/src/Providers/EventsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
use He4rt\Events\AdminEventPanelPlugin;
use He4rt\Events\AppEventPanelPlugin;
use He4rt\Events\EventPanelPlugin;
use He4rt\Events\Models\EventSegment;
use He4rt\Events\Models\EventSubmission;
use He4rt\Events\Models\Sponsor;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\ServiceProvider;

class EventsServiceProvider extends ServiceProvider
Expand All @@ -29,5 +33,11 @@ public function boot(): void
{
$this->loadMigrationsFrom(__DIR__.'/../../database/migrations');
$this->loadViewsFrom(__DIR__.'/../../resources/views', 'events');

Relation::morphMap([
'event_submission' => EventSubmission::class,
'event_segment' => EventSegment::class,
'sponsor' => Sponsor::class,
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use He4rt\Events\Enums\EventTypeEnum;
use He4rt\Events\Filament\Admin\Resources\Events\Pages\CreateEvent;
use He4rt\Events\Models\EventModel;
use He4rt\Identity\Tenant\Models\Tenant;
use Illuminate\Support\Facades\Date;

use function Pest\Laravel\assertDatabaseCount;
Expand All @@ -16,6 +17,7 @@
beforeEach(function (): void {
Filament::setCurrentPanel(FilamentPanel::Admin->value);
$this->actingAsAdmin();
$this->tenant = Tenant::query()->first();
});

it('should render', function (): void {
Expand All @@ -27,7 +29,7 @@
livewire(CreateEvent::class)
->assertOk()
->fillForm([
'tenant_id' => 1,
'tenant_id' => $this->tenant->getKey(),
'title' => 'event title',
'slug' => 'event-slug',
'description' => 'event description',
Expand All @@ -44,7 +46,7 @@

assertDatabaseCount(EventModel::class, 1);
assertDatabaseHas(EventModel::class, [
'tenant_id' => 1,
'tenant_id' => $this->tenant->getKey(),
'title' => 'event title',
'slug' => 'event-slug',
'location' => 'event location',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Filament\Facades\Filament;
use He4rt\Events\Filament\Resources\Sponsors\Pages\CreateSponsor;
use He4rt\Events\Models\Sponsor;
use He4rt\Identity\Tenant\Models\Tenant;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;

Expand All @@ -27,10 +28,12 @@
Filament::setCurrentPanel(FilamentPanel::Admin->value);
$this->actingAsAdmin();

$tenant = Tenant::query()->first();

livewire(CreateSponsor::class)
->assertOk()
->fillForm([
'tenant_id' => 1,
'tenant_id' => $tenant->getKey(),
'name' => 'sponsor name',
'receipt' => $image,
'homepage_url' => 'https://www.google.com',
Expand All @@ -41,7 +44,7 @@
assertDatabaseCount(Sponsor::class, 1);

assertDatabaseHas(Sponsor::class, [
'tenant_id' => 1,
'tenant_id' => $tenant->getKey(),
'name' => 'sponsor name',
'homepage_url' => 'https://www.google.com',
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@

it('should see Register or Join Waitlist based on status', function ($status, $text, $dontSeeText): void {
$this->events->each(function (EventModel $event) use ($status): void {
$attendeeIds = $event->attendees->pluck('id');
$event->attendees()->updateExistingPivot(
$attendeeIds,
['status' => $status]
);
foreach ($event->attendees as $attendee) {
$event->attendees()->updateExistingPivot(
$attendee->getKey(),
['status' => $status]
);
}
});

$this->events->fresh();
$this->events = $this->events->fresh();
livewire(ListEventModels::class, ['tenant' => $this->tenant->slug])
->assertOk()
->assertSeeText($text)
Expand All @@ -76,12 +77,14 @@

it('should be able to participate to an event', function (): void {
$event = $this->events->first();
$attendeeIds = $event->attendees->pluck('id');

$event->attendees()->updateExistingPivot(
$attendeeIds,
['status' => AttendingStatusEnum::Waitlist],
);
foreach ($event->attendees as $attendee) {
$event->attendees()->updateExistingPivot(
$attendee->getKey(),
['status' => AttendingStatusEnum::Waitlist],
);
}

livewire(ListEventModels::class, ['tenant' => $this->tenant->slug])
->assertOk()
->call('attend', $event->getKey())
Expand All @@ -92,17 +95,18 @@
);

expect($event->attendees()->count())->toBe(5)
->and($event->attendees()->get()->last()->getKey())->toBe(auth()->user()->getKey());
->and($event->isParticipating(auth()->user()->getKey()))->toBeTrue();
});

it('should go to waitlist', function (): void {
$event = $this->events->first();
$attendeeIds = $event->attendees->pluck('id');

$event->attendees()->updateExistingPivot(
$attendeeIds,
['status' => AttendingStatusEnum::Waitlist],
);
foreach ($event->attendees as $attendee) {
$event->attendees()->updateExistingPivot(
$attendee->getKey(),
['status' => AttendingStatusEnum::Waitlist],
);
}

livewire(ListEventModels::class, ['tenant' => $this->tenant->slug])
->assertOk()
Expand Down
Loading
Loading