# Test Cases: Location Features # HRMS Check-in/Check-out System ## Document Information | Field | Value | |-------|-------| | **Document Version** | 1.0.0 | | **Last Updated** | 2025-03-09 | | **Project** | HRMS Check-in/Check-out | | **Module** | Location Features | | **Author** | QA Team | --- ## 1. Overview (ภาพรวม) ระบบ HRMS Check-in/Check-out มีฟีเจอร์ Location ที่สำคัญในการลงเวลาเข้า-ออกงาน ฟีเจอร์ Location ประกอบด้วย: ### 1.1 Location Features | Feature | Description | |---------|-------------| | **Location Services** | รับพิกัด GPS จากอุปกรณ์ผ่าน Geolocation API | | **Location Validation** | ตรวจสอบความถูกต้องของตำแหน่ง (Mock Location Detection) | | **POI Resolution** | แปลงพิกัดเป็นชื่อสถานที่ (Bangkok GIS / ArcGIS) | | **Check-in/Check-out** | บันทึกตำแหน่งพร้อมรูปถ่าย | | **Privacy Consent** | ขอความยินยอมการเข้าถึงตำแหน่ง | ### 1.2 Related Files | File Path | Description | |-----------|-------------| | `/src/composables/useLocationValidation.ts` | Location validation logic | | `/src/views/HomeView.vue` | Check-in/Check-out page | | `/src/components/AscGISMap.vue` | Map component with location validation | | `/src/api/api.checkin.ts` | Check-in API endpoints | | `/src/stores/privacy.ts` | Privacy store for consent management | | `/src/composables/usePermissions.ts` | Permission checking utilities | --- ## 2. Test Environment (สภาพแวดล้อมการทดสอบ) ### 2.1 Devices (อุปกรณ์ทดสอบ) | Device Type | OS | Browser | Notes | |-------------|-------|---------|-------| | Mobile | iOS 17+ | Safari | Test with real GPS | | Mobile | Android 13+ | Chrome | Test with mock location apps | | Desktop | macOS 14+ | Chrome 121+ | Test with Developer Tools | | Desktop | Windows 11 | Edge 121+ | Test with Developer Tools | ### 2.2 Tools (เครื่องมือทดสอบ) | Tool | Purpose | |------|---------| | Fake GPS Location (Android) | Mock location testing | | Location Changer (iOS) | Mock location testing | | Chrome DevTools | Sensor simulation | | Xcode Simulator | iOS location simulation | | Android Studio Emulator | Android location simulation | ### 2.3 Test Data (ข้อมูลทดสอบ) | Data Type | Valid Value | Invalid Value | |-----------|-------------|---------------| | Latitude | 13.7563 (Bangkok) | 0, 91, -91 | | Longitude | 100.5018 (Bangkok) | 0, 181, -181 | | Accuracy (meters) | 10-50 | 101+ | | Timestamp | Current time | 60+ seconds old | --- ## 3. Validation Rules (กฎการตรวจสอบ) ### 3.1 Location Validation Rules | Rule | Threshold | Error Message (Thai) | Mock Indicator | |------|-----------|---------------------|----------------| | Valid Coordinates | -90 to 90 lat, -180 to 180 lon, not (0,0) | "พิกัดตำแหน่งไม่ถูกต้อง กรุณาลองใหม่" | +3 | | Fresh Timestamp | <= 60 seconds old | "ข้อมูลตำแหน่งเก่าเกินไป กรุณารับสัญญาณ GPS ใหม่" | +2 | | GPS Accuracy | <= 100 meters | "ความแม่นยำตำแหน่งต่ำเกินไป กรุณาตรวจสอบการรับสัญญาณ GPS" | +1 | | Movement Speed | <= 100 m/s (~360 km/h) | "ตรวจพบการเคลื่อนที่ด้วยความเร็วผิดปกติ อาจเป็นการจำลองตำแหน่ง" | +3 | | Mock Detection | >= 3 indicators | "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง กรุณาปิดแอปจำลองตำแหน่งและลองใหม่" | - | ### 3.2 Validation Configuration ```typescript VALIDATION_CONFIG = { MAX_TIMESTAMP_AGE_MS: 60_000, // 60 seconds MAX_ACCURACY_METERS: 100, // 100 meters MAX_SPEED_MS: 100, // ~360 km/h POSITION_HISTORY_SIZE: 5, // positions for pattern detection MOCK_INDICATOR_THRESHOLD: 3, // indicators for mock detection } ``` --- ## 4. Test Scenarios ### 4.1 TC-LOC-01: Location Permission | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-01-01 | อนุญาตให้เข้าถึงตำแหน่ง | High | | TC-LOC-01-02 | ปฏิเสธการเข้าถึงตำแหน่ง | High | ### 4.2 TC-LOC-02: Location Acquisition | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-02-01 | รับพิกัด GPS สำเร็จ (Outdoor) | High | | TC-LOC-02-02 | รับพิกัด GPS สำเร็จ (Indoor) | Medium | | TC-LOC-02-03 | รับพิกัด GPS ล้มเหลว (GPS ไม่ทำงาน) | High | | TC-LOC-02-04 | หมดเวลาขอรับพิกัด (Timeout) | Medium | ### 4.3 TC-LOC-03: Location Validation | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-03-01 | พิกัดถูกต้อง (Valid coordinates) | High | | TC-LOC-03-02 | พิกัดไม่ถูกต้อง (Invalid coordinates - (0,0)) | High | | TC-LOC-03-03 | พิกัดนอกช่วง (Out of range) | Medium | | TC-LOC-03-04 | ข้อมูลตำแหน่งเก่าเกินไป (Stale timestamp) | High | | TC-LOC-03-05 | ความแม่นยำต่ำ (Poor accuracy) | Medium | | TC-LOC-03-06 | ความเร็วเคลื่อนที่ผิดปกติ (Impossible speed) | High | ### 4.4 TC-LOC-04: Mock Location Detection | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-04-01 | ไม่พบ Mock Location (Normal GPS) | High | | TC-LOC-04-02 | พบ Mock Location - Fake GPS App | High | | TC-LOC-04-03 | พบ Mock Location - พิกัด (0,0) | High | | TC-LOC-04-04 | พบ Mock Location - ข้อมูลเก่าเกินไป | High | | TC-LOC-04-05 | พบ Mock Location - ความเร็วผิดปกติ | High | | TC-LOC-04-06 | พบ Mock Location - หลาย indicators (Confidence High) | High | ### 4.5 TC-LOC-05: POI Resolution | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-05-01 | แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (Bangkok GIS) | High | | TC-LOC-05-02 | แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (ArcGIS Fallback) | Medium | | TC-LOC-05-03 | แปลงพิกัดล้มเหลว (ทั้งสอง service down) | Low | ### 4.6 TC-LOC-06: Check-in with Location | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-06-01 | ลงเวลาเข้าสำเร็จ - ณ สถานที่ตั้ง (In-place) | High | | TC-LOC-06-02 | ลงเวลาเข้าสำเร็จ - นอกสถานที่ตั้ง (Off-site) | High | | TC-LOC-06-03 | ลงเวลาเข้าล้มเหลว - Mock Location detected | High | | TC-LOC-06-04 | ลงเวลาเข้าล้มเหลว - Location permission denied | High | ### 4.7 TC-LOC-07: Check-out with Location | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-07-01 | ลงเวลาออกสำเร็จ | High | | TC-LOC-07-02 | ลงเวลาออกล้มเหลว - Mock Location detected | High | ### 4.8 TC-LOC-08: Special Time Entry | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-08-01 | บันทึกเวลาพิเศษพร้อมตำแหน่งสำเร็จ | Medium | | TC-LOC-08-02 | บันทึกเวลาพิเศษล้มเหลว - ไม่ระบุตำแหน่ง | Medium | ### 4.9 TC-LOC-09: Privacy Consent | Test Case | Description | Priority | |-----------|-------------|----------| | TC-LOC-09-01 | แสดง Privacy Modal ก่อนใช้ Location | High | | TC-LOC-09-02 | ยอมรับ Privacy Policy | High | | TC-LOC-09-03 | ปฏิเสธ Privacy Policy | High | --- ## 5. Test Cases Details ### Test Case Template ``` Test Case ID: TC-LOC-XX-XX Test Case Name: [ชื่อ Test Case] Description: [คำอธิบาย] Priority: High/Medium/Low Pre-conditions: [เงื่อนไขเบื้องต้น] Test Data: [ข้อมูลทดสอบ] Test Steps: [ขั้นตอนการทดสอบ] Expected Result: [ผลลัพธ์ที่คาดหวัง] Actual Result: [ผลลัพธ์จริง - ว่างไว้กรอก] Status: [Pass/Fail/Not Run] Tested By: [ผู้ทดสอบ] Test Date: [วันที่ทดสอบ] ``` --- ### TC-LOC-01: Location Permission #### TC-LOC-01-01: อนุญาตให้เข้าถึงตำแหน่ง | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-01-01 | | **Test Case Name** | อนุญาตให้เข้าถึงตำแหน่ง | | **Description** | ผู้ใช้อนุญาตให้แอปเข้าถึงตำแหน่ง GPS | | **Priority** | High | | **Pre-conditions** | 1. ยอมรับ Privacy Policy แล้ว
2. เปิดแอปครั้งแรก หรือยังไม่เคยอนุญาต Location Permission | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. กดปุ่มขอตำแหน่ง (ถ้าจำเป็น)
3. เลือก "Allow" เมื่อระบบขอ Location Permission | | **Expected Result** | 1. แสดงแผนที่พร้อมตำแหน่งปัจจุบัน
2. แสดงชื่อสถานที่ใกล้เคียง
3. ปุ่มลงเวลาเข้า/ออกใช้งานได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-01-02: ปฏิเสธการเข้าถึงตำแหน่ง | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-01-02 | | **Test Case Name** | ปฏิเสธการเข้าถึงตำแหน่ง | | **Description** | ผู้ใช้ปฏิเสธการเข้าถึงตำแหน่ง GPS | | **Priority** | High | | **Pre-conditions** | 1. ยอมรับ Privacy Policy แล้ว
2. เปิดแอปครั้งแรก หรือยังไม่เคยอนุญาต Location Permission | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. กดปุ่มขอตำแหน่ง (ถ้าจำเป็น)
3. เลือก "Deny" เมื่อระบบขอ Location Permission | | **Expected Result** | 1. แสดงข้อความแจ้งเตือน: "ไม่สามารถระบุตำแหน่งปัจจุบันได้ เนื่องจากคุณปฏิเสธการเข้าถึงตำแหน่ง กรุณาเปิดการเข้าถึงตำแหน่ง"
2. แผนที่ไม่แสดง
3. ปุ่มลงเวลาเข้า/ออกใช้งานไม่ได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-02: Location Acquisition #### TC-LOC-02-01: รับพิกัด GPS สำเร็จ (Outdoor) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-02-01 | | **Test Case Name** | รับพิกัด GPS สำเร็จ (Outdoor) | | **Description** | รับพิกัด GPS สำเร็จในพื้นที่เปิดกว้าง | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Location: อาคารรัฐสภา แขวง ถนนนครไชยศรี เขตดุสิต กรุงเทพมหานคร (13.7563, 100.5018) | | **Test Steps** | 1. เปิดแอป HRMS
2. อยู่ในพื้นที่เปิดกว้าง (Outdoor)
3. รอรับพิกัด GPS | | **Expected Result** | 1. รับพิกัด GPS สำเร็จ
2. แสดงแผนที่พร้อมตำแหน่ง
3. แสดงชื่อสถานที่ใกล้เคียง
4. locationGranted = true | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-02-02: รับพิกัด GPS สำเร็จ (Indoor) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-02-02 | | **Test Case Name** | รับพิกัด GPS สำเร็จ (Indoor) | | **Description** | รับพิกัด GPS สำเร็จในพื้นที่ปิด | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Location: ภายในอาคารสำนักงาน | | **Test Steps** | 1. เปิดแอป HRMS
2. อยู่ในพื้นที่ปิด (Indoor)
3. รอรับพิกัด GPS | | **Expected Result** | 1. รับพิกัด GPS สำเร็จ
2. แสดงแผนที่พร้อมตำแหน่ง
3. แสดงชื่อสถานที่ใกล้เคียง
4. อาจมีความแม่นยำต่ำกว่า Outdoor | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-02-03: รับพิกัด GPS ล้มเหลว (GPS ไม่ทำงาน) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-02-03 | | **Test Case Name** | รับพิกัด GPS ล้มเหลว (GPS ไม่ทำงาน) | | **Description** | GPS ไม่ทำงาน หรืออยู่ในพื้นที่ที่ไม่มีสัญญาณ GPS | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. ปิด GPS ในอุปกรณ์
3. พยายามขอรับพิกัด | | **Expected Result** | 1. แสดงข้อความแจ้งเตือน: "ไม่สามารถระบุตำแหน่งปัจจุบันได้"
2. แผนที่ไม่แสดง | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-02-04: หมดเวลาขอรับพิกัด (Timeout) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-02-04 | | **Test Case Name** | หมดเวลาขอรับพิกัด (Timeout) | | **Description** | การร้องขอตำแหน่งหมดเวลา | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองสภาวะที่ GPS ตอบสนองช้า (ใช้ Developer Tools)
3. รอจนหมดเวลา | | **Expected Result** | 1. แสดงข้อความแจ้งเตือน: "การร้องขอตำแหน่งหมดเวลา กรุณาลองอีกครั้ง" | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-03: Location Validation #### TC-LOC-03-01: พิกัดถูกต้อง (Valid coordinates) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-01 | | **Test Case Name** | พิกัดถูกต้อง (Valid coordinates) | | **Description** | ตรวจสอบพิกัดที่ถูกต้อง | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Latitude: 13.7563, Longitude: 100.5018, Accuracy: 10m, Timestamp: current | | **Test Steps** | 1. เปิดแอป HRMS
2. รับพิกัด GPS ที่ถูกต้อง | | **Expected Result** | 1. validation = { isValid: true, isMockDetected: false }
2. locationGranted = true
3. ไม่มี error/warning | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-03-02: พิกัดไม่ถูกต้อง (Invalid coordinates - (0,0)) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-02 | | **Test Case Name** | พิกัดไม่ถูกต้อง (Invalid coordinates - (0,0)) | | **Description** | ตรวจสอบพิกัด (0,0) ซึ่งเป็นค่า default ของ mock location | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Latitude: 0, Longitude: 0 | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองพิกัด (0,0) ด้วย Mock Location App | | **Expected Result** | 1. validation = { isValid: false, isMockDetected: true, confidence: 'high' }
2. แสดงข้อความ: "พิกัดตำแหน่งไม่ถูกต้อง กรุณาลองใหม่"
3. disabledBtn = true | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-03-03: พิกัดนอกช่วง (Out of range) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-03 | | **Test Case Name** | พิกัดนอกช่วง (Out of range) | | **Description** | ตรวจสอบพิกัดที่อยู่นอกช่วงที่กำหนด | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Latitude: 91, Longitude: 181 (out of range) | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองพิกัดนอกช่วงด้วย Developer Tools | | **Expected Result** | 1. validation = { isValid: false }
2. แสดงข้อความ: "พิกัดตำแหน่งไม่ถูกต้อง กรุณาลองใหม่" | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-03-04: ข้อมูลตำแหน่งเก่าเกินไป (Stale timestamp) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-04 | | **Test Case Name** | ข้อมูลตำแหน่งเก่าเกินไป (Stale timestamp) | | **Description** | ตรวจสอบว่าข้อมูลตำแหน่งเก่าเกิน 60 วินาที | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Timestamp: Date.now() - 70,000 ms (70 seconds old) | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลอง timestamp เก่าเกิน 60 วินาที | | **Expected Result** | 1. validation.errors = ["ข้อมูลตำแหน่งเก่าเกินไป กรุณารับสัญญาณ GPS ใหม่"]
2. mockIndicators += 2 | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-03-05: ความแม่นยำต่ำ (Poor accuracy) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-05 | | **Test Case Name** | ความแม่นยำต่ำ (Poor accuracy) | | **Description** | ตรวจสอบความแม่นยำของ GPS ต่ำกว่า 100 เมตร | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Accuracy: 150 meters | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองความแม่นยำต่ำด้วย Developer Tools | | **Expected Result** | 1. validation.warnings = ["ความแม่นยำตำแหน่งต่ำเกินไป กรุณาตรวจสอบการรับสัญญาณ GPS"]
2. mockIndicators += 1 | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-03-06: ความเร็วเคลื่อนที่ผิดปกติ (Impossible speed) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-03-06 | | **Test Case Name** | ความเร็วเคลื่อนที่ผิดปกติ (Impossible speed) | | **Description** | ตรวจสอบความเร็วเคลื่อนที่เกิน 100 m/s (360 km/h) | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. มีตำแหน่งเดิมใน history | | **Test Data** | Position 1: (13.7563, 100.5018) at t=0
Position 2: (15.8700, 100.9925) at t=60 (~180 km in 60s = 3000 km/h) | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองการเคลื่อนที่ด้วยความเร็วผิดปกติ | | **Expected Result** | 1. validation.errors = ["ตรวจพบการเคลื่อนที่ด้วยความเร็วผิดปกติ อาจเป็นการจำลองตำแหน่ง"]
2. mockIndicators += 3 | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-04: Mock Location Detection #### TC-LOC-04-01: ไม่พบ Mock Location (Normal GPS) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-01 | | **Test Case Name** | ไม่พบ Mock Location (Normal GPS) | | **Description** | การใช้งาน GPS ปกติ ไม่พบ mock location | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. ไม่ได้เปิด Mock Location App | | **Test Data** | Normal GPS data | | **Test Steps** | 1. เปิดแอป HRMS
2. ใช้งาน GPS ปกติ | | **Expected Result** | 1. validation = { isValid: true, isMockDetected: false }
2. locationGranted = true
3. isMockLocationDetected = false
4. ปุ่มลงเวลาเข้า/ออกใช้งานได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-04-02: พบ Mock Location - Fake GPS App | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-02 | | **Test Case Name** | พบ Mock Location - Fake GPS App | | **Description** | ตรวจพบ mock location จาก Fake GPS App | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Mock location from Fake GPS App | | **Test Steps** | 1. เปิด Fake GPS Location App
2. ตั้งค่าตำแหน่งปลอม
3. เปิดแอป HRMS
4. ขอรับพิกัด | | **Expected Result** | 1. ตรวจพบ mock location (indicators >= 3)
2. แสดงข้อความ: "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง กรุณาปิดแอปจำลองตำแหน่งและลองใหม่"
3. isMockLocationDetected = true
4. disabledBtn = true | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-04-03: พบ Mock Location - พิกัด (0,0) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-03 | | **Test Case Name** | พบ Mock Location - พิกัด (0,0) | | **Description** | ตรวจพบพิกัด (0,0) ซึ่งเป็นค่า default ของ mock location | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Latitude: 0, Longitude: 0 | | **Test Steps** | 1. จำลองพิกัด (0,0) ด้วย Mock Location App
2. เปิดแอป HRMS
3. ขอรับพิกัด | | **Expected Result** | 1. mockIndicators = 3 (จาก invalid coordinates)
2. isMockDetected = true
3. confidence = 'medium'
4. แสดงข้อความแจ้งเตือน | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-04-04: พบ Mock Location - ข้อมูลเก่าเกินไป | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-04 | | **Test Case Name** | พบ Mock Location - ข้อมูลเก่าเกินไป | | **Description** | ตรวจพบข้อมูลตำแหน่งเก่าเกิน 60 วินาที | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Timestamp: Date.now() - 70,000 ms | | **Test Steps** | 1. จำลอง timestamp เก่าเกิน 60 วินาที
2. เปิดแอป HRMS
3. ขอรับพิกัด | | **Expected Result** | 1. mockIndicators = 2 (จาก stale timestamp)
2. แสดง warning: "ข้อมูลตำแหน่งเก่าเกินไป กรุณารับสัญญาณ GPS ใหม่" | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-04-05: พบ Mock Location - ความเร็วผิดปกติ | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-05 | | **Test Case Name** | พบ Mock Location - ความเร็วผิดปกติ | | **Description** | ตรวจพบความเร็วเคลื่อนที่ผิดปกติ | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. มีตำแหน่งเดิมใน history | | **Test Data** | Speed > 100 m/s | | **Test Steps** | 1. จำลองการเคลื่อนที่ด้วยความเร็ว > 100 m/s
2. เปิดแอป HRMS | | **Expected Result** | 1. mockIndicators = 3 (จาก impossible speed)
2. isMockDetected = true
3. confidence = 'medium' | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-04-06: พบ Mock Location - หลาย indicators (Confidence High) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-04-06 | | **Test Case Name** | พบ Mock Location - หลาย indicators (Confidence High) | | **Description** | ตรวจพบหลาย mock indicators พร้อมกัน | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | Combined: invalid coordinates (0,0) + stale timestamp + impossible speed | | **Test Steps** | 1. จำลอง multiple mock indicators
2. เปิดแอป HRMS | | **Expected Result** | 1. mockIndicators >= 5
2. isMockDetected = true
3. confidence = 'high'
4. แสดงข้อความแจ้งเตือนชัดเจน | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-05: POI Resolution #### TC-LOC-05-01: แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (Bangkok GIS) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-05-01 | | **Test Case Name** | แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (Bangkok GIS) | | **Description** | แปลงพิกัดเป็นชื่อสถานที่สำเร็จผ่าน Bangkok GIS API | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. รับพิกัดสำเร็จแล้ว | | **Test Data** | Latitude: 13.7563, Longitude: 100.5018 (Sanam Suea Pa, Bangkok) | | **Test Steps** | 1. เปิดแอป HRMS
2. รับพิกัด GPS
3. รอให้ระบบแปลงพิกัดเป็นชื่อสถานที่ | | **Expected Result** | 1. เรียก Bangkok GIS API: `https://bmagis.bangkok.go.th/...`
2. แสดงชื่อสถานที่ (POI name)
3. poiPlaceName มีค่า | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-05-02: แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (ArcGIS Fallback) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-05-02 | | **Test Case Name** | แปลงพิกัดเป็นชื่อสถานที่สำเร็จ (ArcGIS Fallback) | | **Description** | แปลงพิกัดเป็นชื่อสถานที่สำเร็จผ่าน ArcGIS API (เมื่อ Bangkok GIS fail) | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. Bangkok GIS API ล้มเหลว | | **Test Data** | Latitude: 13.7563, Longitude: 100.5018 | | **Test Steps** | 1. เปิดแอป HRMS
2. รับพิกัด GPS
3. จำลอง Bangkok GIS API fail
4. รอ fallback ไป ArcGIS | | **Expected Result** | 1. เรียก ArcGIS API: `https://geocode.arcgis.com/...`
2. แสดงชื่อสถานที่ (POI name)
3. poiPlaceName มีค่า | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-05-03: แปลงพิกัดล้มเหลว (ทั้งสอง service down) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-05-03 | | **Test Case Name** | แปลงพิกัดล้มเหลว (ทั้งสอง service down) | | **Description** | แปลงพิกัดล้มเหลวเมื่อทั้ง Bangkok GIS และ ArcGIS down | | **Priority** | Low | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. จำลองทั้งสอง API fail | | **Expected Result** | 1. แอปยังทำงานต่อไปได้
2. แผนที่แสดงตำแหน่งแต่ไม่มีชื่อสถานที่
3. formLocation.POI = '' | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-06: Check-in with Location #### TC-LOC-06-01: ลงเวลาเข้าสำเร็จ - ณ สถานที่ตั้ง (In-place) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-06-01 | | **Test Case Name** | ลงเวลาเข้าสำเร็จ - ณ สถานที่ตั้ง (In-place) | | **Description** | ลงเวลาเข้าสำเร็จเมื่ออยู่ ณ สถานที่ตั้ง | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. รับพิกัดและชื่อสถานที่สำเร็จ
4. ถ่ายรูปภาพแล้ว
5. statusCheckin = true (เข้างาน) | | **Test Data** | workplace: 'in-place', locationName: '', POI: 'สนามเสือป่า', img: (รูปถ่าย) | | **Test Steps** | 1. เลือก "ในสถานที่"
2. กด "ลงเวลาเข้างาน"
3. ยืนยันการลงเวลา | | **Expected Result** | 1. API call: POST `/leave/check-in`
2. formdata: { lat, lon, POI, isLocation: true, locationName: '', img, remark, checkInId }
3. แสดง modal ลงเวลาเข้างานสำเร็จ
4. statusCheckin = false | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-06-02: ลงเวลาเข้าสำเร็จ - นอกสถานที่ตั้ง (Off-site) | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-06-02 | | **Test Case Name** | ลงเวลาเข้าสำเร็จ - นอกสถานที่ตั้ง (Off-site) | | **Description** | ลงเวลาเข้าสำเร็จเมื่ออยู่นอกสถานที่ตั้ง | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. รับพิกัดและชื่อสถานที่สำเร็จ
4. ถ่ายรูปภาพแล้ว
5. statusCheckin = true (เข้างาน) | | **Test Data** | workplace: 'off-site', locationName: 'ปฏิบัติงานที่บ้าน (WFH)', POI: 'บ้าน', img: (รูปถ่าย) | | **Test Steps** | 1. เลือก "นอกสถานที่"
2. เลือก "ปฏิบัติงานที่บ้าน (WFH)"
3. กด "ลงเวลาเข้างาน"
4. ยืนยันการลงเวลา | | **Expected Result** | 1. API call: POST `/leave/check-in`
2. formdata: { lat, lon, POI, isLocation: false, locationName: 'ปฏิบัติงานที่บ้าน (WFH)', img, remark, checkInId }
3. แสดง modal ลงเวลาเข้างานสำเร็จ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-06-03: ลงเวลาเข้าล้มเหลว - Mock Location detected | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-06-03 | | **Test Case Name** | ลงเวลาเข้าล้มเหลว - Mock Location detected | | **Description** | ลงเวลาเข้าล้มเหลวเมื่อตรวจพบ mock location | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. เปิด Mock Location App | | **Test Data** | Mock location enabled | | **Test Steps** | 1. เปิด Mock Location App
2. ตั้งค่าตำแหน่งปลอง
3. เปิดแอป HRMS
4. พยายามลงเวลาเข้างาน | | **Expected Result** | 1. แสดงข้อความ: "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง..."
2. isMockLocationDetected = true
3. disabledBtn = true
4. ไม่สามารถลงเวลาเข้างานได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-06-04: ลงเวลาเข้าล้มเหลว - Location permission denied | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-06-04 | | **Test Case Name** | ลงเวลาเข้าล้มเหลว - Location permission denied | | **Description** | ลงเวลาเข้าล้มเหลวเมื่อปฏิเสธ Location Permission | | **Priority** | High | | **Pre-conditions** | 1. ยอมรับ Privacy Policy แล้ว
2. ปฏิเสธ Location Permission | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. ปฏิเสธ Location Permission
3. พยายามลงเวลาเข้างาน | | **Expected Result** | 1. locationGranted = false
2. ปุ่มลงเวลาเข้า/ออก disabled
3. ไม่สามารถลงเวลาเข้างานได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-07: Check-out with Location #### TC-LOC-07-01: ลงเวลาออกสำเร็จ | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-07-01 | | **Test Case Name** | ลงเวลาออกสำเร็จ | | **Description** | ลงเวลาออกสำเร็จพร้อมตำแหน่ง | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. เคยลงเวลาเข้างานแล้ว
4. statusCheckin = false (ออกงาน) | | **Test Data** | POI: 'Office', img: (รูปถ่าย) | | **Test Steps** | 1. เปิดแอป HRMS
2. ถ่ายรูปภาพ
3. กด "ลงเวลาออกงาน" | | **Expected Result** | 1. API call: POST `/leave/check-in` (with checkInId)
2. แสดง modal ลงเวลาออกงานสำเร็จ
3. statusCheckin = true | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-07-02: ลงเวลาออกล้มเหลว - Mock Location detected | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-07-02 | | **Test Case Name** | ลงเวลาออกล้มเหลว - Mock Location detected | | **Description** | ลงเวลาออกล้มเหลวเมื่อตรวจพบ mock location | | **Priority** | High | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. เคยลงเวลาเข้างานแล้ว
4. เปิด Mock Location App | | **Test Data** | Mock location enabled | | **Test Steps** | 1. เปิด Mock Location App
2. พยายามลงเวลาออกงาน | | **Expected Result** | 1. แสดงข้อความ: "ตรวจพบว่าตำแหน่ง GPS อาจไม่ถูกต้อง..."
2. disabledBtn = true
3. ไม่สามารถลงเวลาออกงานได้ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-08: Special Time Entry #### TC-LOC-08-01: บันทึกเวลาพิเศษพร้อมตำแหน่งสำเร็จ | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-08-01 | | **Test Case Name** | บันทึกเวลาพิเศษพร้อมตำแหน่งสำเร็จ | | **Description** | บันทึกเวลาพิเศษพร้อมตำแหน่งสำเร็จ | | **Priority** | Medium | | **Pre-conditions** | 1. อนุญาต Location Permission แล้ว
2. ยอมรับ Privacy Policy แล้ว
3. รับพิกัดสำเร็จ | | **Test Data** | POI: 'Meeting Room', img: (รูปถ่าย) | | **Test Steps** | 1. เปิดแอป HRMS
2. ไปที่หน้าบันทึกเวลาพิเศษ
3. กรอกข้อมูล
4. บันทึก | | **Expected Result** | 1. บันทึกเวลาพิเศษสำเร็จ
2. มีข้อมูลตำแหน่ง | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-08-02: บันทึกเวลาพิเศษล้มเหลว - ไม่ระบุตำแหน่ง | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-08-02 | | **Test Case Name** | บันทึกเวลาพิเศษล้มเหลว - ไม่ระบุตำแหน่ง | | **Description** | บันทึกเวลาพิเศษล้มเหลวเมื่อไม่ระบุตำแหน่ง | | **Priority** | Medium | | **Pre-conditions** | 1. ยอมรับ Privacy Policy แล้ว
2. ปฏิเสธ Location Permission | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. ปฏิเสธ Location Permission
3. พยายามบันทึกเวลาพิเศษ | | **Expected Result** | 1. แจ้งเตือนให้ระบุตำแหน่ง | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ### TC-LOC-09: Privacy Consent #### TC-LOC-09-01: แสดง Privacy Modal ก่อนใช้ Location | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-09-01 | | **Test Case Name** | แสดง Privacy Modal ก่อนใช้ Location | | **Description** | แสดง Privacy Modal ก่อนใช้ Location | | **Priority** | High | | **Pre-conditions** | 1. เปิดแอปครั้งแรก
2. ยังไม่ยอมรับ Privacy Policy | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. กดปุ่มที่ต้องการ Location (แผนที่/กล้อง) | | **Expected Result** | 1. privacyStore.modalPrivacy = true
2. แสดง Privacy Modal
3. ไม่สามารถใช้งาน Location ได้จนกว่าจะยอมรับ | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-09-02: ยอมรับ Privacy Policy | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-09-02 | | **Test Case Name** | ยอมรับ Privacy Policy | | **Description** | ยอมรับ Privacy Policy และใช้งาน Location ได้ | | **Priority** | High | | **Pre-conditions** | 1. เปิดแอปครั้งแรก
2. Privacy Modal แสดงขึ้นมา | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. แสดง Privacy Modal
3. กด "ยอมรับ" | | **Expected Result** | 1. privacyStore.isAccepted = true
2. privacyStore.modalPrivacy = false
3. สามารถใช้งาน Location ได้
4. เรียก mapRef.value?.requestLocationPermission() | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | #### TC-LOC-09-03: ปฏิเสธ Privacy Policy | Field | Value | |-------|-------| | **Test Case ID** | TC-LOC-09-03 | | **Test Case Name** | ปฏิเสธ Privacy Policy | | **Description** | ปฏิเสธ Privacy Policy และไม่สามารถใช้งาน Location | | **Priority** | High | | **Pre-conditions** | 1. เปิดแอปครั้งแรก
2. Privacy Modal แสดงขึ้นมา | | **Test Data** | - | | **Test Steps** | 1. เปิดแอป HRMS
2. แสดง Privacy Modal
3. กด "ปฏิเสธ" หรือปิด Modal | | **Expected Result** | 1. privacyStore.isAccepted = false
2. privacyStore.modalPrivacy = false
3. ไม่สามารถใช้งาน Location ได้
4. แจ้งเตือนเมื่อพยายามใช้งาน Location | | **Actual Result** | | | **Status** | Not Run | | **Tested By** | | | **Test Date** | | --- ## 6. Test Summary ### 6.1 Test Case Statistics | Category | Total | Critical | High | Medium | Low | |----------|-------|----------|------|--------|-----| | Location Permission | 2 | - | 2 | - | - | | Location Acquisition | 4 | - | 2 | 2 | - | | Location Validation | 6 | - | 4 | 2 | - | | Mock Location Detection | 6 | - | 6 | - | - | | POI Resolution | 3 | - | 1 | 1 | 1 | | Check-in with Location | 4 | - | 4 | - | - | | Check-out with Location | 2 | - | 2 | - | - | | Special Time Entry | 2 | - | - | 2 | - | | Privacy Consent | 3 | - | 3 | - | - | | **Total** | **32** | - | **24** | **7** | **1** | ### 6.2 Execution Status | Status | Count | Percentage | |--------|-------|------------| | Not Run | 32 | 100% | | Pass | 0 | 0% | | Fail | 0 | 0% | | Blocked | 0 | 0% | --- ## 7. References ### 7.1 API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/leave/check-in` | POST | Check-in/Check-out with location data | | `/leave/check-time` | GET | Get check-in/check-out status | | `/leave/check-status` | GET | Get queue status | | `/leave/user/checkout-check/{isSeminar}` | GET | Check before check-out | ### 7.2 Key Functions | Function | Location | Description | |----------|----------|-------------| | `validateLocation()` | `useLocationValidation.ts` | Main validation function | | `validateCoordinates()` | `useLocationValidation.ts` | Coordinate validation | | `validateTimestamp()` | `useLocationValidation.ts` | Timestamp validation | | `validateAccuracy()` | `useLocationValidation.ts` | Accuracy validation | | `validateSpeed()` | `useLocationValidation.ts` | Speed validation | | `haversineDistance()` | `useLocationValidation.ts` | Distance calculation | | `checkPrivacyAccepted()` | `usePermissions.ts` | Check privacy consent | | `requestLocationPermission()` | `AscGISMap.vue` | Request location permission | ### 7.3 Related Files - `/src/composables/useLocationValidation.ts` - Location validation logic - `/src/views/HomeView.vue` - Check-in/Check-out page - `/src/components/AscGISMap.vue` - Map component with location validation - `/src/api/api.checkin.ts` - Check-in API endpoints - `/src/stores/privacy.ts` - Privacy store for consent management - `/src/composables/usePermissions.ts` - Permission checking utilities --- ## 8. Revision History | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0.0 | 2025-03-09 | QA Team | Initial version - 32 test cases for Location features | --- ## 9. Approval | Role | Name | Signature | Date | |------|------|-----------|------| | QA Lead | | | | | Developer | | | | | Product Owner | | | |