Device Templates

Comprehensive manual QA testing plan for device templates — configuration presets for devices (~160 tests).

Context#

Comprehensive manual QA testing plan for device templates — configuration presets applied to devices that define which campaign content to show, the checkout experience, and the maximum donation amount. Templates link to a published Campaign or Campaign Group as their content source and provide fallback content for when the primary content is unavailable.


How to Use This Plan#

  • Work through each section sequentially
  • For every setting: change it, save, refresh the page, and confirm it persisted
  • Mark each item pass/fail as you go
  • Pre-requisites: At least 1 published campaign and 1 published campaign group should exist

Key Concepts#

ConceptDetails
Content SourceEach template references a Campaign (ID prefix fc) or Campaign Group (ID prefix fcg)
Checkout ModeEXPRESS, QUICK, or STANDARD — controls the donor checkout flow on the device
Maximum DonationCurrency-aware cap on single donation amount (stored in cents, displayed in dollars)
Fallback ContentTitle + message shown on devices when the primary campaign content is unavailable
Linked DevicesDevices using this template inherit its configuration

1. Device Templates List Page#

Route: /dashboard/{org}/devices/templates

1.1 Data Table Display#

  • Page loads and displays all device templates in a table
  • Columns visible:
    • Name — sortable, title variant
    • Devices — device count using this template, right-aligned, sortable
    • Content — resolved name of the linked campaign/campaign group, sortable
    • Content ID — raw content ID string, sortable
    • Checkout Mode — formatted as "Express", "Quick", or "Standard", sortable
    • Created — formatted date, sortable
    • ID — template identifier
  • All column data matches expected values for each template
  • Content column shows resolved campaign/campaign group name (not raw ID)
  • Content name resolution handles:
    • Campaign IDs (prefix fc) → shows campaign internal_name
    • Campaign Group IDs (prefix fcg) → shows campaign group internal_name
    • Missing/deleted content → shows "-"

1.2 Sorting#

  • Default sort: Device Count (descending)
  • Name — click to sort alphabetically asc/desc
  • Devices — click to sort by device count
  • Created Date — click to sort by creation date
  • Sorting persists in URL params
  • Sort order survives page refresh

1.3 Filtering#

  • Device Count (range filter):
    • Set min device count → filters correctly
    • Set max device count → filters correctly
    • Set both → range filter works
  • Clearing filter restores full list
  • Filter state persists in URL params
  • Search by template name — matches correctly (partial match)
  • Search by content name (resolved) — matches correctly
  • Search by template ID — matches correctly (prefix match)
  • Search by content ID — matches correctly (prefix match)
  • Clear search restores full list
  • Search works in combination with filters

1.5 Pagination#

  • Pagination controls appear when templates exceed page size
  • Page size options: 20, 50, 100
  • Navigating pages works correctly
  • Page state persists in URL

1.6 Mobile Responsive#

  • Resize to mobile width — table switches to card view
  • Mobile card shows:
    • Template name
    • Content name (resolved via useResolveContentName hook)
    • Device count chip (info variant)
  • Skeleton loading state shows while data fetches
  • Actions are accessible on mobile cards

1.7 Row Actions#

  • Edit → navigates to template detail page
  • Delete → opens DeleteTemplateModal

1.8 Empty States#

  • No templates: Shows empty state with "Create new template" button
  • Filters applied, no results: Shows filter empty state with "Clear Filters" button
  • Error loading: Shows error state with retry button

1.9 Add Template Button#

  • "Add Template" button visible at top of page
  • Clicking opens NewTemplateModal

2. Device Template Creation#

