HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/be.naniguide.com/tests/Unit/AccountManagement/AccountProvisioningServiceTest.php
<?php

namespace Tests\Unit\AccountManagement;

use App\Model\Admin;
use App\Model\Customer;
use App\Model\User;
use App\Services\AccountManagement\AccountProvisioningService;
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
use Illuminate\Support\MessageBag;
use Mockery;
use PHPUnit\Framework\TestCase;

class AccountProvisioningServiceTest extends TestCase
{
    protected function tearDown(): void
    {
        Mockery::close();
        parent::tearDown();
    }

    public function test_create_customer_returns_validation_errors_without_writing_data()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $customer = Mockery::mock(Customer::class)->makePartial();
        $user = Mockery::mock(User::class)->makePartial();
        $validator = Mockery::mock(ValidatorContract::class);

        $validator->shouldReceive('fails')->once()->andReturn(true);

        $service->shouldReceive('makeNewCustomer')->once()->andReturn($customer);
        $service->shouldReceive('makeNewUserForCustomer')->once()->with($customer)->andReturn($user);
        $service->shouldReceive('isMobilePhoneRequired')->once()->andReturn(false);
        $service->shouldReceive('makeValidator')->once()->andReturn($validator);
        $service->shouldReceive('runInTransaction')->never();

        [$returnedValidator, $returnedCustomer, $returnedUser] = $service->createCustomer(
            null,
            'Acme',
            'UTC',
            1,
            'invalid-email',
            'secret123',
            'secret123',
            'John',
            'Doe',
            null,
            'role-uid',
            null
        );

