payfrit-beacon-ios/QA_WALKTHROUGH.md
2026-02-01 23:39:29 -08:00

12 KiB

Payfrit Beacon iOS — QA Walkthrough Test Document

Overview

App: Payfrit Beacon iOS (SwiftUI) Purpose: BLE beacon management for business locations Auth: Token-based with Keychain storage + biometric Environment: Dev (dev.payfrit.com) / Prod (biz.payfrit.com) — hardcoded in APIService.swift:50


Pre-Test Setup

  • Device has iOS 14+
  • Bluetooth enabled in Settings
  • Location Services enabled in Settings
  • Stable network connection (Wi-Fi or LTE)
  • A physical BLE beacon available for scanner tests
  • Test account with at least 1 business, 1 beacon, 1 service point

1. Authentication Flow

1.1 First-Time Login

Step Action Expected
1 Launch app (fresh install) LoginScreen shown
2 Leave fields empty, tap "Sign In" Button disabled (name/password empty)
3 Enter email only, tap "Sign In" Error: "Please enter username and password"
4 Enter valid email + wrong password Error: "Invalid email/phone or password"
5 Enter valid credentials, tap "Sign In" Loading spinner on button, navigates to BusinessSelectionScreen
6 Kill and relaunch app Saved auth loaded, skips login

1.2 Biometric Re-Auth (Device Only, Skipped on Simulator)

Step Action Expected
1 Relaunch app with saved auth Face ID / Touch ID prompt appears
2 Authenticate successfully Navigates to BusinessSelectionScreen
3 Relaunch, cancel biometric Still loads saved auth (fallback)

1.3 Logout

Step Action Expected
1 From BusinessSelectionScreen, tap logout (top-right arrow icon) Clears Keychain + UserDefaults, returns to LoginScreen
2 Kill and relaunch LoginScreen shown (no saved auth)

1.4 Session Expiry (401)

Step Action Expected
1 Login, wait for token to expire (or invalidate server-side) Next API call returns 401
2 Try any action (list beacons, etc.) Auto-logout, returns to LoginScreen

1.5 Dev Mode Indicator

Step Action Expected
1 Launch in dev environment LoginScreen shows red "DEV MODE — password: 123456"
2 After login, check bottom-left of RootView Orange "DEV" banner visible

2. Business Selection

2.1 Load Businesses

Step Action Expected
1 Login successfully BusinessSelectionScreen loads with spinner
2 Wait for load List of businesses with name + city
3 Tap a business Pushes to BeaconDashboard, shows "Loading..." then TabView

2.2 Edge Cases

Scenario Expected
User has no businesses "No businesses found" message, can only logout
Network error during load Error message + "Retry" button
Tap Retry Re-fetches business list
401 during load Auto-logout to LoginScreen

3. Beacon Management (Beacons Tab)

3.1 View Beacon List

Step Action Expected
1 Tap "Beacons" tab List loads with spinner
2 Verify beacon rows Each shows: name, formatted UUID (XXXXXXXX-XXXX-...), active badge (green check / red X)
3 Pull down to refresh Spinner appears, list refreshes
4 Empty list "No beacons yet" + "Tap + to add" message

3.2 Create Beacon

Step Action Expected
1 Tap + button BeaconEditSheet modal appears
2 Leave fields empty, tap Save Button disabled
3 Enter name only Button disabled (UUID required)
4 Enter name + valid 32-char hex UUID Save enabled
5 Tap Save Modal dismisses, list refreshes with new beacon
6 Network error during save Error shown in sheet, sheet stays open

3.3 Edit Beacon

Step Action Expected
1 Tap a beacon row Pushes to BeaconDetailScreen
2 Verify pre-filled fields Name, UUID, Active toggle match beacon data
3 Verify read-only fields ID, Business ID, Created, Updated dates shown
4 Change name, tap "Save Changes" Returns to list, beacon updated
5 Toggle Active off, save Badge changes from green check to red X
6 Clear name, try save Button disabled

3.4 Delete Beacon (Detail Screen)

Step Action Expected
1 From BeaconDetailScreen, tap "Delete Beacon" Alert: "Delete Beacon?" with warning about service points
2 Tap "Cancel" Nothing happens
3 Tap "Delete" API call, returns to list, beacon removed
4 Network error during delete Error shown, stays on detail screen

3.5 Delete Beacon (Swipe)

Step Action Expected
1 Swipe left on beacon row Delete action appears
2 Tap delete Beacon removed immediately (optimistic)
3 If API fails Beacon re-added to list, error shown

3.6 Rapid Delete Stress Test

Step Action Expected
1 Swipe-delete 3 beacons quickly All removed from UI
2 Wait for API responses Failed deletes restored, successful ones stay removed

4. Service Points (Service Points Tab)

4.1 View Service Points

Step Action Expected
1 Tap "Service Points" tab List loads (fetches both service points AND beacons)
2 Verify rows Name, type, active indicator (green/red circle), beacon assignment
3 Pull down to refresh Refreshes both lists
4 Empty list "No service points" message

4.2 Assign Beacon

Step Action Expected
1 Find service point with "No beacon assigned" "Assign" button visible
2 Tap "Assign" BeaconPickerSheet opens with all beacons
3 Tap a beacon Sheet dismisses, spinner on row, then beacon name in green

