381 lines
9.8 KiB
Markdown
381 lines
9.8 KiB
Markdown
# ✅ Development Checklist & Testing
|
|
|
|
## 🎯 Pre-Deployment Checklist
|
|
|
|
### Configuration ✓
|
|
- [ ] Update `REFERENCE_LATITUDE` dan `REFERENCE_LONGITUDE` di `AttendanceConfig.kt`
|
|
- [ ] Set `ALLOWED_RADIUS_METERS` ke nilai yang benar
|
|
- [ ] Update `STUDENT_NPM` dan `STUDENT_NAMA`
|
|
- [ ] Verify webhook URLs (`WEBHOOK_PRODUCTION` dan `WEBHOOK_TEST`)
|
|
- [ ] Set `PHOTO_QUALITY` ke nilai optimal (80 recommended)
|
|
|
|
### Permissions ✓
|
|
- [ ] AndroidManifest.xml include semua required permissions
|
|
- [ ] Location permissions (FINE_LOCATION, COARSE_LOCATION)
|
|
- [ ] Camera permission
|
|
- [ ] Internet permission
|
|
|
|
### Location Validation ✓
|
|
- [ ] LocationValidator.calculateDistance() bekerja dengan benar
|
|
- [ ] isLocationValid() mengembalikan hasil yang akurat
|
|
- [ ] getValidationMessage() menampilkan pesan yang jelas
|
|
- [ ] Haversine formula calculation sudah tested
|
|
- [ ] Edge cases sudah di-handle (same location, very far, etc)
|
|
|
|
### API Integration ✓
|
|
- [ ] N8nService bisa serialize Bitmap ke Base64
|
|
- [ ] Request body JSON format sesuai dengan N8n expectation
|
|
- [ ] Response codes (200, 400, 500) ditangani dengan baik
|
|
- [ ] Error messages user-friendly dan informatif
|
|
- [ ] Timeout handling sudah implemented
|
|
- [ ] Test dengan WEBHOOK_TEST dulu sebelum PRODUCTION
|
|
|
|
### UI/UX ✓
|
|
- [ ] PhotoPreviewCard menampilkan foto dengan benar
|
|
- [ ] LocationStatusCard menampilkan koordinat dan jarak akurat
|
|
- [ ] ErrorAlertCard dismissable dan muncul saat ada error
|
|
- [ ] SubmitButtonWithLoader loading state visible
|
|
- [ ] Loading spinner saat ambil GPS
|
|
- [ ] Loading spinner saat submit
|
|
- [ ] Form disabled sampai semua data ready
|
|
- [ ] Scrollable untuk device dengan screen kecil
|
|
|
|
### Error Handling ✓
|
|
- [ ] GPS tidak tersedia → clear error message
|
|
- [ ] Permission denied → actionable error message
|
|
- [ ] Network error → suggest retry
|
|
- [ ] Location invalid → show distance info
|
|
- [ ] Foto tidak ambil → prompt untuk retry
|
|
- [ ] Server error → indicate temporary issue
|
|
- [ ] All errors dismissable atau auto-clear
|
|
|
|
### State Management ✓
|
|
- [ ] AttendanceState properly initialized
|
|
- [ ] State updates immutable (menggunakan .copy())
|
|
- [ ] LaunchedEffect untuk side effects
|
|
- [ ] Permission launchers properly connected
|
|
- [ ] State reset setelah successful submission
|
|
|
|
### Testing ✓
|
|
- [ ] Unit tests LocationValidator berjalan sukses
|
|
- [ ] All distance calculations accurate
|
|
- [ ] Edge cases (distance=0, very far) handled
|
|
- [ ] Manual test: permission flow
|
|
- [ ] Manual test: GPS acquisition
|
|
- [ ] Manual test: photo capture
|
|
- [ ] Manual test: form validation
|
|
- [ ] Manual test: webhook submission
|
|
|
|
---
|
|
|
|
## 🧪 Manual Testing Scenarios
|
|
|
|
### Scenario 1: Happy Path (Semua Berjalan Baik)
|
|
```
|
|
1. ✓ App launch → Request location permission
|
|
2. ✓ Grant permission → GPS location acquired
|
|
3. ✓ LocationStatusCard shows valid location + distance
|
|
4. ✓ User click "Ambil Foto" → Camera app opens
|
|
5. ✓ Take selfie → Photo preview shows
|
|
6. ✓ PhotoPreviewCard displays foto correctly
|
|
7. ✓ All validation checks pass
|
|
8. ✓ Submit button enabled
|
|
9. ✓ Click "Kirim Absensi" → Loading shows
|
|
10. ✓ Response 200 → Success toast appears
|
|
11. ✓ Form auto-reset after 2 seconds
|
|
```
|
|
|
|
**Expected Result**: ✅ Success message shown, form reset
|
|
|
|
---
|
|
|
|
### Scenario 2: Location Outside Radius
|
|
```
|
|
1. ✓ GPS location acquired: -7.05, 110.45 (far away)
|
|
2. ✓ LocationStatusCard shows "✗ Lokasi tidak valid"
|
|
3. ✓ Shows distance exceeded radius
|
|
4. ✓ Submit button remains DISABLED
|
|
5. ✓ User can't submit until inside radius
|
|
```
|
|
|
|
**Expected Result**: ✅ Form disabled, validation error clear
|
|
|
|
---
|
|
|
|
### Scenario 3: Permission Denied
|
|
```
|
|
1. ✓ App launch → Permission dialog appears
|
|
2. ✓ User click "Deny" → Error message shows
|
|
3. ✓ Error: "Izin lokasi ditolak"
|
|
4. ✓ User can open Settings to grant permission manually
|
|
```
|
|
|
|
**Expected Result**: ✅ Clear error, actionable message
|
|
|
|
---
|
|
|
|
### Scenario 4: Camera Not Available
|
|
```
|
|
1. ✓ User click "Ambil Foto"
|
|
2. ✗ Device tidak support camera
|
|
3. ✓ Permission denied → Error message shows
|
|
4. ✓ Error: "Izin kamera ditolak"
|
|
```
|
|
|
|
**Expected Result**: ✅ Graceful handling, clear message
|
|
|
|
---
|
|
|
|
### Scenario 5: Network Error
|
|
```
|
|
1. ✓ All validation pass, ready to submit
|
|
2. ✗ Internet disconnected
|
|
3. ✓ Submit attempt → Network error occurs
|
|
4. ✓ Error message: "Tidak dapat terhubung ke server"
|
|
5. ✓ Loading spinner goes away
|
|
6. ✓ User can retry submission
|
|
```
|
|
|
|
**Expected Result**: ✅ Error handled, user can retry
|
|
|
|
---
|
|
|
|
### Scenario 6: Server Error (5xx)
|
|
```
|
|
1. ✓ All validation pass, ready to submit
|
|
2. ✓ Internet OK, but server returns 500
|
|
3. ✓ Error message shown: "Gagal kirim ke server"
|
|
4. ✓ Suggest checking later or contacting admin
|
|
5. ✓ User can retry
|
|
```
|
|
|
|
**Expected Result**: ✅ Error message clear, retry available
|
|
|
|
---
|
|
|
|
## 🔄 Testing with Different Locations
|
|
|
|
### Test Case 1: Inside Radius (Valid)
|
|
```
|
|
Reference: -7.0, 110.4
|
|
Test Location: -7.0005, 110.4005
|
|
Distance: ~50m
|
|
Expected: ✓ VALID
|
|
```
|
|
|
|
### Test Case 2: On Radius Boundary
|
|
```
|
|
Reference: -7.0, 110.4
|
|
Test Location: -7.0008, 110.4008
|
|
Distance: ~113m
|
|
Radius: 100m
|
|
Expected: ✗ INVALID (just outside)
|
|
```
|
|
|
|
### Test Case 3: Far Away
|
|
```
|
|
Reference: -7.0, 110.4
|
|
Test Location: -7.1, 110.5
|
|
Distance: ~15km+
|
|
Expected: ✗ INVALID
|
|
```
|
|
|
|
---
|
|
|
|
## 📱 Device Testing
|
|
|
|
### Minimum Requirements
|
|
- [ ] Android 8.0 (API 28) or higher
|
|
- [ ] 100MB free storage (APK + photo temp)
|
|
- [ ] Active internet connection
|
|
- [ ] Location services enabled
|
|
- [ ] Google Play Services installed
|
|
|
|
### Test Devices
|
|
- [ ] Physical device (recommended)
|
|
- [ ] Emulator with Google Play Services
|
|
- [ ] Different Android versions (8, 10, 12, 13, 14)
|
|
- [ ] Different screen sizes (small, normal, large)
|
|
|
|
### Test Scenarios per Device
|
|
```
|
|
Device 1: Samsung Galaxy (Android 14)
|
|
[ ] Location acquisition
|
|
[ ] Photo capture quality
|
|
[ ] Network stability
|
|
[ ] UI rendering
|
|
|
|
Device 2: Emulator (Android 12)
|
|
[ ] Permission flows
|
|
[ ] GPS emulation
|
|
[ ] Network simulation
|
|
[ ] Error handling
|
|
```
|
|
|
|
---
|
|
|
|
## 🐛 Debug Mode Checklist
|
|
|
|
### Enable Logging
|
|
```kotlin
|
|
// Di MainActivity atau N8nService
|
|
android.util.Log.d("AbsensiApp", "Location: $latitude, $longitude")
|
|
android.util.Log.d("AbsensiApp", "Distance: $distance meters")
|
|
android.util.Log.d("AbsensiApp", "Validation: $isValid")
|
|
android.util.Log.d("N8nService", "Request: ${json.toString()}")
|
|
android.util.Log.d("N8nService", "Response: $responseCode")
|
|
```
|
|
|
|
### Check Logcat
|
|
```bash
|
|
# Filter logs
|
|
adb logcat | grep "AbsensiApp"
|
|
adb logcat | grep "N8nService"
|
|
|
|
# View all logs
|
|
View → Tool Windows → Logcat (in Android Studio)
|
|
```
|
|
|
|
### Monitor Network
|
|
- [ ] Fiddler or Charles Proxy untuk intercept requests
|
|
- [ ] Verify JSON payload format
|
|
- [ ] Check response codes and messages
|
|
|
|
### Test GPS Simulation (Emulator)
|
|
```
|
|
Extended Controls → Location → Set latitude/longitude
|
|
Or use GPX file untuk simulate route
|
|
```
|
|
|
|
---
|
|
|
|
## ✨ Performance Checklist
|
|
|
|
### App Performance
|
|
- [ ] App startup time < 3 seconds
|
|
- [ ] Location acquisition < 5 seconds
|
|
- [ ] Photo capture responsive (no lag)
|
|
- [ ] Network request timeout configured (30s)
|
|
- [ ] No memory leaks in state management
|
|
- [ ] Bitmap properly disposed after submission
|
|
|
|
### UI Responsiveness
|
|
- [ ] Main thread not blocked by long operations
|
|
- [ ] Network calls on background thread
|
|
- [ ] Permission requests on main thread
|
|
- [ ] State updates propagate quickly
|
|
- [ ] No janky animations/scrolls
|
|
|
|
---
|
|
|
|
## 🔒 Security Checklist
|
|
|
|
### Data Protection
|
|
- [ ] GPS coordinates obfuscated/adjusted if needed
|
|
- [ ] Photo compressed to reasonable size
|
|
- [ ] HTTPS used for API calls
|
|
- [ ] Sensitive data not logged
|
|
- [ ] Hardcoded NPM/nama moved to config
|
|
- [ ] No credentials in code
|
|
|
|
### Permission Security
|
|
- [ ] Only request necessary permissions
|
|
- [ ] Graceful degradation if permission denied
|
|
- [ ] No forced prompts for optional features
|
|
- [ ] Runtime permissions properly handled
|
|
|
|
---
|
|
|
|
## 📊 Pre-Release Checklist
|
|
|
|
### Code Quality
|
|
- [ ] No TODOs or FIXMEs remaining
|
|
- [ ] All error paths handled
|
|
- [ ] No hardcoded strings (use resources)
|
|
- [ ] Proper error messages for users
|
|
- [ ] Code formatted and commented
|
|
- [ ] No debugging logs in release build
|
|
|
|
### Build Configuration
|
|
- [ ] Correct minSdk/targetSdk set
|
|
- [ ] ProGuard/R8 configured for release
|
|
- [ ] Signing key configured
|
|
- [ ] Version code incremented
|
|
- [ ] Version name updated in build.gradle
|
|
|
|
### Documentation
|
|
- [ ] README.md complete
|
|
- [ ] DOKUMENTASI.md updated
|
|
- [ ] PANDUAN_IMPLEMENTASI.md accurate
|
|
- [ ] QUICK_REFERENCE.md helpful
|
|
- [ ] Code comments clear and useful
|
|
|
|
### Testing Complete
|
|
- [ ] All unit tests pass
|
|
- [ ] Manual testing scenarios completed
|
|
- [ ] Different device/OS combinations tested
|
|
- [ ] Error scenarios all handled
|
|
- [ ] Performance acceptable
|
|
- [ ] No crash on common operations
|
|
|
|
---
|
|
|
|
## 🚀 Release Steps
|
|
|
|
1. **Finalize Configuration**
|
|
```
|
|
[ ] Update AttendanceConfig with production values
|
|
[ ] Set WEBHOOK_PRODUCTION as default
|
|
```
|
|
|
|
2. **Build Release APK**
|
|
```bash
|
|
./gradlew assembleRelease
|
|
```
|
|
|
|
3. **Sign APK** (if needed)
|
|
```bash
|
|
jarsigner -verbose -sigalg SHA1withRSA \
|
|
-digestalg SHA1 \
|
|
-keystore keystore.jks \
|
|
app-release-unsigned.apk alias_name
|
|
```
|
|
|
|
4. **Test Release APK**
|
|
```
|
|
[ ] Install on device
|
|
[ ] Test all scenarios
|
|
[ ] Verify permissions work
|
|
[ ] Test location validation
|
|
[ ] Test API submission
|
|
```
|
|
|
|
5. **Deploy**
|
|
```
|
|
[ ] Upload to Play Store / distribute APK
|
|
[ ] Monitor for crashes/feedback
|
|
[ ] Be ready to support users
|
|
```
|
|
|
|
---
|
|
|
|
## 📞 Post-Launch Support
|
|
|
|
### Monitor
|
|
- [ ] Crash Analytics (Firebase if available)
|
|
- [ ] User feedback and reviews
|
|
- [ ] N8n webhook logs
|
|
- [ ] Server/network issues
|
|
|
|
### Maintenance
|
|
- [ ] Fix any reported bugs
|
|
- [ ] Update coordinates if location changes
|
|
- [ ] Monitor API response times
|
|
- [ ] Keep Play Services updated
|
|
|
|
---
|
|
|
|
**Status**: Ready for deployment ✅
|
|
**Last Checked**: January 14, 2026
|
|
|