From 4d924e2f4847d0bca597e18d8efd037d7a46efc0 Mon Sep 17 00:00:00 2001 From: Dante Catalfamo <43040593+dantecatalfamo@users.noreply.github.com> Date: Tue, 21 Jul 2026 16:50:46 -0400 Subject: [PATCH] Show managed Android serial number on Hosts page (#49711) **Related issue:** Resolves #48379 --- changes/48379-android-serial-hosts-page | 1 + .../ManageHostsPage/HostTableConfig.tests.tsx | 72 +++++++++++++++++++ .../hosts/ManageHostsPage/HostTableConfig.tsx | 7 +- 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 changes/48379-android-serial-hosts-page create mode 100644 frontend/pages/hosts/ManageHostsPage/HostTableConfig.tests.tsx diff --git a/changes/48379-android-serial-hosts-page b/changes/48379-android-serial-hosts-page new file mode 100644 index 0000000000..6345bb2a38 --- /dev/null +++ b/changes/48379-android-serial-hosts-page @@ -0,0 +1 @@ +- Fixed the Hosts page so that managed Android hosts display their serial number instead of "Not supported" when one is reported. diff --git a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tests.tsx b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tests.tsx new file mode 100644 index 0000000000..e5f95ae77e --- /dev/null +++ b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tests.tsx @@ -0,0 +1,72 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; + +import { generateAvailableTableHeaders } from "./HostTableConfig"; + +describe("HostTableConfig - Serial number column", () => { + const headers = generateAvailableTableHeaders({ + isFreeTier: false, + isOnlyObserver: false, + }); + + const serialColumn = headers.find((h) => h.id === "hardware_serial") as any; + + if (!serialColumn || typeof serialColumn.Cell !== "function") { + throw new Error("hardware_serial column or Cell not found"); + } + + const Cell = serialColumn.Cell as React.ElementType; + + const renderCell = ( + serial: string, + platform: string, + mdm?: { enrollment_status: string } + ) => + render( + + ); + + it("shows the serial number for a macOS host", () => { + renderCell("ABC123", "darwin", { enrollment_status: "On (automatic)" }); + expect(screen.getByText("ABC123")).toBeInTheDocument(); + expect(screen.queryByText("Not supported")).not.toBeInTheDocument(); + }); + + it("shows the serial number for a managed Android host", () => { + renderCell("PIXEL10A", "android", { enrollment_status: "On (automatic)" }); + expect(screen.getByText("PIXEL10A")).toBeInTheDocument(); + expect(screen.queryByText("Not supported")).not.toBeInTheDocument(); + }); + + it("shows the serial number for an Android host with no mdm data", () => { + // Regression guard: the cell must not crash dereferencing a missing `mdm`. + renderCell("PIXEL10A", "android", undefined); + expect(screen.getByText("PIXEL10A")).toBeInTheDocument(); + expect(screen.queryByText("Not supported")).not.toBeInTheDocument(); + }); + + it("shows the serial number for a managed (ADE) iPadOS host", () => { + renderCell("IPAD123", "ipados", { enrollment_status: "On (automatic)" }); + expect(screen.getByText("IPAD123")).toBeInTheDocument(); + expect(screen.queryByText("Not supported")).not.toBeInTheDocument(); + }); + + it("shows 'Not supported' for a personal (BYOD) Android host", () => { + renderCell("", "android", { enrollment_status: "On (manual - personal)" }); + expect(screen.getByText("Not supported")).toBeInTheDocument(); + }); + + it("shows 'Not supported' for a personal (BYOD) iOS host", () => { + renderCell("", "ios", { enrollment_status: "On (manual - personal)" }); + expect(screen.getByText("Not supported")).toBeInTheDocument(); + }); +}); diff --git a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx index c3ead4ccdf..52d89eea6c 100644 --- a/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx +++ b/frontend/pages/hosts/ManageHostsPage/HostTableConfig.tsx @@ -247,11 +247,12 @@ const allHostTableHeaders = (teamId?: number): IHostTableColumnConfig[] => [ accessor: "hardware_serial", id: "hardware_serial", Cell: (cellProps: IHostTableStringCellProps) => { - // TODO(android): is iOS/iPadOS supported? + // Personal (BYOD) devices don't report their serial numbers, so show + // "Not supported" for them. All other hosts, including managed Android + // devices, show the reported serial number. if ( - isAndroid(cellProps.row.original.platform) || isBYODAccountDrivenUserEnrollment( - cellProps.row.original.mdm.enrollment_status + cellProps.row.original.mdm?.enrollment_status ?? null ) ) { return NotSupported;