# add-cockpit-card — Tests

Eight tests covering skill activation, the three card types, the most commonly missed step,
role visibility, on-tap wiring, and the MFG audit invariant.

---

## Test 1: Skill Activation

**Goal:** Verify the skill triggers on all expected user-intent phrases.

**Input phrases (each should activate `add-cockpit-card` — NOT a foundation skill):**

-   "add a card showing today's open visits"
-   "put a task count tile on the home screen"
-   "cockpit card for overdue customers"
-   "home screen card showing upcoming orders"
-   "show visit count on the cockpit"
-   "add a cockpit card for tours"

**Anti-activation phrases (should NOT activate this skill):**

-   "add a list screen for visits" → `add-list-screen`
-   "add a detail page for a visit" → `add-detail-screen`
-   "create a datasource" → `create-datasource`
-   "KPI chart on the cockpit" → block and inform user about `create-ui-plugin`

**Pass criteria:** Skill description's trigger phrases cover all intent forms above.

---

## Test 2: List Card — Full End-to-End Flow

**Scenario:** User asks "add a cockpit list card showing today's open visits for RetailUser".

**Pre-conditions:** SQLite schema has `Visit` table with `Id`, `Name`, `PlannedVisitStartTime`, `Status`, `AccountId`.

**Expected execution trace:**

1. Input prompt: collect all 7 answers (card title, type=list, entity=Visit, module=Visit, naming=VisitsToday, role=RetailUser, on-tap=open Visit detail)
2. `verify-sqlite-schema` invoked → Visit.Id, Visit.Name, Visit.PlannedVisitStartTime, Visit.Status, Visit.AccountId → all OK
3. `create-datasource` invoked with naming `DsLoVisitsToday`, mode declarative, LIMIT `:maxListItems`, WHERE `PlannedVisitStartTime` = today
4. `create-list-object` invoked with LO=`LoVisitsToday`, LI=`LiVisitsToday`, methods `getTasksForCard` + `getInfoForCard`
5. `create-business-logic` invoked twice: `getTasksForCard` and `getInfoForCard`
6. `BoSalesCockpitHelper` updated: `collapseState_CardVisitsToday` property added; `IsCardVisible` case added; `IsCardCollapsible` case added
7. `Application_CockpitProcess.processflow.xml` updated with snippet (declarations + EntryAction + events + 3-step action chain)
8. `Application_CockpitUI.userinterface.xml` updated with NavigationMenuItem + `<CardContainer name="CardVisitsToday">`
9. `build-and-simulate` invoked → build passes, card appears for RetailUser role

**Pass criteria:**

-   All 9 steps executed in order
-   `create-datasource`, `create-list-object`, `create-business-logic`, `verify-sqlite-schema`, `build-and-simulate` all invoked
-   Checklist items for Step 5 (helper registration) explicitly confirmed

---

## Test 3: Tile Card — Single Count

**Scenario:** User asks "show a count of open customer issues on the cockpit home screen".

**Expected behavior:**

-   Card type resolves to: **tile** (user says "count")
-   `create-list-object` produces `LoIssuesCount` with `getTasksForCard` returning 0 rows; value lives in `getInfoForCard` return string
-   `getInfoForCard` BL returns `"5"` (total open issues) or `"5 / 12"` (open / total)
-   `<CockpitList>` may be omitted — the tile only shows the `Information` binding text
-   All other steps identical to Test 2

**Pass criteria:**

-   Skill correctly identifies tile variant from user intent
-   Execution sequence comment notes LO may have 0 rows; info text carries the count
-   `BoSalesCockpitHelper` update still required (Step 5 not skipped)

---

## Test 4: Action Card — Button Cluster, No Data

**Scenario:** User asks "add quick action buttons on the cockpit to start a new visit or open the order list".

**Expected behavior:**

-   Card type resolves to: **action**
-   Steps 1–4 are explicitly skipped (no SQLite check, no DS, no LO, no BL)
-   Step 5: `BoSalesCockpitHelper` still updated (collapseState property, visibility/collapsible cases) — action cards still need to be registered
-   Step 6: Process snippet uses simplified declarations (no `_List`, no `_InformationText`); `_DataLoaded` may be set to `1` directly in EntryActions
-   Step 7: CardContainer uses `<NavigationMenuContainer>` children instead of `<CockpitList>`
-   Step 8: Build + verify

