shouldReceive('user')->andReturn($customer); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->canWithCustomer('view-order'); // THEN expect($result)->toBeTrue(); }); it('returns false for abilities if customer is null', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $guard->shouldReceive('user')->andReturn(null); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->canWithCustomer('view-order'); // THEN expect($result)->toBeFalse(); }); it('logs in customer when active', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $customer->id = (string) Uuid::uuid7(); $shopperService->shouldReceive('canCustomerPassOrdersApp')->withAnyArgs()->andReturn(true); $guard->shouldReceive('login')->with($customer)->once(); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $service->logIn($customer); // THEN expect(true)->toBeTrue(); }); it('throws exception if logging in non-authenticatable', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $invalidCustomer = new class () implements CustomerDetails { }; $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $action = fn () => $service->logIn($invalidCustomer); // THEN expect($action)->toThrow(\InvalidArgumentException::class, 'Expected an instance of Authenticatable and Customer for logging in'); }); it('logs out', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $guard->shouldReceive('logout')->once(); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $service->logout(); // THEN expect(true)->toBeTrue(); }); it('checks if user is logged in', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $guard->shouldReceive('check')->andReturn(true); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $check = $service->check(); $guest = $service->guest(); // THEN expect($check)->toBeTrue() ->and($guest)->toBeFalse(); }); it('gets customer safely', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $guard->shouldReceive('user')->andReturn($customer); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $returned = $service->getCustomer(); // THEN expect($returned)->toBeInstanceOf(Customer::class) ->and($returned)->not->toBe($customer); // Should be a clone }); it('throws exception when customer is not a frontend Customer model', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $user = new class () implements Authenticatable { public function getAuthIdentifierName() { return 'id'; } public function getAuthIdentifier() { return 1; } public function getAuthPassword() { return 'password'; } public function getAuthPasswordName() { return 'password'; } public function getRememberToken() { return ''; } public function setRememberToken($value) { } public function getRememberTokenName() { return ''; } }; $guard->shouldReceive('user')->andReturn($user); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $action = fn () => $service->getCustomer(); // THEN expect($action)->toThrow(\InvalidArgumentException::class, 'Auth service needs a frontend guard'); }); it('gets customer as mandatory', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $guard->shouldReceive('user')->andReturn($customer); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $returned = $service->getCustomerAsMandatory(); // THEN expect($returned)->toBeInstanceOf(Customer::class); }); it('throws exception when getting customer as mandatory but null', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $guard->shouldReceive('user')->andReturn(null); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $action = fn () => $service->getCustomerAsMandatory(); // THEN expect($action)->toThrow(AuthServiceException::class, 'Authenticated user is required from here'); }); it('resets password', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $customer->email = new Email('test@example.com'); $crmService->shouldReceive('resetPasswordFor')->with($customer->email, 'newpass')->andReturn(true); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->resetPasswordFor($customer, 'newpass'); // THEN expect($result)->toBeTrue(); }); it('checks if email is verified', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $hashcode = new CrmHashcode(Uuid::uuid4()); $customer->hashcode = $hashcode; // DO NOT MOCK CrmCustomer $crmCustomer = new CrmCustomer( hashcode: $hashcode->value, email: 'test@example.com', password: 'password', firstname: 'John', lastname: 'Doe', birthDate: '1990-01-01', phone: '123456789', address: '123 Main St', address2: null, city: 'Paris', postcode: '75000', country: Country::france, optIn: true, status: true, lastConnection: null ); $crmService->shouldReceive('getCustomerFromHashCode')->with($customer->hashcode)->andReturn($crmCustomer); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->hasVerifiedEmail($customer); // THEN expect($result)->toBeTrue(); }); it('returns false for hasVerifiedEmail if crm customer not found', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $hashcode = new CrmHashcode(Uuid::uuid4()); $customer->hashcode = $hashcode; $crmService->shouldReceive('getCustomerFromHashCode')->with($customer->hashcode)->andReturn(null); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->hasVerifiedEmail($customer); // THEN expect($result)->toBeFalse(); }); it('verifies email successfully', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $hashcode = new CrmHashcode(Uuid::uuid4()); $customer->hashcode = $hashcode; $crmCustomer = new CrmCustomer( hashcode: $hashcode->value, email: 'test@example.com', password: 'password', firstname: 'John', lastname: 'Doe', birthDate: '1990-01-01', phone: '123456789', address: '123 Main St', address2: null, city: 'Paris', postcode: '75000', country: Country::france, optIn: true, status: true, lastConnection: null ); $crmService->shouldReceive('getCustomerFromHashCode')->with($customer->hashcode)->andReturn($crmCustomer); $activation = new \stdClass(); $activation->result = true; $crmService->shouldReceive('activate')->with($crmCustomer)->andReturn($activation); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->verifyEmail($customer); // THEN expect($result)->toBeTrue(); }); it('returns false for verifyEmail if crm customer not found', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $hashcode = new CrmHashcode(Uuid::uuid4()); $customer->hashcode = $hashcode; $crmService->shouldReceive('getCustomerFromHashCode')->with($customer->hashcode)->andReturn(null); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $result = $service->verifyEmail($customer); // THEN expect($result)->toBeFalse(); }); it('throws CrmServiceException from getCrmCustomerFrom', function (): void { // GIVEN $guard = Mockery::mock(StatefulGuard::class); $crmService = Mockery::mock(CrmService::class); $shopperService = Mockery::mock(ShopperService::class); $customer = new Customer(); $hashcode = new CrmHashcode(Uuid::uuid4()); $customer->hashcode = $hashcode; app()->instance(ExceptionHandler::class, Mockery::mock(ExceptionHandler::class)->shouldIgnoreMissing()); $exception = new CrmServiceException('Crm Error'); $crmService->shouldReceive('getCustomerFromHashCode')->with($customer->hashcode)->andReturn($exception); $service = new AppCustomerAuthService($guard, $crmService, $shopperService); // WHEN $action = fn () => $service->hasVerifiedEmail($customer); // THEN expect($action)->toThrow(CrmServiceException::class, 'Crm Error'); }); });