fix(#411): complete 2026-02-17 remediation sweep
Apply RLS context at task service boundaries, harden orchestrator/web integration and session startup behavior, re-enable targeted frontend tests, and lock vulnerable transitive dependencies so QA and security gates pass cleanly.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
||||
import React from "react";
|
||||
import { render, screen, waitFor, fireEvent, act } from "@testing-library/react";
|
||||
@@ -352,10 +351,7 @@ describe("LinkAutocomplete", (): void => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should perform debounced search when typing query", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should perform debounced search when typing query", async (): Promise<void> => {
|
||||
const mockResults = {
|
||||
data: [
|
||||
{
|
||||
@@ -395,11 +391,6 @@ describe("LinkAutocomplete", (): void => {
|
||||
// Should not call API immediately
|
||||
expect(mockApiRequest).not.toHaveBeenCalled();
|
||||
|
||||
// Fast-forward 300ms and let promises resolve
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockApiRequest).toHaveBeenCalledWith(
|
||||
"/api/knowledge/search?q=test&limit=10",
|
||||
@@ -411,14 +402,9 @@ describe("LinkAutocomplete", (): void => {
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Test Entry")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should navigate results with arrow keys", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should navigate results with arrow keys", async (): Promise<void> => {
|
||||
const mockResults = {
|
||||
data: [
|
||||
{
|
||||
@@ -471,10 +457,6 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Entry One")).toBeInTheDocument();
|
||||
});
|
||||
@@ -500,14 +482,9 @@ describe("LinkAutocomplete", (): void => {
|
||||
const firstItem = screen.getByText("Entry One").closest("li");
|
||||
expect(firstItem).toHaveClass("bg-blue-50");
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should insert link on Enter key", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should insert link on Enter key", async (): Promise<void> => {
|
||||
const mockResults = {
|
||||
data: [
|
||||
{
|
||||
@@ -544,10 +521,6 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Test Entry")).toBeInTheDocument();
|
||||
});
|
||||
@@ -558,14 +531,9 @@ describe("LinkAutocomplete", (): void => {
|
||||
await waitFor(() => {
|
||||
expect(onInsertMock).toHaveBeenCalledWith("[[test-entry|Test Entry]]");
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should insert link on click", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should insert link on click", async (): Promise<void> => {
|
||||
const mockResults = {
|
||||
data: [
|
||||
{
|
||||
@@ -602,10 +570,6 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Test Entry")).toBeInTheDocument();
|
||||
});
|
||||
@@ -616,14 +580,9 @@ describe("LinkAutocomplete", (): void => {
|
||||
await waitFor(() => {
|
||||
expect(onInsertMock).toHaveBeenCalledWith("[[test-entry|Test Entry]]");
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should close dropdown on Escape key", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should close dropdown on Escape key", async (): Promise<void> => {
|
||||
render(<LinkAutocomplete textareaRef={textareaRef} onInsert={onInsertMock} />);
|
||||
|
||||
const textarea = textareaRef.current;
|
||||
@@ -636,28 +595,19 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/Start typing to search/)).toBeInTheDocument();
|
||||
expect(screen.getByText("↑↓ Navigate • Enter Select • Esc Cancel")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Press Escape
|
||||
fireEvent.keyDown(textarea, { key: "Escape" });
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/Start typing to search/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("↑↓ Navigate • Enter Select • Esc Cancel")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should close dropdown when closing brackets are typed", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should close dropdown when closing brackets are typed", async (): Promise<void> => {
|
||||
render(<LinkAutocomplete textareaRef={textareaRef} onInsert={onInsertMock} />);
|
||||
|
||||
const textarea = textareaRef.current;
|
||||
@@ -670,12 +620,8 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/Start typing to search/)).toBeInTheDocument();
|
||||
expect(screen.getByText("↑↓ Navigate • Enter Select • Esc Cancel")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Type closing brackets
|
||||
@@ -686,16 +632,11 @@ describe("LinkAutocomplete", (): void => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText(/Start typing to search/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("↑↓ Navigate • Enter Select • Esc Cancel")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should show 'No entries found' when search returns no results", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should show 'No entries found' when search returns no results", async (): Promise<void> => {
|
||||
mockApiRequest.mockResolvedValue({
|
||||
data: [],
|
||||
meta: { total: 0, page: 1, limit: 10, totalPages: 0 },
|
||||
@@ -713,32 +654,24 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("No entries found")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should show loading state while searching", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should show loading state while searching", async (): Promise<void> => {
|
||||
// Mock a slow API response
|
||||
let resolveSearch: (value: unknown) => void;
|
||||
const searchPromise = new Promise((resolve) => {
|
||||
let resolveSearch: (value: {
|
||||
data: unknown[];
|
||||
meta: { total: number; page: number; limit: number; totalPages: number };
|
||||
}) => void = () => undefined;
|
||||
const searchPromise = new Promise<{
|
||||
data: unknown[];
|
||||
meta: { total: number; page: number; limit: number; totalPages: number };
|
||||
}>((resolve) => {
|
||||
resolveSearch = resolve;
|
||||
});
|
||||
mockApiRequest.mockReturnValue(
|
||||
searchPromise as Promise<{
|
||||
data: unknown[];
|
||||
meta: { total: number; page: number; limit: number; totalPages: number };
|
||||
}>
|
||||
);
|
||||
mockApiRequest.mockReturnValue(searchPromise);
|
||||
|
||||
render(<LinkAutocomplete textareaRef={textareaRef} onInsert={onInsertMock} />);
|
||||
|
||||
@@ -752,16 +685,12 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("Searching...")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
// Resolve the search
|
||||
resolveSearch!({
|
||||
resolveSearch({
|
||||
data: [],
|
||||
meta: { total: 0, page: 1, limit: 10, totalPages: 0 },
|
||||
});
|
||||
@@ -769,14 +698,9 @@ describe("LinkAutocomplete", (): void => {
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText("Searching...")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
// TODO: Fix async/timer interaction - component works but test has timing issues with fake timers
|
||||
it.skip("should display summary preview for entries", async (): Promise<void> => {
|
||||
vi.useFakeTimers();
|
||||
|
||||
it("should display summary preview for entries", async (): Promise<void> => {
|
||||
const mockResults = {
|
||||
data: [
|
||||
{
|
||||
@@ -813,14 +737,8 @@ describe("LinkAutocomplete", (): void => {
|
||||
fireEvent.input(textarea);
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
await vi.runAllTimersAsync();
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("This is a helpful summary")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user