2.1 New Template Modal#

  • Click "Add Template" button — modal opens
  • Name field:
    • Required — cannot submit empty
    • Max 40 characters enforced
    • Placeholder: "Enter template name"
  • Content field (combobox):
    • Required — cannot submit without selection
    • Shows loading spinner while campaigns/groups are fetching
    • Campaign Groups section shown first (with "Campaign Groups" header)
    • Campaigns section shown below (with "Campaigns" header)
    • Only PUBLISHED campaigns and campaign groups are available
    • Draft/Archived campaigns do NOT appear
    • Search within combobox filters options
    • Each option shows: internal_name + title as description
  • Checkout Mode field (dropdown):
    • Required — defaults to EXPRESS
    • Options: Express, Quick, Standard
    • All three options selectable
  • No maximum donation amount field in creation modal (set on detail page)
  • No fallback content fields in creation modal (set on detail page)
  • Create button:
    • Disabled until name AND content are provided
    • Shows loading state during submission
    • Cannot close modal during submission
  • On success:
    • Modal closes
    • Device templates list cache invalidated
    • Navigates to new template's detail page
    • New template appears in templates list
  • Cancel button closes modal without creating

3. Device Template Detail Page#

Route: /dashboard/{org}/devices/templates/{templateId}

3.1 Header#

  • Template name displays as title
  • Breadcrumb links back to "Templates" list
  • No footer (templates don't track raised amounts)

3.2 Main Details Card (Editable)#

Name Field#

  • Shows current template name
  • Change name → Save → Refresh → Name persisted
  • Name updates in header after save
  • Name updates in templates list
  • Empty name → validation error (save disabled)
  • Max 40 characters enforced

Content Field (Combobox)#

  • Shows currently selected content (campaign or campaign group name)
  • Click to open combobox dropdown
  • Campaign Groups section shown first (with header)
  • Campaigns section shown below (with header)
  • Only PUBLISHED campaigns and campaign groups available
  • Search within combobox filters options by name
  • Select a different campaign → field updates
  • Select a campaign group → field updates
  • Change content → Save → Refresh → New content persisted
  • Content column in templates list updates with new resolved name
  • Error: "Content is required" if cleared/empty

Checkout Mode Field (Dropdown)#

  • Shows current checkout mode
  • Options: Express, Quick, Standard
  • Change mode → Save → Refresh → Mode persisted
  • Mode column in templates list updates
  • Device behavior check: Checkout mode affects the donation flow on physical devices

Maximum Donation Amount Field#

  • Shows current maximum donation amount with currency symbol prefix
  • Formatted with comma separators (e.g., $1,000)
  • Required — cannot save without a value
  • Enter amount → Save → Refresh → Amount persisted
  • Validation:
    • Empty → "Amount is required" error
    • Amount = 0 → validation error
    • Amount > 100,000 → "Cannot exceed {currency}100,000" error
    • Negative amount → validation error
  • Currency handling:
    • Currency symbol matches template's currency
    • Value stored in cents (multiplied by currency multiplier on save)
    • Value displayed in dollars (divided by currency multiplier on load)
    • Different currencies use correct multipliers

Save Behavior#

  • Save button disabled until changes are made
  • Save button disabled if validation fails
  • Saving shows loading state
  • Success toast appears after save
  • Error toast appears on failure
  • Device templates cache invalidated after save

3.3 Fallback Content Card (Editable — Independent Save)#

  • Description: "Set the fallback title and message shown when the primary campaign content is unavailable."
  • Title field:
    • Text input, optional
    • Placeholder: "Enter fallback title"
    • Enter title → Save → Refresh → Title persisted
    • Clear title → Save → Refresh → Title cleared
  • Message field:
    • Textarea, 3 rows, optional
    • Placeholder: "Enter fallback message"
    • Enter message → Save → Refresh → Message persisted
    • Clear message → Save → Refresh → Message cleared
  • Both fields optional — can save with both empty
  • Independent save: This card has its own Save button, separate from Main Details
    • Changing fallback content does NOT enable Main Details save button
    • Saving fallback content does NOT affect Main Details card
    • Both cards can be saved independently
  • Save button disabled until changes are made
  • Success toast appears after save
  • Device templates cache invalidated after save
  • Device behavior check: When primary campaign content is unavailable, device shows fallback title + message

3.4 Linked Devices Card (Read-Only)#

  • Card title shows: "Linked Devices ({count})"
  • Displays first 5 devices as clickable links to device detail pages
  • Each link shows device name
  • If > 5 devices: "See all" link appears → navigates to devices list filtered by this template (/devices?template={templateId})
  • If 0 devices: Empty state message with link to Devices page
  • Device links navigate to correct device detail pages
  • Count matches actual number of devices using this template

3.5 Delete Template Card#

  • Description/warning: "Ensure no devices are using this template before deleting."
  • Delete button is red/destructive
  • Clicking opens DeleteTemplateModal

4. Device Template Deletion#

4.1 Delete Template Modal#

  • Shows template name (read-only)
  • Destructive warning: "Ensure no devices are using this template before deleting."
  • Delete button is red/destructive
  • Shows loading state during deletion
  • Cannot close modal during deletion
  • On success:
    • Success toast: "Template deleted"
    • Device templates list cache invalidated
    • Navigates back to templates list (or triggers onSuccess callback)
    • Template disappears from list
  • Cancel button closes modal without deleting

4.2 Deletion Edge Cases#

  • Delete template with 0 linked devices → clean deletion
  • Delete template with linked devices → what happens?
    • Server may reject deletion (verify behavior)
    • Or devices become orphaned (need re-assignment)
    • Verify the warning message guides user correctly
  • Try to navigate to a deleted template's URL → appropriate error/redirect

5. Content Resolution#

5.1 useResolveContentName Hook#

  • Template linked to a Campaign → Content column shows campaign's internal_name
  • Template linked to a Campaign Group → Content column shows campaign group's internal_name
  • Template linked to deleted/non-existent content → shows "-"
  • Content name resolution works in:
    • Templates list page (Content column)
    • Template mobile card (Content name)
    • Template detail page (Content combobox selected value)

5.2 Content Availability#

  • Only PUBLISHED campaigns appear in content combobox
  • Only PUBLISHED campaign groups appear in content combobox
  • DRAFT campaigns do NOT appear
  • ARCHIVED campaigns do NOT appear
  • DRAFT campaign groups do NOT appear
  • ARCHIVED campaign groups do NOT appear
  • If a campaign is unpublished after being assigned:
    • Template still references it (content_id unchanged)
    • Content name may show as "-" or the original name
    • Fallback content should display on devices

6. Template-Device Relationship#

6.1 Assigning Templates to Devices#

  • Go to a device's detail page
  • Change the Template dropdown to a different template → Save
  • Verify: Device now appears in new template's linked devices
  • Verify: Device removed from previous template's linked devices
  • Verify: Devices list shows new template chip for this device

6.2 Template Configuration Inheritance#

  • Change template's content → all linked devices now serve new content
  • Change template's checkout mode → all linked devices use new checkout flow
  • Change template's max donation → all linked devices enforce new limit
  • Change template's fallback content → all linked devices use new fallback
  • Verify: No per-device override needed — template changes propagate automatically

6.3 Template Chip Display#

  • Device assigned to template → DeviceTemplateChip shows template name + icon
  • Template name change → chip updates across devices list
  • Template not found → chip shows "-"

7. Cross-Cutting Concerns#

7.1 Save Behavior#

  • Both cards (Main Details + Fallback Content) have independent save buttons
  • Each save button disabled until its own card has changes
  • Each save button disabled if its own card has validation errors
  • Saving shows loading state (spinner/disabled)
  • Success toast appears after save
  • Error toast appears on failure
  • Form data not lost on error

7.2 Loading States#

  • Templates list shows loading state while fetching
  • Template detail page shows loading state while fetching
  • Content combobox shows loading spinner while campaigns/groups load
  • Linked devices card shows loading state

7.3 Error Handling#

  • Network error during save → error toast
  • Network error during load → error state with retry
  • Server validation error → displayed to user

7.4 URL State Persistence#

  • Templates list: filters, sort, pagination, search persist in URL params
  • Copy/paste URL with params → same view loads
  • Browser back/forward navigates between filter states

7.5 Data Consistency#

  • Create template → appears in templates list immediately
  • Edit template name → list reflects new name
  • Edit template content → list content column updates
  • Edit template checkout mode → list checkout mode column updates
  • Delete template → disappears from list
  • Device assigned to template → linked devices count increments
  • Device unassigned from template → linked devices count decrements

7.6 Mobile Responsiveness#

  • List page renders as cards on mobile
  • Detail page stacks cards vertically on mobile
  • Combobox dropdown works on mobile
  • Modal displays correctly on mobile

8. End-to-End Flows#

8.1 Create Template and Assign to Device#

  1. Click "Add Template" → modal opens
  2. Enter template name (e.g., "Lobby Express Checkout")
  3. Select a published campaign as content
  4. Set checkout mode to "Express"
  5. Submit → redirected to new template detail page
  6. Set maximum donation amount (e.g., $5,000) → Save
  7. Set fallback content (title: "Welcome", message: "Please try again shortly") → Save
  8. Go to a device's detail page → change template to "Lobby Express Checkout" → Save
  9. Go back to template detail page
  10. Verify: Device appears in linked devices card
  11. Verify: Device count is 1
  12. Go to devices list → verify device shows "Lobby Express Checkout" template chip

8.2 Change Template Content Source#

  1. Open a template detail page
  2. Note the current content (e.g., Campaign A)
  3. Change content to a Campaign Group
  4. Save → verify success
  5. Verify: Content column in templates list shows campaign group name
  6. Verify: Linked devices now serve campaign group content (check on device if possible)

8.3 Fallback Content Verification#

  1. Create a template linked to a published campaign
  2. Set fallback content (title + message)
  3. Unpublish/archive the campaign
  4. Verify: Devices using this template should show fallback content
  5. Re-publish the campaign
  6. Verify: Devices go back to showing campaign content

8.4 Template Deletion Flow#

  1. Create a template with no devices assigned
  2. Delete via detail page → verify clean deletion
  3. Create another template and assign 1 device to it
  4. Try to delete → verify warning about ensuring no devices use it
  5. Reassign the device to a different template
  6. Delete the now-empty template → verify clean deletion

8.5 Content Combobox Behavior#

  1. Create a template → open content combobox
  2. Verify: Campaign Groups section appears first (if any exist)
  3. Verify: Campaigns section appears below
  4. Verify: Only PUBLISHED campaigns/groups shown
  5. Create a new draft campaign → verify it does NOT appear in combobox
  6. Publish the campaign → refresh → verify it now appears in combobox
  7. Archive a campaign that was available → refresh → verify it disappears from combobox

8.6 Maximum Donation Amount Currency Handling#

  1. Open a template with USD currency
  2. Set max donation to $500 → Save
  3. Verify: Display shows "$500" (with currency symbol)
  4. Verify: Stored value is 50000 (in cents — check via API or refresh)
  5. Set max donation to $100,000 → Save → verify it accepts
  6. Set max donation to $100,001 → verify validation error
  7. Set max donation to $0 → verify validation error

8.7 Edge Cases#

  1. Template name at max length (40 chars) → saves and displays correctly
  2. Template with no fallback content → saves correctly (both fields empty)
  3. Multiple templates linked to the same campaign → both work independently
  4. Delete a campaign that's linked to a template → template still exists, content shows "-"
  5. Template with 0 devices → all operations work normally

Verification Checklist#

AreaTotal TestsPassFailNotes
Templates List Page~25
Template Creation~18
Template Detail (Main)~30
Template Detail (Fallback)~12
Template Deletion~8
Content Resolution~12
Template-Device Relationship~10
Cross-Cutting~15
E2E Flows~30
TOTAL~160