starling-devex 0.1.2

Starling: a local dev orchestrator with a central daemon, shared named-URL proxy, and a k9s-style TUI (a Rust port of Tilt + portless)
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import React, { ReactElement } from "react"
import { MemoryRouter } from "react-router"
import { accessorsForTesting, tiltfileKeyContext } from "./BrowserStorage"
import Features, { FeaturesTestProvider, Flag } from "./feature"
import {
  TenResourcesWithLabels,
  TestsWithErrors,
  TwoResourcesTwoTests,
} from "./OverviewResourceSidebar.stories"
import { OverviewSidebarOptionsRoot } from "./OverviewSidebarOptions"
import { ResourceGroupsContextProvider } from "./ResourceGroupsContext"
import {
  DEFAULT_OPTIONS,
  ResourceListOptions,
  ResourceListOptionsProvider,
  RESOURCE_LIST_OPTIONS_KEY,
} from "./ResourceListOptionsContext"
import { ResourceNameFilterTextField } from "./ResourceNameFilter"
import { SidebarItemNameRoot, SidebarItemRoot } from "./SidebarItemView"
import {
  SidebarListSectionItemsRoot,
  SidebarResourcesRoot,
} from "./SidebarResources"

const resourceListOptionsAccessor = accessorsForTesting<ResourceListOptions>(
  RESOURCE_LIST_OPTIONS_KEY,
  sessionStorage
)
/**
 * TODO (lizz): These tests behave more like integration tests
 * and test the SidebarOptions component within the larger `SidebarResources`
 * component. The tests should be moved over to that component's test suite
 * and refactored with the react-testing-library changes.
 */

function assertSidebarItemsAndOptions(
  root: HTMLElement,
  names: string[],
  expectAlertsOnTop: boolean,
  expectedResourceNameFilter?: string
) {
  let sidebar = Array.from(root.querySelectorAll(SidebarResourcesRoot))
  expect(sidebar).toHaveLength(1)

  // only check items in the "all resources" section, i.e. don't look at starred things
  // or we'll have duplicates
  let all = sidebar[0].querySelector(SidebarListSectionItemsRoot)!
  let items = Array.from(all.querySelectorAll(SidebarItemRoot))
  const observedNames = items.map(
    (i) => i.querySelector(SidebarItemNameRoot)?.textContent
  )
  expect(observedNames).toEqual(names)

  let optSetter = Array.from(
    sidebar[0].querySelectorAll(OverviewSidebarOptionsRoot)
  )
  expect(optSetter).toHaveLength(1)

  let checkbox = optSetter[0].querySelector(
    "input[type=checkbox]"
  ) as HTMLInputElement
  expect(checkbox.checked).toEqual(expectAlertsOnTop)
  if (expectedResourceNameFilter !== undefined) {
    expect(
      optSetter[0].querySelector(ResourceNameFilterTextField)!.textContent
    ).toEqual(expectedResourceNameFilter)
  }
}

beforeEach(() => {})

afterEach(() => {
  localStorage.clear()
  resourceListOptionsAccessor.set({
    ...DEFAULT_OPTIONS,
  })
})

function renderContainer(x: ReactElement) {
  const features = new Features({
    [Flag.Labels]: true,
  })
  const { container } = render(
    <MemoryRouter
      future={{ v7_startTransition: true, v7_relativeSplatPath: true }}
    >
      <FeaturesTestProvider value={features}>
        <tiltfileKeyContext.Provider value="test">
          <ResourceGroupsContextProvider>
            <ResourceListOptionsProvider>{x}</ResourceListOptionsProvider>
          </ResourceGroupsContextProvider>
        </tiltfileKeyContext.Provider>
      </FeaturesTestProvider>
    </MemoryRouter>
  )
  return container
}

describe("overview sidebar options", () => {
  it("says no matches found", () => {
    resourceListOptionsAccessor.set({
      ...DEFAULT_OPTIONS,
      resourceNameFilter: "asdfawfwef",
    })
    const container = renderContainer(<TwoResourcesTwoTests />)
    const resourceSectionItems = Array.from(
      container
        .querySelector(SidebarListSectionItemsRoot)!
        .querySelectorAll("li")
    )
    expect(resourceSectionItems.map((n) => n.textContent)).toEqual([
      "No matching resources",
    ])
  })
})

it("toggles/untoggles Alerts On Top sorting when button clicked", () => {
  const { container } = render(TestsWithErrors())

  const origOrder = [
    "(Tiltfile)",
    "test_0",
    "test_1",
    "test_2",
    "test_3",
    "test_4",
    "test_5",
    "test_6",
    "test_7",
  ]
  const alertsOnTopOrder = [
    "test_0",
    "test_2",
    "test_4",
    "test_6",
    "(Tiltfile)",
    "test_1",
    "test_3",
    "test_5",
    "test_7",
  ]
  assertSidebarItemsAndOptions(container, origOrder, false)

  let aotToggle = screen.getByLabelText("Alerts on top")
  userEvent.click(aotToggle)

  assertSidebarItemsAndOptions(container, alertsOnTopOrder, true)

  userEvent.click(aotToggle)
  assertSidebarItemsAndOptions(container, origOrder, false)
})