4.3 Change Beacon Assignment

Step Action Expected
1 Find service point with assigned beacon "Change" button + X button visible
2 Tap "Change" Picker opens, current beacon has checkmark
3 Select different beacon Assignment updated

4.4 Unassign Beacon

Step Action Expected
1 Find service point with assigned beacon X button visible
2 Tap X button API called with nil beaconId, shows "No beacon assigned"

4.5 Edge Cases

Scenario Expected
No beacons exist Picker opens with empty list
Network error during assign Error shown, assignment reverted
401 during any operation Auto-logout

5. Scanner (Scanner Tab)

5.1 Basic Scanning Flow

Step Action Expected
1 Tap "Scanner" tab Beacon picker loads at top
2 No beacon selected "Start Scanning" button disabled
3 Select a beacon from picker Button becomes enabled
4 Tap "Start Scanning" Status: "Scanning..." (blue antenna icon)
5 Move close to matching beacon RSSI value appears, samples count up (X/5)
6 Stay close for 5+ samples with RSSI >= -75 "Beacon Detected! (avg -XX dBm)" (green checkmark)
7 Tap "Stop Scanning" Status resets to "Select a beacon to scan"

5.2 Signal Strength Visualization

RSSI Range Bar Color Signal Quality
-30 to -51 Green Strong
-52 to -72 Yellow Medium
-73 to -100 Red Weak

5.3 RSSI Threshold Behavior

Step Action Expected
1 Scanning, RSSI >= -75 Sample appended, count increments
2 RSSI drops below -75 All samples cleared, count resets to 0
3 RSSI returns above -75 Samples start accumulating again from 0
4 Beacon disappears entirely (RSSI = 0) Samples cleared, "Searching for beacon signal..."

5.4 Permission Handling

Scenario Expected
Location not determined System prompt shown, scanning waits
Location granted after prompt Scanning starts automatically
Location denied "Location Permission Denied" (red), scanning stops
Location denied in Settings Same as above on next scan attempt
Bluetooth off "Bluetooth is OFF" (orange), scanning stops
Bluetooth turned off mid-scan Detected within 5 seconds, scanning stops

5.5 Beacon Change During Scan

Step Action Expected
1 Start scanning for Beacon A Scanning active
2 Change picker to Beacon B Scan stops immediately
3 Tap "Start Scanning" New scan starts for Beacon B

5.6 Screen Lock Prevention

Step Action Expected
1 Start scanning Screen stays awake (idle timer disabled)
2 Stop scanning Idle timer re-enabled, screen can lock normally

5.7 Error Cases

Scenario Expected
Invalid UUID format on beacon Error: "Invalid beacon UUID format"
Ranging failure (CLLocationManager error) Error: "Beacon ranging failed: [description]"
Beacon list fails to load Picker empty, scanner still functional if UUID known

6. Cross-Cutting Concerns

6.1 Network Error Handling (All Screens)

Scenario Expected
Airplane mode during API call Network error displayed
Server returns 500 "HTTP 500" error shown
Server returns non-JSON "Decoding error: Non-JSON response"
Server returns {"OK": false, "ERROR": "..."} Error message from server shown
401 on any authenticated endpoint Auto-logout to LoginScreen

6.2 Navigation

Test Expected
Back button from BeaconDetailScreen Returns to BeaconListScreen
Back button from BeaconDashboard Returns to BusinessSelectionScreen
Tab switching in BeaconDashboard Beacons / Service Points / Scanner tabs all functional
Deep link: Business > Beacon > Detail > Back > Back Full nav stack unwinds cleanly

6.3 Data Consistency

Test Expected
Add beacon, switch to Service Points tab New beacon available in picker
Delete beacon assigned to service point Service point shows "No beacon assigned" on refresh
Edit beacon name Updated name shows in list and service point rows

7. API Endpoints Reference

Action Method Endpoint
Login POST /auth/login.cfm
List businesses POST /workers/myBusinesses.cfm
List beacons POST /beacons/list.cfm
Get beacon POST /beacons/get.cfm
Create beacon POST /beacons/create.cfm
Update beacon POST /beacons/update.cfm
Delete beacon POST /beacons/delete.cfm
List service points POST /servicePoints/list.cfm
List SP types POST /servicePoints/types.cfm
Assign beacon to SP POST /servicePoints/assignBeacon.cfm

All requests include headers:

  • Content-Type: application/json
  • X-User-Token: <token> (after login)
  • X-Business-ID: <id> (after business selection)

8. Permissions Checklist

Permission Info.plist Key When Prompted
Location (When In Use) NSLocationWhenInUseUsageDescription First beacon scan
Location (Always) NSLocationAlwaysAndWhenInUseUsageDescription Background scanning
Bluetooth NSBluetoothAlwaysUsageDescription First beacon scan
Face ID NSFaceIDUsageDescription App relaunch with saved auth

9. Known Limitations

  1. Environment switching requires code change + recompile (APIService.swift:50)
  2. Service points are read-only — can only assign/unassign beacons, not create/edit/delete SPs
  3. No token refresh — expired tokens force full re-login
  4. Single scanner — only one scan at a time, changing beacon stops previous
  5. Background scanning depends on iOS version and background mode support
  6. Photo URLs resolved but not cached across sessions