# How to Run the Geofence Check-In Tests

## Quick Start

### Prerequisites
```bash
# Ensure PHP and Composer are installed
php --version
composer --version
```

### Run All Tests
```bash
cd c:\xampp\htdocs\fwgmalayasia\fwg-malaysia\fwg-malaysia
php artisan test tests/Feature/GeofenceCheckInTest.php
```

### Expected Output (Success)
```
   PASS  tests/Feature/GeofenceCheckInTest.php
  ✓ test_get_profile_returns_assigned_locations_with_coordinates
  ✓ test_profile_filters_incomplete_assignments
  ✓ test_check_in_succeeds_inside_geofence
  ✓ test_check_in_fails_outside_geofence_with_location_details
  ✓ test_get_geofences_returns_location_coordinates
  ✓ test_check_geofence_status_inside
  ✓ test_check_geofence_status_outside_with_diagnostics
  ✓ test_multiple_assigned_locations_display
  ✓ test_inactive_assignments_excluded_from_profile
  ✓ test_prevent_duplicate_check_in_same_day
  ✓ test_check_in_validation_invalid_coordinates
  ✓ test_distance_calculation_accuracy

Tests: 12 passed
Time: 2.345s
```

---

## Test Commands Reference

### Run with Verbose Output
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php -v
```

### Run Specific Test
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --filter test_check_in_succeeds_inside_geofence
```

### Run with Code Coverage
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --coverage
```

### Run Tests in Isolation
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --isolated
```

### Run with Output Only on Failure
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --stop-on-failure
```

---

## Test Structure

### Test Class: `GeofenceCheckInTest`

**Inheritance**: Extends `TestCase`  
**Trait**: Uses `RefreshDatabase` (cleans database after each test)

```
GeofenceCheckInTest
├── setUp() - Creates test data before each test
├── createTestData() - Initializes: Client, Location, Service, Geofence, User, Assignment
│
├── Profile Tests
│   ├── test_get_profile_returns_assigned_locations_with_coordinates
│   ├── test_profile_filters_incomplete_assignments
│   └── test_multiple_assigned_locations_display
│
├── Check-In Tests
│   ├── test_check_in_succeeds_inside_geofence
│   ├── test_check_in_fails_outside_geofence_with_location_details
│   └── test_prevent_duplicate_check_in_same_day
│
├── Geofence Status Tests
│   ├── test_get_geofences_returns_location_coordinates
│   ├── test_check_geofence_status_inside
│   └── test_check_geofence_status_outside_with_diagnostics
│
├── Validation Tests
│   ├── test_check_in_validation_invalid_coordinates
│   ├── test_inactive_assignments_excluded_from_profile
│   └── test_distance_calculation_accuracy
```

---

## Understanding Test Data

Each test uses this data structure:

```
CLIENT: Test Client (TC001)
│
├── LOCATION: Main Office
│   └── Coordinates: 12.9716, 77.5946
│       Address: 123 Main St, Bangalore - 560001
│
├── SERVICE: Security Patrol - Building A
│   └── Zone: North Wing
│       Status: Active
│
├── GEOFENCE: Building A - Perimeter
│   └── Type: Radius
│       Radius: 100 meters
│       Tolerance: 50 meters
│
├── EMPLOYEE: John Doe (employee@test.com)
│   └── Password: password (for testing)
│
└── ASSIGNMENT: Primary
    └── Status: Active
```

### Test Locations for Reference

| Name | Latitude | Longitude | Purpose |
|------|----------|-----------|---------|
| Main Office (Center) | 12.9716 | 77.5946 | Inside geofence |
| Secondary Office | 12.9745 | 77.5976 | Multiple locations |
| Far Away | 12.997422 | 80.211936 | Outside geofence |

---

## Common Test Results & Meanings

### ✅ PASS - All Good
```
✓ test_check_in_succeeds_inside_geofence
```
Test passed successfully. Code is working as expected.

### ❌ FAIL - Something Broke
```
✗ test_check_in_succeeds_inside_geofence
  Expected status code 200 but received 500
```
Check the error details and code changes.

### ⚠️ INCOMPLETE - Setup Failed
```
✗ test_check_in_succeeds_inside_geofence
  Exception: Call to undefined method User::create()