        $this->assertSame($validator, $returnedValidator);
        $this->assertSame($customer, $returnedCustomer);
        $this->assertSame($user, $returnedUser);
    }

    public function test_create_customer_creates_user_and_customer_in_transaction()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $customer = Mockery::mock(Customer::class)->makePartial();
        $user = Mockery::mock(User::class)->makePartial();
        $validator = Mockery::mock(ValidatorContract::class);
        $customerValidator = Mockery::mock(ValidatorContract::class);

        $validator->shouldReceive('fails')->once()->andReturn(false);
        $customerValidator->shouldReceive('fails')->once()->andReturn(false);

        $service->shouldReceive('makeNewCustomer')->once()->andReturn($customer);
        $service->shouldReceive('makeNewUserForCustomer')->once()->with($customer)->andReturn($user);
        $service->shouldReceive('isMobilePhoneRequired')->once()->andReturn(false);
        $service->shouldReceive('makeValidator')->once()->andReturn($validator);
        $service->shouldReceive('runInTransaction')->once()->andReturnUsing(function ($callback) {
            return $callback();
        });

        $user->shouldReceive('saveUser')->once()->with(
            '[email protected]',
            'secret123',
            'secret123',
            'John',
            'Doe',
            null,
            'role-uid',
            '+84123456789'
        )->andReturn([true, new MessageBag()]);

        $service->shouldReceive('createCustomerEntity')->once()->with(
            'Acme',
            'UTC',
            7,
            null
        )->andReturn([$customerValidator, $customer]);

        $customer->shouldReceive('addUser')->once()->with($user);

        [$returnedValidator, $returnedCustomer, $returnedUser] = $service->createCustomer(
            null,
            'Acme',
            'UTC',
            7,
            '[email protected]',
            'secret123',
            'secret123',
            'John',
            'Doe',
            null,
            'role-uid',
            '+84123456789'
        );

        $this->assertSame($validator, $returnedValidator);
        $this->assertSame($customer, $returnedCustomer);
        $this->assertSame($user, $returnedUser);
    }

    public function test_create_install_account_creates_all_entities()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $user = Mockery::mock(User::class)->makePartial();
        $admin = Mockery::mock(Admin::class)->makePartial();
        $customer = Mockery::mock(Customer::class)->makePartial();
        $customerValidator = Mockery::mock(ValidatorContract::class);

        $customerValidator->shouldReceive('fails')->once()->andReturn(false);

        $service->shouldReceive('runInTransaction')->once()->andReturnUsing(function ($callback) {
            return $callback();
        });
        $service->shouldReceive('makeNewUser')->once()->andReturn($user);
        $service->shouldReceive('defaultAdminRoleUid')->once()->andReturn('default-admin-role-uid');
        $service->shouldReceive('makeNewAdmin')->once()->andReturn($admin);
        $service->shouldReceive('createCustomerEntity')->once()->with(
            'Acme',
            'UTC',
            99,
            $admin
        )->andReturn([$customerValidator, $customer]);

        $user->shouldReceive('saveUser')->once()->with(
            '[email protected]',
            'secret123',
            'secret123',
            'Admin',
            'Owner',
            null,
            'default-admin-role-uid'
        )->andReturn([true, new MessageBag()]);

        $admin->shouldReceive('saveAdmin')->once()->with(
            $user,
            1,
            null,
            'UTC',
            99,
            null
        )->andReturn([true, new MessageBag()]);

        $customer->shouldReceive('addUser')->once()->with($user);

        [$createdUser, $createdAdmin, $createdCustomer] = $service->createInstallAccount([
            'email' => '[email protected]',
            'password' => 'secret123',
            'first_name' => 'Admin',
            'last_name' => 'Owner',
            'timezone' => 'UTC',
            'name' => 'Acme',
        ], 99);

        $this->assertSame($user, $createdUser);
        $this->assertSame($admin, $createdAdmin);
        $this->assertSame($customer, $createdCustomer);
    }

    public function test_create_install_account_throws_when_admin_creation_fails()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $user = Mockery::mock(User::class)->makePartial();
        $admin = Mockery::mock(Admin::class)->makePartial();

        $service->shouldReceive('runInTransaction')->once()->andReturnUsing(function ($callback) {
            return $callback();
        });
        $service->shouldReceive('makeNewUser')->once()->andReturn($user);
        $service->shouldReceive('defaultAdminRoleUid')->once()->andReturn('default-admin-role-uid');
        $service->shouldReceive('makeNewAdmin')->once()->andReturn($admin);
        $service->shouldReceive('createCustomerEntity')->never();

        $user->shouldReceive('saveUser')->once()->andReturn([true, new MessageBag()]);
        $admin->shouldReceive('saveAdmin')->once()->andReturn([false, new MessageBag(['admin' => ['Cannot save admin']])]);

        $this->expectException(\RuntimeException::class);
        $this->expectExceptionMessage('Cannot save admin');

        $service->createInstallAccount([
            'email' => '[email protected]',
            'password' => 'secret123',
            'first_name' => 'Admin',
            'last_name' => 'Owner',
            'timezone' => 'UTC',
            'name' => 'Acme',
        ], 99);
    }

    public function test_create_admin_returns_validation_errors_without_writing_data()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $admin = Mockery::mock(Admin::class)->makePartial();
        $user = Mockery::mock(User::class)->makePartial();
        $validator = Mockery::mock(ValidatorContract::class);

        $validator->shouldReceive('fails')->once()->andReturn(true);

        $service->shouldReceive('makeNewAdmin')->once()->andReturn($admin);
        $service->shouldReceive('makeNewUser')->once()->andReturn($user);
        $service->shouldReceive('makeValidator')->once()->andReturn($validator);
        $service->shouldReceive('runInTransaction')->never();

        [$returnedValidator, $returnedAdmin, $returnedUser] = $service->createAdmin(
            'invalid-email',
            'secret123',
            'secret123',
            'John',
            'Doe',
            null,
            null,
            1,
            'UTC',
            1,
            null
        );

        $this->assertSame($validator, $returnedValidator);
        $this->assertSame($admin, $returnedAdmin);
        $this->assertSame($user, $returnedUser);
    }

    public function test_create_admin_creates_user_and_admin_in_transaction()
    {
        $service = Mockery::mock(AccountProvisioningService::class)->makePartial();
        $service->shouldAllowMockingProtectedMethods();

        $admin = Mockery::mock(Admin::class)->makePartial();
        $user = Mockery::mock(User::class)->makePartial();
        $validator = Mockery::mock(ValidatorContract::class);

        $validator->shouldReceive('fails')->once()->andReturn(false);

        $service->shouldReceive('makeNewAdmin')->once()->andReturn($admin);
        $service->shouldReceive('makeNewUser')->once()->andReturn($user);
        $service->shouldReceive('makeValidator')->once()->andReturn($validator);
        $service->shouldReceive('defaultAdminRoleUid')->once()->andReturn('default-admin-role-uid');
        $service->shouldReceive('runInTransaction')->once()->andReturnUsing(function ($callback) {
            return $callback();
        });

        $user->shouldReceive('saveUser')->once()->with(
            '[email protected]',
            'secret123',
            'secret123',
            'Admin',
            'Owner',
            null,
            'default-admin-role-uid'
        )->andReturn([true, new MessageBag()]);

        $admin->shouldReceive('saveAdmin')->once()->with(
            $user,
            3,
            99,
            'UTC',
            7,
            'yes'
        )->andReturn([true, new MessageBag()]);

        [$returnedValidator, $returnedAdmin, $returnedUser] = $service->createAdmin(
            '[email protected]',
            'secret123',
            'secret123',
            'Admin',
            'Owner',
            null,
            3,
            99,
            'UTC',
            7,
            'yes'
        );

        $this->assertSame($validator, $returnedValidator);
        $this->assertSame($admin, $returnedAdmin);
        $this->assertSame($user, $returnedUser);
    }
}