Snapshot of main at 9f39a6e1e (2026-11-02)
This commit is contained in:
commit
6ccf1792d7
2580 files changed
+1040202
No files matched your search
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Polls;
|
||||
|
||||
use App\Models\Organization;
|
||||
use App\Models\Poll;
|
||||
use App\Models\PollAnswer;
|
||||
use App\Models\PollQuestion;
|
||||
use App\Models\PollResponse;
|
||||
use App\Models\Post;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* Relations, cascades and the one-vote unique index of the poll tables.
|
||||
*/
|
||||
class PollModelTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
// phpunit.xml configures Redis, which is the dev site's cache too
|
||||
config(['cache.default' => 'array']);
|
||||
}
|
||||
|
||||
private function makePoll(array $attributes = []): Poll
|
||||
{
|
||||
// Inserted directly: Post is Searchable and would sync to Elasticsearch
|
||||
$postId = DB::table('posts')->insertGetId([
|
||||
'postable_id' => 1,
|
||||
'postable_type' => 'App\Models\Admin',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
return Poll::create(array_merge(['post_id' => $postId, 'status' => Poll::STATUS_OPEN], $attributes));
|
||||
}
|
||||
|
||||
private function vote(Poll $poll, $profile, User $user): PollResponse
|
||||
{
|
||||
return PollResponse::create([
|
||||
'poll_id' => $poll->id,
|
||||
'voter_id' => $profile->id,
|
||||
'voter_type' => get_class($profile),
|
||||
'user_id' => $user->id,
|
||||
'dedupe_key' => $poll->dedupeKey($profile, $user->id),
|
||||
'submitted_at' => now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_relations_and_casts(): void
|
||||
{
|
||||
$poll = $this->makePoll(['target_profile_types' => [User::class]]);
|
||||
$question = PollQuestion::create([
|
||||
'poll_id' => $poll->id,
|
||||
'type' => 'single_choice',
|
||||
'label' => ['en' => 'Which day?', 'nl' => 'Welke dag?'],
|
||||
'settings' => ['options' => ['mon' => 'Monday']],
|
||||
]);
|
||||
$user = User::factory()->create();
|
||||
$response = $this->vote($poll, $user, $user);
|
||||
PollAnswer::create([
|
||||
'poll_response_id' => $response->id,
|
||||
'poll_question_id' => $question->id,
|
||||
'value' => ['mon'],
|
||||
]);
|
||||
|
||||
$post = Post::find($poll->post_id);
|
||||
$this->assertTrue($post->poll->is($poll));
|
||||
$this->assertSame([User::class], $poll->fresh()->target_profile_types);
|
||||
$this->assertSame('Welke dag?', $question->labelFor('nl'));
|
||||
$this->assertSame('Which day?', $question->labelFor('de')); // fallback locale
|
||||
$this->assertTrue($response->voter->is($user));
|
||||
$this->assertSame(['mon'], $poll->responses->first()->answers->first()->value);
|
||||
$this->assertTrue($poll->hasResponses());
|
||||
}
|
||||
|
||||
public function test_is_open_respects_status_and_window(): void
|
||||
{
|
||||
$this->assertTrue($this->makePoll()->isOpen());
|
||||
$this->assertFalse($this->makePoll(['status' => Poll::STATUS_DRAFT])->isOpen());
|
||||
$this->assertFalse($this->makePoll(['opens_at' => now()->addDay()])->isOpen());
|
||||
$this->assertFalse($this->makePoll(['closes_at' => now()->subMinute()])->isOpen());
|
||||
}
|
||||
|
||||
public function test_per_profile_poll_allows_one_vote_per_organization(): void
|
||||
{
|
||||
$poll = $this->makePoll(['vote_scope' => Poll::VOTE_SCOPE_PER_PROFILE]);
|
||||
$organization = Organization::factory()->create();
|
||||
[$manager1, $manager2] = User::factory()->count(2)->create();
|
||||
|
||||
$this->vote($poll, $organization, $manager1);
|
||||
|
||||
$this->expectException(QueryException::class);
|
||||
$this->vote($poll, $organization, $manager2);
|
||||
}
|
||||
|
||||
public function test_per_user_poll_allows_one_vote_per_user_behind_organization(): void
|
||||
{
|
||||
$poll = $this->makePoll(['vote_scope' => Poll::VOTE_SCOPE_PER_USER]);
|
||||
$organization = Organization::factory()->create();
|
||||
[$manager1, $manager2] = User::factory()->count(2)->create();
|
||||
|
||||
$this->vote($poll, $organization, $manager1);
|
||||
$this->vote($poll, $organization, $manager2);
|
||||
$this->assertSame(2, $poll->responses()->count());
|
||||
|
||||
$this->expectException(QueryException::class);
|
||||
$this->vote($poll, $organization, $manager1);
|
||||
}
|
||||
|
||||
public function test_deleting_user_or_post_removes_votes(): void
|
||||
{
|
||||
$poll = $this->makePoll();
|
||||
$user = User::factory()->create();
|
||||
$this->vote($poll, $user, $user);
|
||||
|
||||
DB::table('users')->where('id', $user->id)->delete();
|
||||
$this->assertSame(0, $poll->responses()->count());
|
||||
|
||||
$this->vote($poll, $other = User::factory()->create(), $other);
|
||||
DB::table('posts')->where('id', $poll->post_id)->delete();
|
||||
$this->assertSame(0, PollResponse::where('user_id', $other->id)->count());
|
||||
$this->assertNull(Poll::withTrashed()->find($poll->id));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user