create(); $invitation = Invitation::create([ 'code' => 'test-invitation-code', 'email' => 'test@example.com', 'invited_by' => $user->id, 'expires_at' => now()->addDays(7) ]); expect($invitation->code)->toBe('test-invitation-code'); expect($invitation->email)->toBe('test@example.com'); expect($invitation->invited_by)->toBe($user->id); }); it('has status method that returns correct status', function () { $invitation = Invitation::factory()->create(['accepted_at' => null]); expect($invitation->status())->toBe('pending'); $invitation->update(['accepted_at' => now()]); expect($invitation->status())->toBe('accepted'); }); it('has isPending method that checks if invitation is pending', function () { $invitation = Invitation::factory()->create(['accepted_at' => null]); expect($invitation->isPending())->toBe(true); $invitation->update(['accepted_at' => now()]); expect($invitation->isPending())->toBe(false); }); it('can accept an invitation', function () { $invitation = Invitation::factory()->create(['accepted_at' => null]); expect($invitation->isPending())->toBe(true); $invitation->accept(); expect($invitation->isPending())->toBe(false); expect($invitation->accepted_at)->not()->toBeNull(); expect($invitation->status())->toBe('accepted'); }); it('belongs to a creator user', function () { $creator = User::factory()->create(); $invitation = Invitation::factory()->create(['invited_by' => $creator->id]); expect($invitation->creator)->toBeInstanceOf(User::class); expect($invitation->creator->id)->toBe($creator->id); }); it('generates invite URL correctly', function () { $invitation = Invitation::factory()->create(['code' => 'test-code-123']); $expectedUrl = route('register', ['code' => 'test-code-123']); expect($invitation->getInviteUrl())->toBe($expectedUrl); }); it('casts dates properly', function () { $invitation = Invitation::factory()->create([ 'expires_at' => '2024-01-01 12:00:00', 'accepted_at' => '2024-01-01 13:00:00' ]); expect($invitation->expires_at)->toBeInstanceOf(\Illuminate\Support\Carbon::class); expect($invitation->accepted_at)->toBeInstanceOf(\Illuminate\Support\Carbon::class); }); it('has fillable fields except id', function () { $invitation = new Invitation(); expect($invitation->getFillable())->not()->toContain('id'); // Since guarded is used with ['id'], all other fields should be fillable expect($invitation->getGuarded())->toBe(['id']); }); it('uses HasFactory trait', function () { expect(method_exists(Invitation::class, 'factory'))->toBe(true); expect(in_array('Illuminate\Database\Eloquent\Factories\HasFactory', class_uses(Invitation::class)))->toBe(true); }); it('can find invitation by code', function () { $invitation = Invitation::factory()->create(['code' => 'unique-code-456']); $found = Invitation::where('code', 'unique-code-456')->first(); expect($found)->not()->toBeNull(); expect($found->id)->toBe($invitation->id); }); it('can find invitation by email', function () { $invitation = Invitation::factory()->create(['email' => 'unique@test.com']); $found = Invitation::where('email', 'unique@test.com')->first(); expect($found)->not()->toBeNull(); expect($found->id)->toBe($invitation->id); }); it('can filter pending invitations', function () { $pendingInvitation = Invitation::factory()->create(['accepted_at' => null]); $acceptedInvitation = Invitation::factory()->create(['accepted_at' => now()]); $pending = Invitation::whereNull('accepted_at')->get(); expect($pending->count())->toBe(1); expect($pending->first()->id)->toBe($pendingInvitation->id); }); it('can filter accepted invitations', function () { $pendingInvitation = Invitation::factory()->create(['accepted_at' => null]); $acceptedInvitation = Invitation::factory()->create(['accepted_at' => now()]); $accepted = Invitation::whereNotNull('accepted_at')->get(); expect($accepted->count())->toBe(1); expect($accepted->first()->id)->toBe($acceptedInvitation->id); }); it('accept method persists to database', function () { $invitation = Invitation::factory()->create(['accepted_at' => null]); $invitation->accept(); // Refresh from database to verify it was persisted $invitation->refresh(); expect($invitation->accepted_at)->not()->toBeNull(); expect($invitation->isPending())->toBe(false); }); });