diff --git a/app/Maildispatcher/Actions/ResyncAction.php b/app/Maildispatcher/Actions/ResyncAction.php index 671d2434..57f1dce0 100644 --- a/app/Maildispatcher/Actions/ResyncAction.php +++ b/app/Maildispatcher/Actions/ResyncAction.php @@ -27,6 +27,9 @@ class ResyncAction { return Member::search(data_get($dispatcher->filter, 'search', ''))->query( fn ($q) => $q->select('*')->withFilter(FilterScope::fromPost($dispatcher->filter)) - )->get()->filter(fn ($member) => $member->email || $member->email_parents)->map(fn ($member) => MailEntry::from(['email' => $member->email ?: $member->email_parents])); + )->get() + ->filter(fn ($member) => $member->email || $member->email_parents) + ->map(fn ($member) => MailEntry::from(['email' => $member->email ?: $member->email_parents])) + ->unique(fn ($member) => $member->email); } } diff --git a/tests/Feature/Maildispatcher/StoreTest.php b/tests/Feature/Maildispatcher/StoreTest.php index 47b850be..b6490f2c 100644 --- a/tests/Feature/Maildispatcher/StoreTest.php +++ b/tests/Feature/Maildispatcher/StoreTest.php @@ -2,6 +2,7 @@ namespace Tests\Feature\Maildispatcher; +use \Mockery as M; use App\Activity; use App\Maildispatcher\Models\Localmaildispatcher; use App\Maildispatcher\Models\Maildispatcher; @@ -50,6 +51,23 @@ class StoreTest extends TestCase ]); } + public function testItDoesntStoreTwoMembersWithSameEmailAddress(): void + { + $type = M::mock(LocalType::class)->makePartial(); + $type->shouldReceive('add')->once(); + app()->instance(LocalType::class, $type); + + $gateway = Mailgateway::factory()->type(LocalType::class, [])->domain('example.com')->create(); + Member::factory()->defaults()->create(['email' => 'jane@example.com']); + Member::factory()->defaults()->create(['email' => 'jane@example.com']); + + $this->postJson('/maildispatcher', [ + 'name' => 'test', + 'gateway_id' => $gateway->id, + 'filter' => [], + ]); + } + public function testMaildispatcherReceivesLowerVersionOfEmail(): void { $gateway = Mailgateway::factory()->type(LocalType::class, [])->create();