From 211f93ec175d0f8b3b542c980e4bd63d81f3d729 Mon Sep 17 00:00:00 2001 From: philipp lang Date: Thu, 23 Feb 2023 00:38:17 +0100 Subject: [PATCH] Fix member resync --- app/Initialize/Actions/ProcessRedisAction.php | 34 --------------- app/Initialize/InitializeMembers.php | 14 ++++--- app/Member/Actions/InsertFullMemberAction.php | 23 +++++++++++ app/Member/Actions/MemberResyncAction.php | 12 ++---- app/Member/Data/FullMember.php | 25 +++++++++++ app/Nami/Api/CompleteMemberToRedisJob.php | 41 ------------------- app/Nami/Api/FullMemberAction.php | 30 ++++++++++++++ phpstan-baseline.neon | 41 ------------------- phpstan.neon | 35 +++++++++++++--- tests/Feature/Member/ResyncTest.php | 31 ++++++-------- 10 files changed, 132 insertions(+), 154 deletions(-) delete mode 100644 app/Initialize/Actions/ProcessRedisAction.php create mode 100644 app/Member/Actions/InsertFullMemberAction.php create mode 100644 app/Member/Data/FullMember.php delete mode 100644 app/Nami/Api/CompleteMemberToRedisJob.php create mode 100644 app/Nami/Api/FullMemberAction.php delete mode 100644 phpstan-baseline.neon diff --git a/app/Initialize/Actions/ProcessRedisAction.php b/app/Initialize/Actions/ProcessRedisAction.php deleted file mode 100644 index 6ecf7088..00000000 --- a/app/Initialize/Actions/ProcessRedisAction.php +++ /dev/null @@ -1,34 +0,0 @@ -, memberships: array, courses: array} $data - */ - public function handle(array $data): void - { - $localMember = InsertMemberAction::run(NamiMember::from($data['member'])); - InsertMembershipsAction::run( - $localMember, - collect($data['memberships'])->map(fn ($membership) => NamiMembershipEntry::from($membership)), - ); - InsertCoursesAction::run( - $localMember, - collect($data['courses'])->map(fn ($course) => NamiCourse::from($course)), - ); - } -} diff --git a/app/Initialize/InitializeMembers.php b/app/Initialize/InitializeMembers.php index 5f9fd0b7..c7e97bf9 100644 --- a/app/Initialize/InitializeMembers.php +++ b/app/Initialize/InitializeMembers.php @@ -2,8 +2,9 @@ namespace App\Initialize; -use App\Initialize\Actions\ProcessRedisAction; -use App\Nami\Api\CompleteMemberToRedisJob; +use App\Member\Actions\InsertFullMemberAction; +use App\Member\Data\FullMember; +use App\Nami\Api\FullMemberAction; use App\Setting\NamiSettings; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Redis; @@ -23,13 +24,16 @@ class InitializeMembers Redis::delete('members'); $jobs = $api->search([])->map(function (NamiMemberEntry $member) use ($api) { - return new CompleteMemberToRedisJob($api, $member->groupId, $member->id); + return FullMemberAction::makeJob($api, $member->groupId, $member->id, 'members'); })->toArray(); Bus::batch($jobs) ->finally(function () { - foreach (Redis::lrange('members', 0, -1) as $data) { - ProcessRedisAction::dispatch(json_decode($data, true)); + /** @var array */ + $members = array_map(fn ($member) => FullMember::from(json_decode($member, true)), Redis::lrange('members', 0, -1)); + + foreach ($members as $data) { + InsertFullMemberAction::dispatch($data); } }) ->onQueue('long') diff --git a/app/Member/Actions/InsertFullMemberAction.php b/app/Member/Actions/InsertFullMemberAction.php new file mode 100644 index 00000000..07ee6f71 --- /dev/null +++ b/app/Member/Actions/InsertFullMemberAction.php @@ -0,0 +1,23 @@ +member); + InsertMembershipsAction::run($localMember, $member->memberships->toCollection()); + InsertCoursesAction::run($localMember, $member->courses->toCollection()); + } +} diff --git a/app/Member/Actions/MemberResyncAction.php b/app/Member/Actions/MemberResyncAction.php index 31adb8c2..fa4f57dc 100644 --- a/app/Member/Actions/MemberResyncAction.php +++ b/app/Member/Actions/MemberResyncAction.php @@ -2,15 +2,13 @@ namespace App\Member\Actions; -use App\Actions\PullMemberAction; -use App\Actions\PullMembershipsAction; use App\Member\Member; +use App\Nami\Api\FullMemberAction; use App\Setting\NamiSettings; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; use Lorisleiva\Actions\ActionRequest; use Lorisleiva\Actions\Concerns\AsAction; -use Zoomyboy\LaravelNami\Exceptions\Skippable; class MemberResyncAction { @@ -24,13 +22,9 @@ class MemberResyncAction return; } - try { - $localMember = app(PullMemberAction::class)->handle($member->group->nami_id, $member->nami_id); - } catch (Skippable $e) { - return; - } + $fullMember = FullMemberAction::run($api, $member->group->nami_id, $member->nami_id); - app(PullMembershipsAction::class)->handle($localMember); + InsertFullMemberAction::dispatch($fullMember); } public function asController(ActionRequest $request, Member $member): RedirectResponse|Response diff --git a/app/Member/Data/FullMember.php b/app/Member/Data/FullMember.php new file mode 100644 index 00000000..2be8efb6 --- /dev/null +++ b/app/Member/Data/FullMember.php @@ -0,0 +1,25 @@ + $courses + * @param DataCollection $memberships + */ + public function __construct( + public NamiMember $member, + #[DataCollectionOf(NamiCourse::class)] + public DataCollection $courses, + #[DataCollectionOf(NamiMembershipEntry::class)] + public DataCollection $memberships, + ) {} +} + diff --git a/app/Nami/Api/CompleteMemberToRedisJob.php b/app/Nami/Api/CompleteMemberToRedisJob.php deleted file mode 100644 index 08ce4e0a..00000000 --- a/app/Nami/Api/CompleteMemberToRedisJob.php +++ /dev/null @@ -1,41 +0,0 @@ -batch()->cancelled()) { - return; - } - - Redis::rpush('members', collect([ - 'member' => MemberAction::run($this->api, $this->groupId, $this->memberId), - 'memberships' => MembershipsOfAction::run($this->api, $this->memberId), - 'courses' => CoursesOfAction::run($this->api, $this->memberId), - ])->toJson()); - } -} diff --git a/app/Nami/Api/FullMemberAction.php b/app/Nami/Api/FullMemberAction.php new file mode 100644 index 00000000..7831959e --- /dev/null +++ b/app/Nami/Api/FullMemberAction.php @@ -0,0 +1,30 @@ + MemberAction::run($api, $groupId, $memberId), + 'memberships' => MembershipsOfAction::run($api, $memberId), + 'courses' => CoursesOfAction::run($api, $memberId), + ]); + + if (!$redisKey) { + return $fullMember; + } + + Redis::rpush($redisKey, $fullMember->toJson()); + + return $fullMember; + } +} diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index 73308de5..00000000 --- a/phpstan-baseline.neon +++ /dev/null @@ -1,41 +0,0 @@ -parameters: - ignoreErrors: - - - message: "#^Parameter \\#1 \\$callback of method Illuminate\\\\Support\\\\LazyCollection\\\\:\\:each\\(\\) expects callable\\(int, int\\)\\: mixed, Closure\\(Zoomyboy\\\\LaravelNami\\\\Data\\\\MemberEntry\\)\\: void given\\.$#" - count: 1 - path: app/Initialize/InitializeMembers.php - - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:never\\(\\)\\.$#" - count: 1 - path: tests/Feature/Initialize/InitializeActionTest.php - - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:with\\(\\)\\.$#" - count: 1 - path: tests/Feature/Initialize/InitializeActionTest.php - - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:once\\(\\)\\.$#" - count: 10 - path: tests/Feature/Initialize/InitializeMembersTest.php - - - - message: "#^Parameter \\#1 \\$mock of static method Phake\\:\\:verify\\(\\) expects Phake\\\\IMock, App\\\\Actions\\\\PullMemberAction given\\.$#" - count: 1 - path: tests/Feature/Member/NamiPutMemberActionTest.php - - - - message: "#^Parameter \\#1 \\$mock of static method Phake\\:\\:verify\\(\\) expects Phake\\\\IMock, App\\\\Actions\\\\PullMembershipsAction given\\.$#" - count: 1 - path: tests/Feature/Member/NamiPutMemberActionTest.php - - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:never\\(\\)\\.$#" - count: 4 - path: tests/Feature/Member/ResyncTest.php - - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:once\\(\\)\\.$#" - count: 2 - path: tests/Feature/Member/ResyncTest.php diff --git a/phpstan.neon b/phpstan.neon index 35b83f66..58d46e93 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -599,13 +599,38 @@ parameters: count: 1 path: tests/Feature/Member/NamiPutMemberActionTest.php - - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:never\\(\\)\\.$#" - count: 4 - path: tests/Feature/Member/ResyncTest.php - - message: "#^Call to an undefined method Mockery\\\\ExpectationInterface\\|Mockery\\\\HigherOrderMessage\\:\\:once\\(\\)\\.$#" count: 2 path: tests/Feature/Member/ResyncTest.php + - + message: "#^Method App\\\\Region\\:\\:forSelect\\(\\) should return Illuminate\\\\Support\\\\Collection\\ but returns Illuminate\\\\Database\\\\Eloquent\\\\Collection\\\\.$#" + count: 1 + path: app/Region.php + + - + message: "#^Access to an undefined property Sabre\\\\VObject\\\\Component\\\\VCard\\:\\:\\$BDAY\\.$#" + count: 1 + path: tests/Feature/Member/DavTest.php + + - + message: "#^Access to an undefined property Sabre\\\\VObject\\\\Component\\\\VCard\\:\\:\\$FN\\.$#" + count: 1 + path: tests/Feature/Member/DavTest.php + + - + message: "#^Access to an undefined property Sabre\\\\VObject\\\\Component\\\\VCard\\:\\:\\$N\\.$#" + count: 1 + path: tests/Feature/Member/DavTest.php + + - + message: "#^Access to an undefined property Sabre\\\\VObject\\\\Component\\\\VCard\\:\\:\\$TEL\\.$#" + count: 1 + path: tests/Feature/Member/DavTest.php + + - + message: "#^Access to an undefined property Sabre\\\\VObject\\\\Component\\\\VCard\\:\\:\\$UID\\.$#" + count: 1 + path: tests/Feature/Member/DavTest.php + diff --git a/tests/Feature/Member/ResyncTest.php b/tests/Feature/Member/ResyncTest.php index 169bd64b..ee73237b 100644 --- a/tests/Feature/Member/ResyncTest.php +++ b/tests/Feature/Member/ResyncTest.php @@ -2,42 +2,35 @@ namespace Tests\Feature\Member; -use App\Actions\PullCoursesAction; -use App\Actions\PullMemberAction; -use App\Actions\PullMembershipsAction; use App\Group; +use App\Member\Actions\InsertFullMemberAction; +use App\Member\Data\FullMember; use App\Member\Member; +use App\Nami\Api\FullMemberAction; use Illuminate\Foundation\Testing\DatabaseTransactions; use Tests\TestCase; +use Zoomyboy\LaravelNami\Api; +use Zoomyboy\LaravelNami\Fakes\MemberFake; class ResyncTest extends TestCase { use DatabaseTransactions; + private Api $api; + public function testItCanResyncAMember(): void { + $this->api = $this->createStub(Api::class); $this->login()->loginNami(); + app(MemberFake::class)->shows(32, 33); + $fullMember = FullMember::from(['courses' => [], 'memberships' => [], 'member' => $this->api->member(32, 33)]); + FullMemberAction::shouldRun()->once()->andReturn($fullMember); + InsertFullMemberAction::shouldRun()->once(); $member = Member::factory()->defaults()->for(Group::factory()->inNami(32))->inNami(33)->create(); - PullMemberAction::shouldRun()->once()->with(32, 33)->andReturn($member); - PullMembershipsAction::shouldRun()->once()->with($member); - PullCoursesAction::shouldRun()->never(); $response = $this->from('/member')->get(route('member.resync', ['member' => $member])); $response->assertRedirect('/member'); } - public function testItReturnsErrorWhenMemberIsNotInNami(): void - { - $this->login()->loginNami(); - $member = Member::factory()->defaults()->create(); - - PullMemberAction::shouldRun()->never(); - PullMembershipsAction::shouldRun()->never(); - PullCoursesAction::shouldRun()->never(); - - $response = $this->from('/member')->get(route('member.resync', ['member' => $member])); - - $response->assertRedirect('/member'); - } }