diff --git a/docker-compose.yml b/docker-compose.yml
index aa27c717..bea7193b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -103,6 +103,8 @@ services:
- ./data/redis:/data
meilisearch:
+ ports:
+ - "7700:7700"
image: getmeili/meilisearch:v1.6
volumes:
- ./data/meilisearch:/meili_data
diff --git a/phpstan.neon b/phpstan.neon
index 3d85785d..0271ef9e 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -68,11 +68,6 @@ parameters:
count: 1
path: app/Member/MemberRequest.php
- -
- message: "#^Method App\\\\Membership\\\\MembershipResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: app/Membership/MembershipResource.php
-
-
message: "#^Method App\\\\Payment\\\\SubscriptionResource\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
diff --git a/resources/css/table.css b/resources/css/table.css
index 518bb1bd..9c62e2a4 100644
--- a/resources/css/table.css
+++ b/resources/css/table.css
@@ -1,10 +1,10 @@
.custom-table {
width: 100%;
- & > thead > th {
+ & > thead > th, & > thead > tr > th {
@apply text-left px-6 text-gray-200 font-semibold py-3 border-gray-600 border-b;
}
- & > tr {
+ & > tr, & > tbody > tr {
@apply text-gray-200 transition-all duration-300 rounded hover:bg-gray-800;
& > td {
@apply py-1 px-6;
@@ -12,10 +12,10 @@
}
&.custom-table-sm {
- & > thead > th {
+ & > thead > th, & > thead > tr > th {
@apply px-3 py-2;
}
- & > tr {
+ & > tr, & > tbody > tr {
& > td {
@apply py-1 px-3;
}
@@ -32,11 +32,4 @@
}
}
}
-
-}
-.custom-table > * {
- display: table-row;
-}
-.custom-table > * > * {
- display: table-cell;
}
diff --git a/resources/js/components/ui/ActionButton.vue b/resources/js/components/ui/ActionButton.vue
index f36695d3..5e6e0b99 100644
--- a/resources/js/components/ui/ActionButton.vue
+++ b/resources/js/components/ui/ActionButton.vue
@@ -1,28 +1,14 @@
-
+
-
diff --git a/resources/js/components/ui/Sprite.vue b/resources/js/components/ui/Sprite.vue
index 0ddccd81..f18d47bf 100644
--- a/resources/js/components/ui/Sprite.vue
+++ b/resources/js/components/ui/Sprite.vue
@@ -2,6 +2,5 @@
-
diff --git a/resources/js/components/ui/Tabs.vue b/resources/js/components/ui/Tabs.vue
index aa20be4b..3a73ca0c 100644
--- a/resources/js/components/ui/Tabs.vue
+++ b/resources/js/components/ui/Tabs.vue
@@ -9,7 +9,7 @@
-
diff --git a/tests/Feature/Member/ShowTest.php b/tests/Feature/Member/ShowTest.php
index 63efc7ab..24d640ae 100644
--- a/tests/Feature/Member/ShowTest.php
+++ b/tests/Feature/Member/ShowTest.php
@@ -7,10 +7,12 @@ use App\Course\Models\Course;
use App\Course\Models\CourseMember;
use App\Gender;
use App\Group;
+use App\Invoice\BillKind;
use App\Invoice\Models\Invoice;
use App\Invoice\Models\InvoicePosition;
use App\Member\Data\MembershipData;
use App\Member\Member;
+use App\Member\MemberResource;
use App\Member\Membership;
use App\Nationality;
use App\Payment\Subscription;
@@ -25,7 +27,28 @@ beforeEach(function () {
Country::factory()->create(['name' => 'Deutschland']);
});
-it('testItShowsSingleMember', function () {
+covers(MemberResource::class);
+covers(MembershipData::class);
+
+it('shows courses', function () {
+ $this->withoutExceptionHandling()->login()->loginNami();
+ $member = Member::factory()
+ ->defaults()
+ ->has(CourseMember::factory()
+ ->for(Course::factory()->name(' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention '))
+ ->state(['organizer' => 'DPSG', 'event_name' => 'Wochenende', 'completed_at' => '2022-03-03']),
+ 'courses')
+ ->create();
+
+ $this->get("/member/{$member->id}")
+ ->assertInertiaPath('data.courses.0.organizer', 'DPSG')
+ ->assertInertiaPath('data.courses.0.event_name', 'Wochenende')
+ ->assertInertiaPath('data.courses.0.completed_at_human', '03.03.2022')
+ ->assertInertiaPath('data.courses.0.course.name', ' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention ')
+ ->assertInertiaPath('data.courses.0.course.short_name', '2e');
+});
+
+it('shows memberships', function () {
Carbon::setTestNow(Carbon::parse('2006-01-01 15:00:00'));
$this->withoutExceptionHandling()->login()->loginNami();
@@ -33,143 +56,96 @@ it('testItShowsSingleMember', function () {
->defaults()
->for(Group::factory()->name('Stamm Beispiel'))
->has(Membership::factory()->promise(now())->in('€ LeiterIn', 5, 'Jungpfadfinder', 88)->from('2022-11-19'))
- ->has(InvoicePosition::factory()->for(Invoice::factory())->price(1050)->description('uu'))
- ->for(Gender::factory()->male())
- ->for(Region::factory()->name('NRW'))
- ->postBillKind()
- ->inNami(123)
- ->for(Subscription::factory()->name('Sub')->forFee())
- ->has(CourseMember::factory()->for(Course::factory()->name(' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention '))->state(['organizer' => 'DPSG', 'event_name' => 'Wochenende', 'completed_at' => '2022-03-03']), 'courses')
- ->create([
- 'birthday' => '1991-04-20',
- 'address' => 'Itterstr 3',
- 'zip' => '42719',
- 'location' => 'Solingen',
- 'firstname' => 'Max',
- 'lastname' => 'Muster',
- 'other_country' => 'other',
- 'main_phone' => '+49 212 1266775',
- 'mobile_phone' => '+49 212 1266776',
- 'work_phone' => '+49 212 1266777',
- 'children_phone' => '+49 212 1266778',
- 'email' => 'a@b.de',
- 'email_parents' => 'b@c.de',
- 'fax' => '+49 212 1255674',
- 'efz' => '2022-09-20',
- 'ps_at' => '2022-04-20',
- 'more_ps_at' => '2022-06-02',
- 'recertified_at' => '2022-06-13',
- 'without_education_at' => '2022-06-03',
- 'without_efz_at' => '2022-06-04',
- 'has_vk' => true,
- 'has_svk' => true,
- 'multiply_pv' => true,
- 'multiply_more_pv' => true,
- 'send_newspaper' => true,
- 'joined_at' => '2022-06-11',
- 'mitgliedsnr' => 998,
- 'lon' => 19.05,
- 'lat' => 14.053,
- ]);
+ ->create();
- $response = $this->get("/member/{$member->id}");
-
- $this->assertInertiaHas([
- 'birthday_human' => '20.04.1991',
- 'age' => 14,
- 'group_name' => 'Stamm Beispiel',
- 'full_address' => 'Itterstr 3, 42719 Solingen',
- 'region' => ['name' => 'NRW'],
- 'other_country' => 'other',
- 'main_phone' => '+49 212 1266775',
- 'mobile_phone' => '+49 212 1266776',
- 'work_phone' => '+49 212 1266777',
- 'children_phone' => '+49 212 1266778',
- 'email' => 'a@b.de',
- 'email_parents' => 'b@c.de',
- 'fax' => '+49 212 1255674',
- 'fullname' => 'Herr Max Muster',
- 'efz_human' => '20.09.2022',
- 'ps_at_human' => '20.04.2022',
- 'more_ps_at_human' => '02.06.2022',
- 'without_education_at_human' => '03.06.2022',
- 'without_efz_at_human' => '04.06.2022',
- 'recertified_at_human' => '13.06.2022',
- 'has_vk' => true,
- 'has_svk' => true,
- 'multiply_pv' => true,
- 'multiply_more_pv' => true,
- 'has_nami' => true,
- 'nami_id' => 123,
- 'send_newspaper' => true,
- 'joined_at_human' => '11.06.2022',
- 'bill_kind_name' => 'Post',
- 'mitgliedsnr' => 998,
- 'lon' => 19.05,
- 'lat' => 14.053,
- 'subscription' => [
- 'name' => 'Sub',
- ],
- ], $response, 'data');
- $this->assertInertiaHas([
- 'id' => $member->memberships->first()->id,
- 'from' => ['human' => '19.11.2022', 'raw' => '2022-11-19'],
- 'promised_at' => ['human' => now()->format('d.m.Y'), 'raw' => now()->format('Y-m-d')],
- 'activity' => [
- 'name' => '€ LeiterIn',
- 'id' => $member->memberships->first()->activity->id,
- ],
- 'subactivity' => [
- 'name' => 'Jungpfadfinder',
- 'id' => $member->memberships->first()->subactivity->id,
- ]
- ], $response, 'data.memberships.0');
-
- $this->assertInertiaHas([
- 'organizer' => 'DPSG',
- 'event_name' => 'Wochenende',
- 'completed_at_human' => '03.03.2022',
- 'course' => [
- 'name' => ' Baustein 2e - Gewalt gegen Kinder und Jugendliche: Vertiefung, Prävention ',
- 'short_name' => '2e',
- ],
- ], $response, 'data.courses.0');
- $this->assertInertiaHas([
- 'description' => 'uu',
- 'price_human' => '10,50 €',
- 'invoice' => [
- 'status' => 'Neu',
- ]
- ], $response, 'data.invoicePositions.0');
+ $this->get("/member/{$member->id}")
+ ->assertInertiaPath('data.memberships.0.id', $member->memberships->first()->id)
+ ->assertInertiaPath('data.memberships.0.from.human', '19.11.2022')
+ ->assertInertiaPath('data.memberships.0.from.raw', '2022-11-19')
+ ->assertInertiaPath('data.memberships.0.promised_at.human', now()->format('d.m.Y'))
+ ->assertInertiaPath('data.memberships.0.promised_at.raw', now()->format('Y-m-d'))
+ ->assertInertiaPath('data.memberships.0.activity.name', '€ LeiterIn')
+ ->assertInertiaPath('data.memberships.0.activity.id',$member->memberships->first()->activity->id)
+ ->assertInertiaPath('data.memberships.0.subactivity.name', 'Jungpfadfinder')
+ ->assertInertiaPath('data.memberships.0.subactivity.id',$member->memberships->first()->subactivity->id);
});
-it('testItShowsMinimalSingleMember', function () {
+it('shows invoice positions', function () {
+ Carbon::setTestNow(Carbon::parse('2006-01-01 15:00:00'));
+
+ $this->withoutExceptionHandling()->login()->loginNami();
+ $member = Member::factory()
+ ->defaults()
+ ->for(Group::factory()->name('Stamm Beispiel'))
+ ->has(InvoicePosition::factory()->for(Invoice::factory())->price(1050)->description('uu'))
+ ->create();
+
+ $this->get("/member/{$member->id}")
+ ->assertInertiaPath('data.invoicePositions.0.description', 'uu')
+ ->assertInertiaPath('data.invoicePositions.0.price_human', '10,50 €')
+ ->assertInertiaPath('data.invoicePositions.0.invoice.status', 'Neu');
+});
+
+it('shows member', function (array $attributes, array $expect) {
+ Carbon::setTestNow(Carbon::parse('2006-01-01 15:00:00'));
$this->withoutExceptionHandling()->login()->loginNami();
$member = Member::factory()
->for(Group::factory())
->for(Nationality::factory()->name('deutsch'))
->for(Subscription::factory()->forFee())
- ->create(['firstname' => 'Max', 'lastname' => 'Muster', 'has_vk' => false, 'has_svk' => false]);
+ ->create($attributes);
- $response = $this->get("/member/{$member->id}");
-
- $this->assertInertiaHas([
- 'region' => ['name' => '-- kein --'],
- 'fullname' => 'Max Muster',
- 'nationality' => [
- 'name' => 'deutsch',
- ],
- 'efz_human' => null,
- 'ps_at_human' => null,
- 'more_ps_at_human' => null,
- 'without_education_at_human' => null,
- 'without_efz_at_human' => null,
- 'has_vk' => false,
- 'has_svk' => false,
- 'multiply_pv' => false,
- 'multiply_more_pv' => false,
- ], $response, 'data');
-});
+ $this->get("/member/{$member->id}")
+ ->assertInertiaPath('data.id', $member->id)
+ ->assertInertiaPathArray($expect);
+})->with([
+ fn() => [['region_id' => Region::factory()->name('UUU')->create()->id], ['data.region.name' => 'UUU', 'data.region.id' => Region::first()->id]],
+ fn() => [['nationality_id' => Nationality::factory()->name('UUU')->create()->id], ['data.nationality.name' => 'UUU', 'data.nationality_id' => Nationality::first()->id, 'data.nationality.id' => Nationality::first()->id]],
+ fn() => [['group_id' => Group::factory()->name('UUU')->create()->id], ['data.group_name' => 'UUU']],
+ fn() => [['bill_kind' => BillKind::EMAIL->value], ['data.bill_kind_name' => 'E-Mail']],
+ fn() => [['subscription_id' => Subscription::factory()->name('Sub')->forFee()->create()], ['data.subscription.name' => 'Sub', 'data.subscription_id' => Subscription::first()->id]],
+ fn() => [['country_id' => Country::factory()->create(['name' => 'Sub'])->id], ['data.country_id' => Country::firstWhere('name', 'Sub')->id]],
+ fn () => [['firstname' => 'Max', 'lastname' => 'Muster', 'gender_id' => Gender::factory()->male()->create()->id], ['data.firstname' => 'Max', 'data.lastname' => 'Muster', 'data.fullname' => 'Herr Max Muster', 'data.gender_id' => Gender::first()->id]],
+ [['firstname' => 'Max', 'lastname' => 'Muster', 'gender_id' => null], ['data.fullname' => 'Max Muster']],
+ [['other_country' => 'other'], ['data.other_country' => 'other']],
+ [['further_address' => 'other'], ['data.further_address' => 'other']],
+ [['gender_id' => null], ['data.gender_name' => 'keine Angabe']],
+ [['birthday' => null], ['data.birthday' => null, 'data.birthday_human' => null]],
+ [['efz' => null], ['data.efz_human' => null]],
+ [['ps_at' => null], ['data.ps_at_human' => null]],
+ [['ps_at' => null], ['data.ps_at_human' => null]],
+ [['more_ps_at' => null], ['data.more_ps_at_human' => null]],
+ [['has_svk' => false], ['data.has_svk' => false]],
+ [['has_vk' => false], ['data.has_vk' => false]],
+ [['has_svk' => true], ['data.has_svk' => true]],
+ [['has_vk' => true], ['data.has_vk' => true]],
+ [['multiply_more_pv' => false], ['data.multiply_more_pv' => false]],
+ [['without_efz_at' => null], ['data.without_efz_at_human' => null]],
+ [['without_education_at' => null], ['data.without_education_at_human' => null]],
+ [['main_phone' => '+49 212 1266775'], ['data.main_phone' => '+49 212 1266775']],
+ [['mobile_phone' => '+49 212 1266776'], ['data.mobile_phone' => '+49 212 1266776']],
+ [['work_phone' => '+49 212 1266777'], ['data.work_phone' => '+49 212 1266777']],
+ [['children_phone' => '+49 212 1266778'], ['data.children_phone' => '+49 212 1266778']],
+ [['efz' => '2022-09-20'], ['data.efz_human' => '20.09.2022']],
+ [['ps_at' => '2022-04-20'], ['data.ps_at_human' => '20.04.2022']],
+ [['more_ps_at' => '2022-06-02'], ['data.more_ps_at_human' => '02.06.2022']],
+ [['without_education_at' => '03.06.2022'], ['data.without_education_at_human' => '03.06.2022']],
+ [['without_efz_at' => '2022-06-04'], ['data.without_efz_at_human' => '04.06.2022']],
+ [['recertified_at' => '2022-06-13'], ['data.recertified_at_human' => '13.06.2022']],
+ [['multiply_pv' => true], ['data.multiply_pv' => true]],
+ [['multiply_more_pv' => true], ['data.multiply_more_pv' => true]],
+ [['email' => 'a@b.de'], ['data.email' => 'a@b.de']],
+ [['email_parents' => 'b@c.de'], ['data.email_parents' => 'b@c.de']],
+ [['fax' => '+49 212 1255674'], ['data.fax' => '+49 212 1255674']],
+ [['nami_id' => 123], ['data.nami_id' => 123, 'data.has_nami' => true]],
+ [['send_newspaper' => true], ['data.send_newspaper' => true]],
+ [['address' => 'Itterstr 3', 'location' => 'Solingen', 'zip' => '42719'], ['data.location' => 'Solingen', 'data.address' => 'Itterstr 3', 'data.zip' => '42719', 'data.full_address' => 'Itterstr 3, 42719 Solingen']],
+ [['lon' => 19.05], ['data.lon' => 19.05]],
+ [['lat' => 14.053], ['data.lat' => 14.053]],
+ [['birthday' => '1991-04-20'], ['data.birthday' => '1991-04-20', 'data.birthday_human' => '20.04.1991', 'data.age' => 14]],
+ [['joined_at' => '2022-06-11'], ['data.joined_at' => '2022-06-11', 'data.joined_at_human' => '11.06.2022']],
+ [['mitgliedsnr' => 998], ['data.mitgliedsnr' => 998]],
+]);
it('testItShowsIfMembershipIsActive', function (Carbon $from, ?Carbon $to, bool $isActive) {
$this->withoutExceptionHandling()->login()->loginNami();
diff --git a/tests/TestCase.php b/tests/TestCase.php
index dec5fdb2..6731b997 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -119,12 +119,24 @@ class TestCase extends BaseTestCase
/** @var TestResponse */
$response = $this;
$props = data_get($response->viewData('page'), 'props');
+ Assert::assertTrue(Arr::has($props, $path), 'Failed that key ' . $path . ' is in Response.');
Assert::assertNotNull($props);
$json = new AssertableJsonString($props);
$json->assertPath($path, $value);
return $this;
});
+ TestResponse::macro('assertInertiaPathArray', function ($arr) {
+ /** @var TestResponse */
+ $response = $this;
+
+ foreach ($arr as $key => $value) {
+ $response->assertInertiaPath($key, $value);
+ }
+
+ return $response;
+ });
+
TestResponse::macro('assertInertiaCount', function ($path, $count) {
/** @var TestResponse */
$response = $this;