CaiWuXiTong/tests/Unit/Auth/SupplierPortalAccessTest.php

115 lines
5.4 KiB
PHP

<?php
namespace Tests\Unit\Auth;
use App\Services\Auth\SupplierPortalAccess;
use Mockery;
use Modules\EcommerceFinance\Repositories\SupplierManagementMirrorRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
use Tests\TestCase;
class SupplierPortalAccessTest extends TestCase
{
public function test_exact_supplier_group_resolves_to_one_supplier(): void
{
$query = Mockery::mock(UpstreamReadOnlyQuery::class);
$query->shouldReceive('select')->twice()->andReturnUsing(function (string $sql, array $bindings): array {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
if (str_contains($sql, 'hr_employee')) {
$this->assertSame(['ding-supplier'], $bindings);
return [[
'userid' => 'ding-supplier',
'unionid' => 'union-supplier',
'active' => 1,
'dept_id_list' => '55248182',
]];
}
$this->assertContains('55248182', $bindings);
return [
['Id' => 55248182, 'parent_id' => 900, 'name' => '晨丰', 'depth' => 0],
['Id' => 900, 'parent_id' => 1, 'name' => '供应商', 'depth' => 1],
];
});
$factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class);
$factory->shouldReceive('forSource')->once()->with('operations_replica')->andReturn($query);
$suppliers = Mockery::mock(SupplierManagementMirrorRepository::class);
$suppliers->shouldReceive('suppliersByNames')->once()
->with(['晨丰', '供应商'])
->andReturn([(object) ['Id' => 9, 'scmcode' => 'CF-001', 'scmname' => '晨丰']]);
$resolved = (new SupplierPortalAccess($factory, $suppliers))->resolve('ding-supplier', 'union-supplier');
$this->assertSame('晨丰', $resolved['supplier_name']);
$this->assertSame('CF-001', $resolved['supplier_code']);
$this->assertSame(55248182, $resolved['dingtalk_group_id']);
}
public function test_inactive_or_union_mismatched_employee_is_denied(): void
{
foreach ([
[['userid' => 'ding-supplier', 'unionid' => 'union-supplier', 'active' => 0, 'dept_id_list' => '1']],
[['userid' => 'ding-supplier', 'unionid' => 'different-union', 'active' => 1, 'dept_id_list' => '1']],
] as $employees) {
$query = Mockery::mock(UpstreamReadOnlyQuery::class);
$query->shouldReceive('select')->once()->with(Mockery::on(function (string $sql): bool {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
return str_contains($sql, 'hr_employee');
}), ['ding-supplier'])->andReturn($employees);
$factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class);
$factory->shouldReceive('forSource')->andReturn($query);
$suppliers = Mockery::mock(SupplierManagementMirrorRepository::class);
$suppliers->shouldNotReceive('suppliersByNames');
$this->assertNull((new SupplierPortalAccess($factory, $suppliers))->resolve('ding-supplier', 'union-supplier'));
}
}
public function test_multiple_supplier_ancestors_are_ambiguous_and_denied(): void
{
$query = Mockery::mock(UpstreamReadOnlyQuery::class);
$query->shouldReceive('select')->twice()->andReturnUsing(function (string $sql): array {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
if (str_contains($sql, 'hr_employee')) {
return [['userid' => 'ding-supplier', 'unionid' => 'union-supplier', 'active' => 1, 'dept_id_list' => '10,20']];
}
return [
['Id' => 10, 'parent_id' => 1, 'name' => '晨丰', 'depth' => 0],
['Id' => 20, 'parent_id' => 1, 'name' => '鸣飞家具', 'depth' => 0],
];
});
$factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class);
$factory->shouldReceive('forSource')->once()->andReturn($query);
$suppliers = Mockery::mock(SupplierManagementMirrorRepository::class);
$suppliers->shouldReceive('suppliersByNames')->once()->andReturn([
(object) ['Id' => 1, 'scmcode' => 'CF', 'scmname' => '晨丰'],
(object) ['Id' => 2, 'scmcode' => 'MF', 'scmname' => '鸣飞家具'],
]);
$this->assertNull((new SupplierPortalAccess($factory, $suppliers))->resolve('ding-supplier', 'union-supplier'));
}
public function test_organization_cycle_is_rejected(): void
{
$query = Mockery::mock(UpstreamReadOnlyQuery::class);
$query->shouldReceive('select')->twice()->andReturnUsing(function (string $sql): array {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
if (str_contains($sql, 'hr_employee')) {
return [['userid' => 'ding-supplier', 'unionid' => 'union-supplier', 'active' => 1, 'dept_id_list' => '30']];
}
return [['Id' => 30, 'parent_id' => 30, 'name' => '晨丰', 'depth' => 20]];
});
$factory = Mockery::mock(UpstreamReadOnlyQueryFactory::class);
$factory->shouldReceive('forSource')->once()->andReturn($query);
$suppliers = Mockery::mock(SupplierManagementMirrorRepository::class);
$suppliers->shouldNotReceive('suppliersByNames');
$this->assertNull((new SupplierPortalAccess($factory, $suppliers))->resolve('ding-supplier', 'union-supplier'));
}
}