Add membership entry

This commit is contained in:
philipp lang 2022-03-06 02:41:40 +01:00
parent b515f18b73
commit 33125a511a
6 changed files with 142 additions and 60 deletions

View File

@ -17,6 +17,7 @@ use Zoomyboy\LaravelNami\Concerns\IsNamiMember;
use Zoomyboy\LaravelNami\Data\Baustein; use Zoomyboy\LaravelNami\Data\Baustein;
use Zoomyboy\LaravelNami\Data\Course; use Zoomyboy\LaravelNami\Data\Course;
use Zoomyboy\LaravelNami\Data\Membership; use Zoomyboy\LaravelNami\Data\Membership;
use Zoomyboy\LaravelNami\Data\MembershipEntry;
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException; use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Exceptions\RightException; use Zoomyboy\LaravelNami\Exceptions\RightException;
use Zoomyboy\LaravelNami\NamiException; use Zoomyboy\LaravelNami\NamiException;
@ -163,7 +164,7 @@ class Api {
} }
/** /**
* @return Collection<Membership> * @return Collection<MembershipEntry>
*/ */
public function membershipsOf(int $memberId): Collection public function membershipsOf(int $memberId): Collection
{ {
@ -174,8 +175,7 @@ class Api {
'/ica/rest/nami/zugeordnete-taetigkeiten/filtered-for-navigation/gruppierung-mitglied/mitglied/'.$memberId.'/flist', '/ica/rest/nami/zugeordnete-taetigkeiten/filtered-for-navigation/gruppierung-mitglied/mitglied/'.$memberId.'/flist',
'Membership fetch failed' 'Membership fetch failed'
) )
->map(fn ($membership) => $this->membership($memberId, $membership['id'])) ->map(fn ($membership) => new MembershipEntry($membership));
->filter(fn ($membership) => $membership !== null);
} }
public function subactivitiesOf(int $activityId): Collection public function subactivitiesOf(int $activityId): Collection
@ -188,7 +188,7 @@ class Api {
)->map(fn ($subactivity) => Subactivity::fromNami($subactivity)); )->map(fn ($subactivity) => Subactivity::fromNami($subactivity));
} }
public function membership($memberId, $membershipId): ?Membership public function membership(int $memberId, int $membershipId): ?Membership
{ {
$this->assertLoggedIn(); $this->assertLoggedIn();
$membership = $this->fetchData( $membership = $this->fetchData(

View File

@ -0,0 +1,16 @@
<?php
namespace Zoomyboy\LaravelNami\Casters;
use Carbon\Carbon;
use Spatie\DataTransferObject\Caster;
class NullableString implements Caster {
public function cast(mixed $value): ?string
{
return $value ?: null;
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace Zoomyboy\LaravelNami\Data;
use Carbon\Carbon;
use Spatie\DataTransferObject\Attributes\CastWith;
use Spatie\DataTransferObject\Attributes\MapFrom;
use Spatie\DataTransferObject\DataTransferObject;
use Zoomyboy\LaravelNami\Casters\CarbonCaster;
use Zoomyboy\LaravelNami\Casters\NullableCarbonCaster;
use Zoomyboy\LaravelNami\Casters\NullableString;
class MembershipEntry extends DataTransferObject {
public ?int $id;
#[MapFrom('entries_gruppierung')]
public string $group;
#[MapFrom('entries_aktivVon')]
#[CastWith(CarbonCaster::class)]
public Carbon $startsAt;
#[MapFrom('entries_aktivBis')]
#[CastWith(NullableCarbonCaster::class)]
public ?Carbon $endsAt;
#[MapFrom('entries_taetigkeit')]
public string $activity;
#[MapFrom('entries_untergliederung')]
#[CastWith(NullableString::class)]
public ?string $subactivity;
}

View File

@ -12,7 +12,19 @@ class MembershipFake extends Fake {
Http::fake(function($request) use ($memberId, $membershipIds) { Http::fake(function($request) use ($memberId, $membershipIds) {
$url = 'https://nami.dpsg.de/ica/rest/nami/zugeordnete-taetigkeiten/filtered-for-navigation/gruppierung-mitglied/mitglied/'.$memberId.'/flist'; $url = 'https://nami.dpsg.de/ica/rest/nami/zugeordnete-taetigkeiten/filtered-for-navigation/gruppierung-mitglied/mitglied/'.$memberId.'/flist';
if ($request->url() === $url && $request->method() === 'GET') { if ($request->url() === $url && $request->method() === 'GET') {
return $this->collection(collect($membershipIds)->map(fn ($membershipId) => ['id' => $membershipId])); return $this->collection(collect($membershipIds)->map(function ($membership) {
return [
...[
'entries_aktivBis' => '2021-02-04 00:00:00',
'entries_aktivVon' => '2021-02-03 00:00:00',
'entries_untergliederung' => '::unter::',
'entries_taetigkeit' => 'Leiter (6)',
'id' => 55,
'entries_gruppierung' => '::group::',
],
...(is_array($membership) ? $membership : ['id' => $membership])
];
}));
} }
}); });

View File

@ -0,0 +1,65 @@
<?php
namespace Zoomyboy\LaravelNami\Tests\Unit\Api;
use Carbon\Carbon;
use Zoomyboy\LaravelNami\Data\Membership;
use Zoomyboy\LaravelNami\Data\MembershipEntry;
use Zoomyboy\LaravelNami\Exceptions\RightException;
use Zoomyboy\LaravelNami\Fakes\MembershipFake;
use Zoomyboy\LaravelNami\Nami;
use Zoomyboy\LaravelNami\NamiException;
use Zoomyboy\LaravelNami\Tests\TestCase;
class MembershipIndexTest extends TestCase
{
public function testGetMembershipsCount(): void
{
app(MembershipFake::class)->fetches(6, [10, 11]);
$memberships = $this->login()->membershipsOf(6);
$this->assertCount(2, $memberships);
}
public function testMembershipIsInstanceOfDto(): void
{
app(MembershipFake::class)
->fetches(6, [[
'entries_aktivBis' => '2021-02-04 00:00:00',
'entries_aktivVon' => '2021-02-03 00:00:00',
'entries_untergliederung' => '::unter::',
'entries_taetigkeit' => 'Leiter (6)',
'id' => 55,
'entries_gruppierung' => '::group::',
]]);
$membership = $this->login()->membershipsOf(6)->first();
$this->assertInstanceOf(MembershipEntry::class, $membership);
$this->assertSame(55, $membership->id);
$this->assertSame('2021-02-03 00:00:00', $membership->startsAt->toDateTimeString());
$this->assertSame('2021-02-04 00:00:00', $membership->endsAt->toDateTimeString());
$this->assertSame('::group::', $membership->group);
$this->assertSame('Leiter (6)', $membership->activity);
$this->assertSame('::unter::', $membership->subactivity);
}
public function testStringsCanBeNull(): void
{
app(MembershipFake::class)
->fetches(6, [[
'entries_aktivBis' => '',
'entries_untergliederung' => '',
]]);
$membership = $this->login()->membershipsOf(6)->first();
$this->assertNull($membership->endsAt);
$this->assertNull($membership->subactivity);
}
}

View File

@ -13,22 +13,9 @@ use Zoomyboy\LaravelNami\Tests\TestCase;
class MembershipTest extends TestCase class MembershipTest extends TestCase
{ {
public function testGetMembershipsCount(): void
{
app(MembershipFake::class)
->fetches(6, [10, 11])
->shows(6, ['id' => 10])
->shows(6, ['id' => 11]);
$memberships = $this->login()->membershipsOf(6);
$this->assertCount(2, $memberships);
}
public function testMembershipIsInstanceOfDto(): void public function testMembershipIsInstanceOfDto(): void
{ {
app(MembershipFake::class) app(MembershipFake::class)
->fetches(6, [10])
->shows(6, [ ->shows(6, [
'id' => 10, 'id' => 10,
'aktivBis' => '', 'aktivBis' => '',
@ -38,7 +25,7 @@ class MembershipTest extends TestCase
'untergliederungId' => 16, 'untergliederungId' => 16,
]); ]);
$membership = $this->login()->membershipsOf(6)->first(); $membership = $this->login()->membership(6, 10);
$this->assertInstanceOf(Membership::class, $membership); $this->assertInstanceOf(Membership::class, $membership);
$this->assertSame(10, $membership->id); $this->assertSame(10, $membership->id);
@ -51,62 +38,28 @@ class MembershipTest extends TestCase
public function testFetchesMembership(): void public function testFetchesMembership(): void
{ {
app(MembershipFake::class) app(MembershipFake::class)->shows(6, ['id' => 10]);
->fetches(6, [10])
->shows(6, ['id' => 10]);
$this->login()->membershipsOf(6); $this->login()->membership(6, 10);
app(MembershipFake::class)->assertFetched(6);
app(MembershipFake::class)->assertFetchedSingle(6, 10); app(MembershipFake::class)->assertFetchedSingle(6, 10);
} }
public function testThrowExceptionWhenFetchingFails(): void public function testThrowExceptionWhenFetchingFails(): void
{ {
app(MembershipFake::class)->failsFetching(6); app(MembershipFake::class)->failsShowing(6, 11);
$this->expectException(NamiException::class); $this->expectException(NamiException::class);
$this->login()->membershipsOf(6); $this->login()->membership(6, 11);
} }
public function testReturnsNothingWhenFetchingFailsWithHtml(): void public function testReturnsNothingWhenFetchingFailsWithHtml(): void
{ {
app(MembershipFake::class)->failsFetchingWithHtml(6); app(MembershipFake::class)->failsShowingWithHtml(6, 11);
$memberships = $this->login()->membershipsOf(6); $membership = $this->login()->membership(6, 11);
$this->assertCount(0, $memberships); $this->assertNull($membership);
}
public function testThrowExceptionWhenFetchingSingleFails(): void
{
app(MembershipFake::class)
->fetches(6, [55])
->failsShowing(6, 55);
$this->expectException(NamiException::class);
$this->login()->membershipsOf(6);
}
public function testDontReturnSingleThatReturnsHtml(): void
{
app(MembershipFake::class)
->fetches(6, [55, 66])
->shows(6, ['id' => 55])
->failsShowingWithHtml(6, 66);
$memberships = $this->login()->membershipsOf(6);
$this->assertCount(1, $memberships);
}
public function testItFetchesSingleMembership(): void
{
app(MembershipFake::class)->shows(16, [ "id" => 68 ]);
$membership = $this->login()->membership(16, 68);
$this->assertSame(68, $membership->id);
} }
/** /**