makeEngagement(['portal_token' => hash('sha256', $plain)]); $resolved = (new ArtistResolver)->fromPortalToken($plain); $this->assertSame($engagement->artist_id, $resolved->subject->id); $this->assertSame((string) $engagement->event_id, $resolved->eventId); $this->assertSame($engagement->id, $resolved->engagement->id); } public function test_invalid_token_throws_invalid_portal_token(): void { $this->expectException(InvalidPortalTokenException::class); (new ArtistResolver)->fromPortalToken('not-a-real-token'); } public function test_engagement_with_soft_deleted_artist_throws_artist_deleted(): void { $plain = (string) Str::ulid(); $engagement = $this->makeEngagement(['portal_token' => hash('sha256', $plain)]); Artist::query() ->withoutGlobalScope(OrganisationScope::class) ->whereKey($engagement->artist_id) ->delete(); try { (new ArtistResolver)->fromPortalToken($plain); $this->fail('Expected ArtistDeletedException'); } catch (ArtistDeletedException $e) { $this->assertSame((string) $engagement->id, $e->engagementId); } } public function test_token_uses_sha256_digest_lookup(): void { $plain = 'plain-text-token'; $digest = hash('sha256', $plain); $engagement = $this->makeEngagement(['portal_token' => $digest]); $resolved = (new ArtistResolver)->fromPortalToken($plain); $this->assertSame($engagement->id, $resolved->engagement->id); } /** * @param array $overrides */ private function makeEngagement(array $overrides = []): ArtistEngagement { $org = Organisation::factory()->create(); $event = Event::factory()->for($org)->create(); $artist = Artist::factory()->for($org)->create(); return ArtistEngagement::factory()->create(array_merge([ 'organisation_id' => $org->id, 'artist_id' => $artist->id, 'event_id' => $event->id, ], $overrides)); } }