```
Verify model definitions and migrations.

### ⏭️ SKIP - Test Disabled
```
S test_check_in_succeeds_inside_geofence
```
Test was intentionally skipped.

---

## What Each Test Validates

### 1️⃣ Profile Tests
**Purpose**: Employee profile API working correctly

```
Profile API → Includes assigned locations → 
Locations have coordinates → Filters incomplete data
```

**Files Tested**: `ProfileController.php`

---

### 2️⃣ Check-In Tests  
**Purpose**: Clock-in functionality with geofencing

```
Check-in inside → Success ✓
Check-in outside → Error with navigation info ✓
Check-in twice → Prevented ✓
```

**Files Tested**: `AttendanceController.php`

---

### 3️⃣ Geofence Tests
**Purpose**: Geofence status checking

```
Location inside → inside_any: true ✓
Location outside → inside_any: false, all_geofences returned ✓
Coordinates included → Navigation possible ✓
```

**Files Tested**: `GeofencingService.php`, `GeofencingController.php`

---

### 4️⃣ Validation Tests
**Purpose**: Data validation and business logic

```
Invalid coordinates → Rejected ✓
Inactive assignments → Excluded ✓
Distance calculation → Accurate ✓
```

---

## Debugging Failed Tests

### Step 1: Run Test with Full Output
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php -v --stop-on-failure
```

### Step 2: Run Single Failing Test
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --filter test_name
```

### Step 3: Check Test Code
```php
// tests/Feature/GeofenceCheckInTest.php
// Read the failing test method
public function test_check_in_succeeds_inside_geofence()
{
    // Each line explains what's being tested
}
```

### Step 4: Check Application Code
Compare test expectations with actual code in:
- `app/Http/Controllers/Api/Employee/ProfileController.php`
- `app/Http/Controllers/Api/Employee/AttendanceController.php`
- `app/Services/GeofencingService.php`

### Step 5: Check Database
```bash
# If using SQLite file
sqlite3 database/database.sqlite ".tables"
sqlite3 database/database.sqlite "SELECT * FROM employee_assignments LIMIT 1;"
```

---

## Test Maintenance

### Adding a New Test
```php
public function test_new_feature()
{
    // 1. Setup data if needed
    // 2. Perform action
    // 3. Assert results
    
    $response = $this->actingAs($this->user)
        ->postJson('/api/v1/endpoint', ['data' => 'value']);
    
    $response->assertStatus(200);
}
```

### Updating Test Data
Edit `createTestData()` method to add more models/relationships.

### Removing Old Tests
```php
// Comment out or delete entire test method
// public function test_old_functionality()
// {
// }
```

---

## Integration with CI/CD

### GitHub Actions Example
```yaml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v2
      
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.1'
          extensions: sqlite
          
      - name: Install dependencies
        run: composer install --no-progress --prefer-dist
        
      - name: Run tests
        run: php artisan test tests/Feature/GeofenceCheckInTest.php
```

---

## Performance Metrics

Each test typically runs in:
- Profile tests: ~100ms
- Check-in tests: ~150ms
- Geofence tests: ~120ms
- Validation tests: ~80ms

**Total Suite**: ~2-3 seconds

---

## Coverage Report

After running with coverage:
```bash
php artisan test tests/Feature/GeofenceCheckInTest.php --coverage
```

You'll see coverage % for:
- `ProfileController.php`
- `AttendanceController.php`
- `GeofencingService.php`
- `GeofencingController.php`

**Target**: > 90% code coverage

---

## Troubleshooting

### "No such file or directory"
```bash
# Make sure you're in the right directory
cd c:\xampp\htdocs\fwgmalayasia\fwg-malaysia\fwg-malaysia
```

### "Unable to connect to database"
- Tests use in-memory SQLite (automatic)
- No external database needed
- Migrations run automatically

### "Class not found"
```bash
# Rebuild autoloader
composer dump-autoload
```

### "Permission denied"
```bash
# Ensure Laravel can write to storage
chmod -R 777 storage bootstrap/cache
```

---

## Next Steps

1. ✅ Run all tests: `php artisan test`
2. ✅ Verify all pass: 12/12 should pass
3. ✅ Check coverage: `--coverage` flag
4. ✅ Add to CI/CD pipeline
5. ✅ Run tests on every commit

---

## Support Files

- 📄 [Test Suite Documentation](TEST_SUITE_DOCUMENTATION.md)
- 📄 [Geofence Check-In Fix](GEOFENCE_CHECKIN_FIX.md)
- 📄 [Angular Integration Guide](ANGULAR_GEOFENCE_INTEGRATION.md)
- 📂 [Test Code](../../tests/Feature/GeofenceCheckInTest.php)
