published() ->forPortal($portal) ->for(Company::factory()->state(['portal' => $portal->value])) ->create(array_merge([ 'slug' => $slug, 'language' => $language, 'published_at' => now()->subDay(), ], $attributes)); } test('the same slug on both portals resolves to the release of the reported host', function () { /** @var TestCase $this */ $presseecho = resolverRelease(Portal::Presseecho, 'gleicher-slug'); $businessportal = resolverRelease(Portal::Businessportal24, 'gleicher-slug'); $resolver = app(ReportedUrlResolver::class); expect($resolver->resolve('https://presseecho.test/de/press-release/gleicher-slug')?->id)->toBe($presseecho->id) ->and($resolver->resolve('https://businessportal24.test/de/press-release/gleicher-slug')?->id)->toBe($businessportal->id); }); test('the same slug in both editions resolves to the release of the reported edition', function () { /** @var TestCase $this */ $german = resolverRelease(Portal::Presseecho, 'zwei-sprachen', 'de'); $english = resolverRelease(Portal::Presseecho, 'zwei-sprachen', 'en'); $resolver = app(ReportedUrlResolver::class); expect($resolver->resolve('https://presseecho.test/en/press-release/zwei-sprachen')?->id)->toBe($english->id) ->and($resolver->resolve('https://presseecho.test/de/press-release/zwei-sprachen')?->id)->toBe($german->id) // Ohne Ausgabe im Pfad gilt die Standard-Ausgabe (SetEdition). ->and($resolver->resolve('https://presseecho.test/press-release/zwei-sprachen')?->id)->toBe($german->id); }); test('a foreign host with a matching path resolves to nothing', function () { /** @var TestCase $this */ resolverRelease(Portal::Presseecho, 'fremder-host'); $resolver = app(ReportedUrlResolver::class); expect($resolver->resolve('https://example.com/de/press-release/fremder-host'))->toBeNull() ->and($resolver->resolve('https://presseecho.test.evil.example/de/press-release/fremder-host'))->toBeNull() // Der Hub liefert keine Meldungen aus, er leitet auf das Portal um. ->and($resolver->resolve('https://pressekonto.test/de/press-release/fremder-host'))->toBeNull() ->and($resolver->resolve('kein-url'))->toBeNull(); }); test('a www host and an url-encoded slug still resolve', function () { /** @var TestCase $this */ $release = resolverRelease(Portal::Businessportal24, 'kaffee-kuchen'); $resolver = app(ReportedUrlResolver::class); expect($resolver->resolve('https://www.businessportal24.test/de/press-release/kaffee%2Dkuchen?utm_source=x#top')?->id)->toBe($release->id); }); test('deleted, scheduled and unpublished releases resolve to nothing', function () { /** @var TestCase $this */ resolverRelease(Portal::Presseecho, 'geloescht')->delete(); resolverRelease(Portal::Presseecho, 'terminiert', 'de', ['published_at' => now()->addDay()]); PressRelease::factory()->forPortal(Portal::Presseecho)->create(['slug' => 'entwurf', 'language' => 'de']); $resolver = app(ReportedUrlResolver::class); expect($resolver->resolve('https://presseecho.test/de/press-release/geloescht'))->toBeNull() ->and($resolver->resolve('https://presseecho.test/de/press-release/terminiert'))->toBeNull() ->and($resolver->resolve('https://presseecho.test/de/press-release/entwurf'))->toBeNull(); }); test('a portal-wide copy loses against the canonical release with the same slug', function () { /** @var TestCase $this */ $canonical = resolverRelease(Portal::Presseecho, 'doppelt'); $copy = resolverRelease(Portal::Both, 'doppelt', 'de', ['canonical_press_release_id' => $canonical->id]); expect($copy->id)->toBeGreaterThan($canonical->id) ->and(app(ReportedUrlResolver::class)->resolve('https://presseecho.test/de/press-release/doppelt')?->id)->toBe($canonical->id); });