# API Testing Guide

This guide provides step-by-step instructions for testing all attendance API endpoints.

## Prerequisites

1. Laravel application running: `php artisan serve`
2. JWT token from authentication (test user already created)
3. Postman or similar API client

## Test Data Setup

```bash
# Generate test company and employee
php artisan tinker --execute="
\$company = \App\Models\Company::create([
    'no_company' => 'TEST001',
    'name' => 'Test Company',
    'address' => '123 Test Street'
]);

\$employee = \App\Models\Employee::create([
    'id_company' => \$company->id,
    'id_department' => 1,
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'phone_number' => '08123456789',
    'is_attendances' => true
]);

echo 'Company ID: ' . \$company->id . PHP_EOL;
echo 'Employee ID: ' . \$employee->id . PHP_EOL;
"
```

## 1. PUBLIC API TESTS (No Authentication Required)

### 1.1 Get Employee Info by Email

**Endpoint:** `GET /api/public/employee`

**Request:**
```
GET /api/public/employee?email=john@example.com
Content-Type: application/json
```

**Expected Response (200):**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "company": "Test Company",
    "department": "IT",
    "fingerprint_registered": false
  },
  "message": "Employee found"
}
```

### 1.2 Register Fingerprint

**Endpoint:** `POST /api/public/attendance/register-fingerprint`

**Request:**
```bash
curl -X POST http://localhost:8000/api/public/attendance/register-fingerprint \
  -H "Content-Type: application/json" \
  -d '{
    "email": "john@example.com",
    "fingerprint_data": "YWJjZGVmZ2hpamtsbW5vcA=="
  }'
```

**Expected Response (201):**
```json
{
  "success": true,
  "data": {
    "employee_id": 1,
    "fingerprint_registered": true,
    "message": "Fingerprint registered successfully"
  },
  "message": "Fingerprint registered"
}
```

### 1.3 Join Attendance (Check-In)

**Endpoint:** `POST /api/public/attendance/join`

**Request (form-data):**
```
POST /api/public/attendance/join
Content-Type: multipart/form-data

- email: john@example.com
- fingerprint_data: YWJjZGVmZ2hpamtsbW5vcA==
- photo: [binary file] (optional)
- location_latitude: -6.1234 (optional)
- location_longitude: 106.5678 (optional)
- type: check_in (default)
```

**cURL Example:**
```bash
curl -X POST http://localhost:8000/api/public/attendance/join \
  -F "email=john@example.com" \
  -F "fingerprint_data=YWJjZGVmZ2hpamtsbW5vcA==" \
  -F "location_latitude=-6.1234" \
  -F "location_longitude=106.5678" \
  -F "type=check_in"
```

**Expected Response (200):**
```json
{
  "success": true,
  "data": {
    "attendance": {
      "id": 1,
      "id_employee": 1,
      "date": "2025-11-10",
      "check_in": "08:30:45",
      "check_out": null,
      "status": "present",
      "location_in": "-6.1234,106.5678",
      "photo_check_in": null,
      "photo_check_out": null
    },
    "working_hours": {
      "within_hours": true,
      "current_time": "08:30:45",
      "work_start": null,
      "work_end": null,
      "message": "No schedule restriction"
    },
    "fingerprint_similarity": "100%"
  },
  "message": "Check-in successful"
}
```

### 1.4 Join Attendance (Check-Out)

**Endpoint:** `POST /api/public/attendance/join`

**Request (same as Check-In but with type=check_out):**
```bash
curl -X POST http://localhost:8000/api/public/attendance/join \
  -F "email=john@example.com" \
  -F "fingerprint_data=YWJjZGVmZ2hpamtsbW5vcA==" \
  -F "location_latitude=-6.1234" \
  -F "location_longitude=106.5678" \
  -F "type=check_out"
```

**Expected Response (200):**
```json
{
  "success": true,
  "data": {
    "attendance": {
      "id": 1,
      "id_employee": 1,
      "date": "2025-11-10",
      "check_in": "08:30:45",
      "check_out": "17:30:00",
      "status": "present",
      "location_in": "-6.1234,106.5678",
      "location_out": "-6.1240,106.5685",
      "photo_check_in": null,
      "photo_check_out": null
    },
    "working_hours": {
      "within_hours": true,
      "current_time": "17:30:00",
      "work_start": null,
      "work_end": null,
      "message": "No schedule restriction"
    },
    "fingerprint_similarity": "100%"
  },
  "message": "Check-out successful"
}
```

## 2. PROTECTED API TESTS (Requires JWT Token)

### Get JWT Token

```bash
curl -X POST http://localhost:8000/api/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "password"
  }'
```

Store the returned token for use in protected endpoints.

### 2.1 List Attendances

**Endpoint:** `GET /api/attendance`

**Request:**
```bash
curl -X GET "http://localhost:8000/api/attendance?page=1&per_page=10" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Query Parameters:**
- `page`: Page number (default: 1)
- `per_page`: Items per page (default: 10)
- `search`: Search by employee name/email
- `date_from`: Filter from date (YYYY-MM-DD)
- `date_to`: Filter to date (YYYY-MM-DD)
- `id_employee`: Filter by employee ID
- `status`: Filter by status (present, absent, late, approved_by_admin)