**Pass criteria:**

-   Skill clearly documents skipping Steps 1–4 for action cards
-   BoSalesCockpitHelper registration (Step 5) is NOT skipped
-   Build passes with no LO references in the CardContainer

---

## Test 5: Missing Helper Catch (Step 5 Skipped)

**Scenario:** A developer ships a card following Steps 1–4 and 6–8 but omits Step 5. The card does not appear in the simulator.

**Failure mode triggered:** Fm1 — Card completely invisible on cockpit.

**Expected diagnosis path per SKILL.md:**

1. Build passes with no errors (the missing case in `IsCardVisible.bl.js` is not a build error)
2. Simulator loads cockpit without console errors
3. Card is absent from the cockpit view
4. Developer follows Fm1 guidance: opens `BoSalesCockpitHelper.IsCardVisible.bl.js`, finds no `case "Card<Name>"` in switch
5. Adds the case, runs `sf mdl build` again
6. Card now appears

**Pass criteria:**

-   SKILL.md Fm1 section clearly identifies the symptom (invisible, no error) and root cause
-   Step 5 is labeled "MOST OFTEN MISSED" in the execution sequence
-   Checklist items for `IsCardVisible` and `IsCardCollapsible` are bold/flagged

---

## Test 6: Role Visibility — Card Hidden for Non-Authorized Roles

**Scenario:** Card should only appear for `TourUser` role. `RetailUser` logs in and should not see it.

**Expected behavior:**

-   `IsCardVisible.bl.js` case uses `ApplicationContext.get('user').hasRole('TourUser')` guard:
    ```javascript
    case "CardTourSummary":
      if (ApplicationContext.get('user').hasRole('TourUser')) { visible = true; }
      break;
    ```
-   `<CardContainer>` in UI has:
    ```xml
    <VisibilityRoles allRoles="false">
      <Role name="TourUser" />
    </VisibilityRoles>
    ```
-   Both mechanisms agree — `allRoles="true"` in UI but BL-gated would show empty card instead of hiding it

**Pass criteria:**

-   SKILL.md Input Prompt item 6 collects role visibility requirement
-   Step 5 guidance includes role-check code snippet
-   Step 7 CardContainer template includes `<VisibilityRoles>` with placeholder
-   Fm5 documents the mismatch risk

---

## Test 7: On-Tap Wiring — Row Tap Navigates to Detail

**Scenario:** User taps a row in the list card and expects it to open the Visit detail screen.

**Expected behavior:**

-   Input Prompt item 7 (on-tap action) is set to "navigate to Visit detail"
-   Process snippet PART C includes:
    ```xml
    <Event name="CardVisitsToday_itemSelected" action="CardVisitsToday_ShowDetail" />
    ```
-   Process `<Actions>` includes a `CardVisitsToday_ShowDetail` action that either:
    -   Invokes a NAVIGATION process action, OR
    -   Calls `add-detail-screen` skill separately (mentioned as escape hatch)
-   `CockpitList` in UI template includes item-tap event binding on `<Items>`

**Pass criteria:**

-   Fm4 (clicking does nothing) clearly identifies event-name mismatch as root cause
-   Step 7 CardContainer template notes the `_itemSelected` event needs to be added when on-tap is configured
-   Verify step 5 ("Tapping a card row navigates...") is in the Verify section

---

## Test 8: MFG Audit — No MFG References in Skill Files

**Scenario:** Automated audit run per plan Step 9.

**Command:**

```bash
grep -rni "mfg\|MfgVisit\|MfgQuality\|MfgAgreements" \
  .claude/skills/add-cockpit-card/ \
  --include="*.md" --include="*.snippet" \
  | grep -v "MFG check\|Forbidden\|no-MFG\|NO MFG" \
  || echo "NO MFG"
```

**Expected output:** `NO MFG`

**Pass criteria:**

-   Zero matches for `mfg`, `MfgVisit`, `MfgQuality`, `MfgAgreements` (case-insensitive) in any file
-   All examples in the skill use real modules: Visit, Tour, TourVisit, Call, Task, Order, Customer
