pp-planer/tests/Feature/AgendaMatcherServiceTest.php

160 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
use App\Models\ServiceAgendaItem;
use App\Services\AgendaMatcherService;
beforeEach(function () {
$this->service = new AgendaMatcherService;
});
// Exact match
test('matches exact title', function () {
expect($this->service->matches('Predigt', 'Predigt'))->toBeTrue();
});
// Wildcard suffix
test('matches wildcard suffix pattern', function () {
expect($this->service->matches('Predigt Thema XY', 'Predigt*'))->toBeTrue();
});
// Wildcard prefix
test('matches wildcard prefix pattern', function () {
expect($this->service->matches('Die Predigt', '*Predigt'))->toBeTrue();
});
// Wildcard both
test('matches wildcard both sides pattern', function () {
expect($this->service->matches('Die Predigt heute', '*Predigt*'))->toBeTrue();
});
// Case insensitive
test('matches case insensitive', function () {
expect($this->service->matches('Predigt Thema', 'predigt*'))->toBeTrue();
});
// No match
test('does not match unrelated title', function () {
expect($this->service->matches('Lobpreis', 'Predigt*'))->toBeFalse();
});
// Multiple patterns — matchesAny
test('matchesAny returns true if any pattern matches', function () {
$patterns = ['Predigt*', 'Sermon*'];
expect($this->service->matchesAny('Predigt Thema', $patterns))->toBeTrue();
});
test('matchesAny returns false if no pattern matches', function () {
$patterns = ['Predigt*', 'Sermon*'];
expect($this->service->matchesAny('Lobpreis', $patterns))->toBeFalse();
});
// findFirstMatch returns matching item
test('findFirstMatch returns first matching ServiceAgendaItem', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Lobpreis']),
ServiceAgendaItem::factory()->create(['title' => 'Predigt Thema']),
ServiceAgendaItem::factory()->create(['title' => 'Gebet']),
];
$result = $this->service->findFirstMatch($items, 'Predigt*');
expect($result)->toBeInstanceOf(ServiceAgendaItem::class);
expect($result->title)->toBe('Predigt Thema');
});
test('findFirstMatch returns null when no match', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Lobpreis']),
ServiceAgendaItem::factory()->create(['title' => 'Gebet']),
];
$result = $this->service->findFirstMatch($items, 'Predigt*');
expect($result)->toBeNull();
});
// filterBetween with both start and end
test('filterBetween filters items between start and end (both excluded)', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Info']),
ServiceAgendaItem::factory()->create(['title' => 'Start']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 1']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 2']),
ServiceAgendaItem::factory()->create(['title' => 'End']),
ServiceAgendaItem::factory()->create(['title' => 'Segen']),
];
$result = $this->service->filterBetween($items, 'Start', 'End');
expect($result)->toHaveCount(2);
expect($result[0]->title)->toBe('Lied 1');
expect($result[1]->title)->toBe('Lied 2');
});
// filterBetween with start only
test('filterBetween from start boundary to end of items', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Info']),
ServiceAgendaItem::factory()->create(['title' => 'Start']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 1']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 2']),
];
$result = $this->service->filterBetween($items, 'Start', null);
expect($result)->toHaveCount(2);
expect($result[0]->title)->toBe('Lied 1');
expect($result[1]->title)->toBe('Lied 2');
});
// filterBetween with neither
test('filterBetween with no start or end patterns returns all items', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Info']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 1']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 2']),
];
$result = $this->service->filterBetween($items, null, null);
expect($result)->toHaveCount(3);
});
// filterBetween with no matching start
test('filterBetween with no matching start pattern returns empty array', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Lied 1']),
ServiceAgendaItem::factory()->create(['title' => 'Lied 2']),
];
$result = $this->service->filterBetween($items, 'Nonexistent*', null);
expect($result)->toBeEmpty();
});
// findFirstMatch with comma-separated patterns
test('findFirstMatch splits comma-separated patterns and matches', function () {
$items = [
ServiceAgendaItem::factory()->create(['title' => 'Lobpreis']),
ServiceAgendaItem::factory()->create(['title' => 'Predigt Thema']),
];
$result = $this->service->findFirstMatch($items, 'Lied*,Predigt*');
expect($result)->toBeInstanceOf(ServiceAgendaItem::class);
expect($result->title)->toBe('Predigt Thema');
});
// Edge case: empty items array
test('findFirstMatch with empty items returns null', function () {
$result = $this->service->findFirstMatch([], 'Predigt*');
expect($result)->toBeNull();
});
test('filterBetween with empty items returns empty array', function () {
$result = $this->service->filterBetween([], 'Start', 'End');
expect($result)->toBeEmpty();
});