**Expected Response (200):**
```json
{
  "success": true,
  "data": {
    "data": [
      {
        "id": 1,
        "id_employee": 1,
        "date": "2025-11-10",
        "check_in": "08:30:45",
        "check_out": "17:30:00",
        "status": "present",
        "location_in": "-6.1234,106.5678",
        "location_out": "-6.1240,106.5685",
        "photo_check_in": null,
        "photo_check_out": null,
        "employee": {
          "id": 1,
          "name": "John Doe",
          "email": "john@example.com",
          "company": {
            "id": 1,
            "name": "Test Company"
          },
          "department": {
            "id": 1,
            "name": "IT"
          }
        },
        "created_at": "2025-11-10T08:30:45Z"
      }
    ],
    "current_page": 1,
    "total": 100,
    "per_page": 10,
    "last_page": 10
  },
  "message": "Attendances fetched successfully"
}
```

### 2.2 Get Single Attendance

**Endpoint:** `GET /api/attendance/{id}`

**Request:**
```bash
curl -X GET http://localhost:8000/api/attendance/1 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
```

**Expected Response (200):**
```json
{
  "success": true,
  "data": {
    "id": 1,
    "id_employee": 1,
    "date": "2025-11-10",
    "check_in": "08:30:45",
    "check_out": "17:30:00",
    "status": "present",
    "location_in": "-6.1234,106.5678",
    "location_out": "-6.1240,106.5685",
    "photo_check_in": null,
    "photo_check_out": null,
    "employee": {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "company": {
        "id": 1,
        "name": "Test Company"
      },
      "department": {
        "id": 1,
        "name": "IT"
      }
    }
  },
  "message": "Attendance fetched successfully"
}
```

### 2.3 Bypass Attendance (Admin)

**Endpoint:** `POST /api/attendance/bypass`

**Request:**
```bash
curl -X POST http://localhost:8000/api/attendance/bypass \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id_employee": 1,
    "date": "2025-11-09",
    "type": "full",
    "manual_check_in": "08:00:00",
    "manual_check_out": "17:00:00",
    "reason": "Late registration due to system error"
  }'
```

**Expected Response (201):**
```json
{
  "success": true,
  "data": {
    "attendance": {
      "id": 2,
      "id_employee": 1,
      "date": "2025-11-09",
      "check_in": "08:00:00",
      "check_out": "17:00:00",
      "status": "approved_by_admin"
    },
    "bypass": {
      "id": 1,
      "id_employee": 1,
      "id_attendance": 2,
      "id_admin": 1,
      "type": "full",
      "reason": "Late registration due to system error",
      "status": "approved"
    }
  },
  "message": "Attendance bypass recorded successfully"
}
```

## 3. ERROR SCENARIOS

### Employee Not Found
```json
{
  "success": false,
  "data": null,
  "message": "Employee not found"
}
```

### Fingerprint Not Registered
```json
{
  "success": false,
  "data": null,
  "message": "Employee has not registered fingerprint yet"
}
```

### Fingerprint Mismatch
```json
{
  "success": false,
  "data": null,
  "message": "Fingerprint verification failed: Fingerprint mismatch. Similarity: 65%"
}
```

### Already Checked In
```json
{
  "success": false,
  "data": null,
  "message": "Already checked in today"
}
```

### Must Check-In First Before Check-Out
```json
{
  "success": false,
  "data": null,
  "message": "Must check-in first before check-out"
}
```

### Validation Failed
```json
{
  "success": false,
  "data": {
    "email": ["The email field is required."]
  },
  "message": "Validation failed"
}
```

## 4. Testing with Postman

### Setup:
1. Import the endpoints into Postman
2. Create environment variables:
   - `base_url`: http://localhost:8000
   - `jwt_token`: Your JWT token from login

### Common Headers:
```
Authorization: Bearer {{jwt_token}}
Content-Type: application/json
Accept: application/json
```

## 5. Mobile App Integration Testing

### Fingerprint Registration Flow:
1. User enters email
2. Call `GET /api/public/employee?email={{email}}`
3. Check if `fingerprint_registered` is false
4. If false, capture fingerprint and call `POST /api/public/attendance/register-fingerprint`

### Daily Attendance Flow:
1. User enters email
2. Call `GET /api/public/employee?email={{email}}`
3. Capture fingerprint from device
4. (Optional) Capture photo
5. Get GPS coordinates
6. Call `POST /api/public/attendance/join` with all data
7. Server verifies fingerprint and records attendance

## 6. Load Testing (Optional)

Use Apache Bench or similar tool:

```bash
# Test 100 requests to attendance endpoint
ab -n 100 -c 10 \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  http://localhost:8000/api/attendance

# Test fingerprint verification (simulate mobile app)
ab -n 50 -c 5 \
  -p payload.json \
  -T "multipart/form-data" \
  http://localhost:8000/api/public/attendance/join
```

## Notes

- Fingerprint similarity threshold is 85% by default
- Photos are stored in `storage/app/public/attendances/{employee_id}/`
- Make sure storage link is created: `php artisan storage:link`
- Fingerprint verification uses Levenshtein distance (simple placeholder for production)
- For production, integrate with proper biometric matching library
