initial: bootstrap from BukidBountyApp base
This commit is contained in:
20
tests/Feature/ExampleTest.php
Normal file
20
tests/Feature/ExampleTest.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
public function testTheApplicationReturnsSuccessfulResponse()
|
||||
{
|
||||
$this->get('/')
|
||||
->assertSuccessful();
|
||||
}
|
||||
}
|
||||
80
tests/Feature/GlobalTransactionFlowTest.php
Normal file
80
tests/Feature/GlobalTransactionFlowTest.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\GlobalTransaction;
|
||||
use App\Models\User;
|
||||
use App\Enums\Market\ProductTransactionType;
|
||||
use App\Enums\Market\TransactionFlow;
|
||||
use Tests\TestCase;
|
||||
use Hypervel\Support\Facades\Auth;
|
||||
use Hypervel\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
class GlobalTransactionFlowTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_transaction_creation_assigns_correct_flow()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
// Test INCOME flow (STORE_SALE)
|
||||
$response = $this->post('/admin/transactions/create', [
|
||||
'amount' => 100,
|
||||
'type' => ProductTransactionType::STORE_SALE->value,
|
||||
'description' => 'Test Sale'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$hashkey = $response->json('hashkey');
|
||||
|
||||
$transaction = GlobalTransaction::where('hashkey', $hashkey)->first();
|
||||
$this->assertEquals(TransactionFlow::INCOME, $transaction->flow);
|
||||
|
||||
// Test EXPENSE flow (PURCHASE)
|
||||
$response = $this->post('/admin/transactions/create', [
|
||||
'amount' => 50,
|
||||
'type' => ProductTransactionType::PURCHASE->value,
|
||||
'description' => 'Test Purchase'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$hashkey = $response->json('hashkey');
|
||||
|
||||
$transaction = GlobalTransaction::where('hashkey', $hashkey)->first();
|
||||
$this->assertEquals(TransactionFlow::EXPENSE, $transaction->flow);
|
||||
|
||||
// Test NEUTRAL flow (INVENTORY_ADJUSTMENT)
|
||||
$response = $this->post('/admin/transactions/create', [
|
||||
'amount' => 0,
|
||||
'type' => ProductTransactionType::INVENTORY_ADJUSTMENT->value,
|
||||
'description' => 'Test Adjustment'
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$hashkey = $response->json('hashkey');
|
||||
|
||||
$transaction = GlobalTransaction::where('hashkey', $hashkey)->first();
|
||||
$this->assertEquals(TransactionFlow::NEUTRAL, $transaction->flow);
|
||||
}
|
||||
|
||||
public function test_transaction_list_returns_flow_data()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
Auth::login($user);
|
||||
|
||||
$response = $this->post('/admin/transactions/list');
|
||||
$response->assertStatus(200);
|
||||
|
||||
$data = $response->json();
|
||||
if (count($data) > 0) {
|
||||
$this->assertArrayHasKey('flow', $data[0]);
|
||||
$this->assertArrayHasKey('value', $data[0]['flow']);
|
||||
$this->assertArrayHasKey('label', $data[0]['flow']);
|
||||
}
|
||||
}
|
||||
}
|
||||
118
tests/Feature/PosAccessTest.php
Normal file
118
tests/Feature/PosAccessTest.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Market\Store;
|
||||
use App\Models\Market\PosSession;
|
||||
use App\Enums\UserTypes;
|
||||
use App\Enums\UserActions;
|
||||
use Tests\TestCase;
|
||||
use Hypervel\Support\Facades\Auth;
|
||||
use Hypervel\Foundation\Testing\RefreshDatabase;
|
||||
use Hyperf\Stringable\Str;
|
||||
|
||||
class PosAccessTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
protected function createUser(UserTypes $type, User $parent = null)
|
||||
{
|
||||
return User::create([
|
||||
'name' => 'Test ' . $type->value,
|
||||
'fullname' => 'Test User ' . $type->value,
|
||||
'username' => 'test_' . str_replace(' ', '_', $type->value) . '_' . Str::random(5),
|
||||
'mobile_number' => '09' . mt_rand(100000000, 999999999),
|
||||
'email' => Str::random(10) . '@example.com',
|
||||
'password' => password_hash('123123', PASSWORD_DEFAULT),
|
||||
'acct_type' => $type,
|
||||
'parentuid' => $parent ? $parent->id : null,
|
||||
'hashkey' => Str::random(100),
|
||||
'active' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function createStore(User $owner, User $manager = null)
|
||||
{
|
||||
return Store::create([
|
||||
'name' => 'Test Store ' . Str::random(5),
|
||||
'owner_id' => $owner->id,
|
||||
'manager_id' => $manager ? $manager->id : $owner->id,
|
||||
'hashkey' => Str::random(100),
|
||||
'is_active' => true,
|
||||
'status' => 'active',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_pos_access_hierarchy()
|
||||
{
|
||||
// 1. Setup Hierarchy
|
||||
$owner = $this->createUser(UserTypes::STORE_OWNER);
|
||||
$store = $this->createStore($owner);
|
||||
|
||||
$manager = $this->createUser(UserTypes::STORE_MANAGER, $owner);
|
||||
$store->manager_id = $manager->id;
|
||||
$store->save();
|
||||
|
||||
$terminal = $this->createUser(UserTypes::POS_TERMINAL, $manager);
|
||||
|
||||
// Another store hierarchy
|
||||
$otherOwner = $this->createUser(UserTypes::STORE_OWNER);
|
||||
$otherStore = $this->createStore($otherOwner);
|
||||
|
||||
// 2. Test Authorized Access
|
||||
|
||||
// Owner access
|
||||
Auth::login($owner);
|
||||
$response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
// Manager access
|
||||
Auth::login($manager);
|
||||
$response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
// Terminal access (child of manager)
|
||||
Auth::login($terminal);
|
||||
$response = $this->post('/api/pos/start', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
// 3. Test Unauthorized Access
|
||||
|
||||
// Terminal accessing another store
|
||||
$response = $this->post('/api/pos/start', ['store_hash' => $otherStore->hashkey]);
|
||||
$response->assertStatus(403);
|
||||
$this->assertEquals('You are not authorized to start a POS session for this store.', $response->json('message'));
|
||||
|
||||
// Manager accessing another store
|
||||
Auth::login($manager);
|
||||
$response = $this->post('/api/pos/start', ['store_hash' => $otherStore->hashkey]);
|
||||
$response->assertStatus(403);
|
||||
|
||||
// 4. Test Other Endpoints
|
||||
Auth::login($terminal);
|
||||
|
||||
// getPosSessions
|
||||
$response = $this->post('/api/pos/sessions/list', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->post('/api/pos/sessions/list', ['store_hash' => $otherStore->hashkey]);
|
||||
$response->assertStatus(403);
|
||||
|
||||
// getTodayStats
|
||||
$response = $this->post('/api/pos/stats', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->post('/api/pos/stats', ['store_hash' => $otherStore->hashkey]);
|
||||
$response->assertStatus(403);
|
||||
|
||||
// getCustomers
|
||||
$response = $this->post('/api/pos/get-customers', ['store_hash' => $store->hashkey]);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response = $this->post('/api/pos/get-customers', ['store_hash' => $otherStore->hashkey]);
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
}
|
||||
39
tests/Feature/RefreshDatabaseTest.php
Normal file
39
tests/Feature/RefreshDatabaseTest.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Hypervel\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class RefreshDatabaseTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function testCreateUser()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'id' => $user->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testCreateMultipleUsers()
|
||||
{
|
||||
factory(User::class, $count = 5)->create();
|
||||
|
||||
$this->assertDatabaseCount('users', $count);
|
||||
}
|
||||
|
||||
public function testZeroUserAfterRefresh()
|
||||
{
|
||||
$this->assertSame(0, User::count());
|
||||
}
|
||||
}
|
||||
13
tests/TestCase.php
Normal file
13
tests/TestCase.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Hypervel\Foundation\Testing\Concerns\RunTestsInCoroutine;
|
||||
use Hypervel\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
use RunTestsInCoroutine;
|
||||
}
|
||||
22
tests/Unit/ExampleTest.php
Normal file
22
tests/Unit/ExampleTest.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use Hypervel\Foundation\Testing\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*/
|
||||
public function testThatTrueIsTrue(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
38
tests/bootstrap.php
Normal file
38
tests/bootstrap.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hypervel\Foundation\Testing\TestScanHandler;
|
||||
|
||||
ini_set('display_errors', 'on');
|
||||
ini_set('display_startup_errors', 'on');
|
||||
|
||||
error_reporting(E_ALL);
|
||||
|
||||
! defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
|
||||
|
||||
$dir = __DIR__;
|
||||
$lastDir = '';
|
||||
if (! defined('BASE_PATH')) {
|
||||
while (! file_exists($dir . '/composer.json') && $dir !== dirname($dir)) {
|
||||
if ($lastDir === $dir) {
|
||||
break;
|
||||
}
|
||||
$lastDir = $dir;
|
||||
$dir = dirname($dir);
|
||||
}
|
||||
}
|
||||
|
||||
if (! file_exists($dir . '/composer.json')) {
|
||||
throw new RuntimeException('Unable to find base path (directory with composer.json)');
|
||||
}
|
||||
|
||||
define('BASE_PATH', $dir);
|
||||
|
||||
require BASE_PATH . '/vendor/autoload.php';
|
||||
|
||||
Hypervel\Foundation\ClassLoader::init(null, null, new TestScanHandler());
|
||||
|
||||
$app = require BASE_PATH . '/bootstrap/app.php';
|
||||
|
||||
$app->get(Hyperf\Contract\ApplicationInterface::class);
|
||||
15
tests/helpers.php
Normal file
15
tests/helpers.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Hyperf\Testing\ModelFactory;
|
||||
use Hypervel\Context\ApplicationContext;
|
||||
|
||||
if (! function_exists('factory')) {
|
||||
function factory(string $class, mixed ...$arguments)
|
||||
{
|
||||
return ApplicationContext::getContainer()
|
||||
->get(ModelFactory::class)
|
||||
->factory($class, ...$arguments);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user