fix: resolve codacy high severity findings

This commit is contained in:
lucaronin
2026-05-07 18:31:20 +02:00
parent b9ce903991
commit f5866a2376
11 changed files with 171 additions and 104 deletions

View File

@@ -28,7 +28,7 @@ jobs:
fetch-depth: 0 # Full history for CodeScene
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -65,7 +65,7 @@ jobs:
- name: Upload frontend coverage to Codecov
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
with:
use_oidc: true
fail_ci_if_error: true
@@ -143,7 +143,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
components: rustfmt, clippy, llvm-tools-preview
@@ -159,7 +159,7 @@ jobs:
${{ runner.os }}-cargo-${{ env.RUST_TARGET_CACHE_VERSION }}-
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
uses: taiki-e/install-action@e5de28abeb52d916c5e5875d54b21a9e738b61ec
- name: Rust tests + coverage (≥85% lines)
run: |
@@ -175,7 +175,7 @@ jobs:
- name: Upload Rust coverage to Codecov
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe
with:
use_oidc: true
fail_ci_if_error: true
@@ -213,7 +213,7 @@ jobs:
file
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -224,7 +224,7 @@ jobs:
cache: 'pnpm'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
components: clippy

View File

@@ -33,7 +33,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -44,7 +44,7 @@ jobs:
cache: pnpm
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest

View File

@@ -82,7 +82,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -93,12 +93,12 @@ jobs:
cache: 'pnpm'
- name: Setup Bun (required for bundle-qmd.sh)
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: ${{ matrix.target }}
@@ -292,7 +292,7 @@ jobs:
rpm
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -303,7 +303,7 @@ jobs:
cache: 'pnpm'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: x86_64-unknown-linux-gnu
@@ -389,7 +389,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -400,7 +400,7 @@ jobs:
cache: 'pnpm'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: x86_64-pc-windows-msvc
@@ -682,7 +682,7 @@ jobs:
echo "stable-latest.json:"; cat stable-latest.json
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
with:
tag_name: ${{ needs.version.outputs.tag }}
name: Tolaria ${{ needs.version.outputs.display_version }}
@@ -740,7 +740,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -751,7 +751,7 @@ jobs:
cache: 'pnpm'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest
@@ -780,7 +780,7 @@ jobs:
cp _site/alpha/latest.json _site/latest-canary.json
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
uses: peaceiris/actions-gh-pages@e9c66a37f080288a11235e32cbe2dc5fb3a679cc
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./_site

View File

@@ -143,7 +143,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -154,12 +154,12 @@ jobs:
cache: 'pnpm'
- name: Setup Bun (required for bundle-qmd.sh)
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: ${{ matrix.target }}
@@ -348,7 +348,7 @@ jobs:
rpm
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -359,7 +359,7 @@ jobs:
cache: 'pnpm'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: x86_64-unknown-linux-gnu
@@ -445,7 +445,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -456,7 +456,7 @@ jobs:
cache: 'pnpm'
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8
with:
targets: x86_64-pc-windows-msvc
@@ -730,7 +730,7 @@ jobs:
echo "alpha-latest.json:"; cat alpha-latest.json
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65
with:
tag_name: ${{ needs.version.outputs.tag }}
name: Tolaria ${{ needs.version.outputs.display_version }}
@@ -786,7 +786,7 @@ jobs:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa
with:
version: 10
@@ -797,7 +797,7 @@ jobs:
cache: 'pnpm'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: latest
@@ -826,7 +826,7 @@ jobs:
cp _site/alpha/latest.json _site/latest-canary.json
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
uses: peaceiris/actions-gh-pages@e9c66a37f080288a11235e32cbe2dc5fb3a679cc
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./_site

10
.semgrepignore Normal file
View File

@@ -0,0 +1,10 @@
tests/
e2e/
node_modules/
dist/
coverage/
test-results/
src-tauri/target/
target/
src-tauri/gen/apple/assets/mcp-server/index.js
src-tauri/gen/apple/assets/mcp-server/ws-bridge.js

23
src-tauri/Cargo.lock generated
View File

@@ -1079,7 +1079,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -2908,15 +2908,14 @@ dependencies = [
[[package]]
name = "openssl"
version = "0.10.78"
version = "0.10.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222"
checksum = "bf0b434746ee2832f4f0baf10137e1cabb18cbe6912c69e2e33263c45250f542"
dependencies = [
"bitflags 2.11.0",
"cfg-if",
"foreign-types 0.3.2",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
@@ -2940,9 +2939,9 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "openssl-sys"
version = "0.9.114"
version = "0.9.115"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6"
checksum = "158fe5b292746440aa6e7a7e690e55aeb72d41505e2804c23c6973ad0e9c9781"
dependencies = [
"cc",
"libc",
@@ -3454,7 +3453,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -3888,7 +3887,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -3945,7 +3944,7 @@ dependencies = [
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -3956,9 +3955,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.103.12"
version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06"
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"ring",
"rustls-pki-types",
@@ -5109,7 +5108,7 @@ dependencies = [
"getrandom 0.4.1",
"once_cell",
"rustix",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]

View File

@@ -641,6 +641,22 @@ mod tests {
use std::ffi::OsString;
use std::process::Command;
#[cfg(target_os = "linux")]
fn current_test_binary() -> PathBuf {
std::fs::read_link("/proc/self/exe").unwrap()
}
#[cfg(target_os = "macos")]
fn current_test_binary() -> PathBuf {
let pid = std::process::id().to_string();
let output = Command::new("/bin/ps")
.args(["-p", pid.as_str(), "-o", "comm="])
.output()
.unwrap();
let path = String::from_utf8(output.stdout).unwrap();
PathBuf::from(path.trim())
}
macro_rules! chat_request {
($message:expr, None, None $(,)?) => {
ChatStreamRequest {
@@ -1185,7 +1201,7 @@ mod tests {
use std::io::Read;
use std::time::{Duration, Instant};
let mut child = Command::new(std::env::current_exe().unwrap())
let mut child = Command::new(current_test_binary())
.arg("stdin_probe_parent_child")
.arg("--ignored")
.arg("--nocapture")
@@ -1231,7 +1247,7 @@ mod tests {
return;
}
let fake_bin = std::env::current_exe().unwrap();
let fake_bin = current_test_binary();
let args = vec![
"stdin_probe_mock_claude_child".to_string(),
"--ignored".to_string(),

View File

@@ -469,6 +469,22 @@ mod tests {
use crate::ai_agents::AiAgentPermissionMode;
use std::ffi::OsStr;
#[cfg(target_os = "linux")]
fn current_test_binary() -> PathBuf {
std::fs::read_link("/proc/self/exe").unwrap()
}
#[cfg(target_os = "macos")]
fn current_test_binary() -> PathBuf {
let pid = std::process::id().to_string();
let output = std::process::Command::new("/bin/ps")
.args(["-p", pid.as_str(), "-o", "comm="])
.output()
.unwrap();
let path = String::from_utf8(output.stdout).unwrap();
PathBuf::from(path.trim())
}
#[cfg(unix)]
fn executable_script(dir: &Path, name: &str, body: &str) -> PathBuf {
use std::os::unix::fs::PermissionsExt;
@@ -798,7 +814,7 @@ exit 2
use std::io::Read;
use std::time::{Duration, Instant};
let mut child = std::process::Command::new(std::env::current_exe().unwrap())
let mut child = std::process::Command::new(current_test_binary())
.arg("codex_stdin_probe_parent_child")
.arg("--ignored")
.arg("--nocapture")

View File

@@ -309,6 +309,32 @@ fn colrv1_fontconfig_file_path() -> Option<std::path::PathBuf> {
)
}
#[cfg(all(desktop, target_os = "linux"))]
fn launched_appimage_path() -> Result<std::path::PathBuf, String> {
if let Some(appimage) = std::env::var_os("APPIMAGE").filter(|value| !value.is_empty()) {
return Ok(std::path::PathBuf::from(appimage));
}
std::fs::read_link("/proc/self/exe")
.map_err(|e| format!("failed to resolve /proc/self/exe ({e})"))
}
#[cfg(all(desktop, target_os = "linux"))]
fn launched_process_args() -> Vec<std::ffi::OsString> {
use std::os::unix::ffi::OsStringExt;
let Ok(cmdline) = std::fs::read("/proc/self/cmdline") else {
return Vec::new();
};
cmdline
.split(|byte| *byte == 0)
.filter(|arg| !arg.is_empty())
.skip(1)
.map(|arg| std::ffi::OsString::from_vec(arg.to_vec()))
.collect()
}
#[cfg(all(desktop, target_os = "linux"))]
fn apply_wayland_client_preload() {
use std::os::unix::process::CommandExt;
@@ -320,18 +346,16 @@ fn apply_wayland_client_preload() {
return;
};
let exe = match std::env::current_exe() {
let exe = match launched_appimage_path() {
Ok(exe) => exe,
Err(e) => {
eprintln!(
"Tolaria AppImage Wayland preload skipped: failed to resolve executable ({e})"
);
eprintln!("Tolaria AppImage Wayland preload skipped: {e}");
return;
}
};
let error = std::process::Command::new(exe)
.args(std::env::args_os().skip(1))
.args(launched_process_args())
.env("LD_PRELOAD", preload_path)
.env("TOLARIA_APPIMAGE_WAYLAND_PRELOAD_ATTEMPTED", "1")
.exec();

View File

@@ -224,14 +224,13 @@ fn node_binary_name() -> &'static str {
/// Resolve the path to `mcp-server/`.
///
/// In dev mode, uses `CARGO_MANIFEST_DIR` (set at compile time).
/// In release mode, navigates from the current executable.
/// In release mode, uses platform resource roots exposed by the launcher.
pub(crate) fn mcp_server_dir() -> Result<PathBuf, String> {
let dev_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("..")
.join("mcp-server");
let exe = std::env::current_exe().map_err(|e| format!("Cannot find executable: {e}"))?;
let appdir = std::env::var_os("APPDIR").map(PathBuf::from);
let candidates = mcp_server_dir_candidates(&dev_path, &exe, appdir.as_deref());
let resource_roots = runtime_resource_roots();
let candidates = mcp_server_dir_candidates(&dev_path, &resource_roots);
if let Some(path) = candidates
.iter()
.find(|path| mcp_server_dir_has_files(path))
@@ -249,29 +248,13 @@ pub(crate) fn mcp_server_dir() -> Result<PathBuf, String> {
))
}
fn mcp_server_dir_candidates(
dev_path: &Path,
exe_path: &Path,
appdir: Option<&Path>,
) -> Vec<PathBuf> {
fn mcp_server_dir_candidates(dev_path: &Path, resource_roots: &[PathBuf]) -> Vec<PathBuf> {
let mut candidates = vec![dev_path.to_path_buf()];
if let Some(exe_dir) = exe_path.parent() {
candidates.push(exe_dir.join("mcp-server"));
if let Some(bundle_root) = exe_dir.parent() {
candidates.push(bundle_root.join("Resources").join("mcp-server"));
candidates.extend(linux_package_mcp_server_dirs(bundle_root));
}
}
if let Some(appdir) = appdir {
candidates.push(
appdir
.join("usr")
.join("lib")
.join("tolaria")
.join("mcp-server"),
);
for root in resource_roots {
candidates.push(root.join("mcp-server"));
candidates.push(root.join("resources").join("mcp-server"));
candidates.extend(linux_package_mcp_server_dirs(root));
}
candidates.extend(linux_package_mcp_server_dirs(Path::new("/usr/local")));
@@ -279,6 +262,28 @@ fn mcp_server_dir_candidates(
candidates
}
fn runtime_resource_roots() -> Vec<PathBuf> {
let mut roots = Vec::new();
if let Some(resource_path) = non_empty_env_path("RESOURCEPATH") {
roots.push(resource_path);
}
if let Some(appdir) = non_empty_env_path("APPDIR") {
roots.push(appdir.join("usr"));
roots.push(appdir.join("usr").join("lib").join("tolaria"));
roots.push(appdir.join("usr").join("lib").join("Tolaria"));
}
roots
}
fn non_empty_env_path(key: &str) -> Option<PathBuf> {
std::env::var_os(key)
.filter(|value| !value.is_empty())
.map(PathBuf::from)
}
fn linux_package_mcp_server_dirs(root: &Path) -> Vec<PathBuf> {
vec![
root.join("Tolaria").join("mcp-server"),
@@ -739,32 +744,36 @@ mod tests {
}
#[test]
fn mcp_server_dir_candidates_prefer_exe_dir_before_macos_resources() {
fn mcp_server_dir_candidates_prefer_resource_root_before_linux_packages() {
let dev_path = Path::new("/repo/mcp-server");
let exe_path = Path::new("/Users/tester/AppData/Local/Tolaria/tolaria.exe");
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
let resource_roots = vec![PathBuf::from(
"/Applications/Tolaria.app/Contents/Resources",
)];
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
let windows_dir = PathBuf::from("/Users/tester/AppData/Local/Tolaria/mcp-server");
let macos_dir = PathBuf::from("/Users/tester/AppData/Local/Resources/mcp-server");
let windows_pos = candidates
let resource_dir = PathBuf::from("/Applications/Tolaria.app/Contents/Resources/mcp-server");
let linux_pos = candidates
.iter()
.position(|path| path == &windows_dir)
.unwrap();
let macos_pos = candidates
.iter()
.position(|path| path == &macos_dir)
.position(|path| path == &PathBuf::from("/usr/local/Tolaria/mcp-server"))
.unwrap();
assert_eq!(candidates[0], dev_path);
assert!(windows_pos < macos_pos);
assert_eq!(candidates[1], resource_dir);
assert!(1 < linux_pos);
}
#[test]
fn mcp_server_dir_candidates_include_linux_package_resource_roots() {
let dev_path = Path::new("/repo/mcp-server");
let exe_path = Path::new("/usr/local/tolaria/tolaria");
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
let resource_roots = vec![PathBuf::from("/opt/tolaria")];
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
let expected = [
PathBuf::from("/opt/tolaria/Tolaria/mcp-server"),
PathBuf::from("/opt/tolaria/Tolaria/resources/mcp-server"),
PathBuf::from("/opt/tolaria/lib/Tolaria/mcp-server"),
PathBuf::from("/opt/tolaria/lib/Tolaria/resources/mcp-server"),
PathBuf::from("/opt/tolaria/lib/tolaria/mcp-server"),
PathBuf::from("/opt/tolaria/lib/tolaria/resources/mcp-server"),
PathBuf::from("/usr/local/Tolaria/mcp-server"),
PathBuf::from("/usr/local/Tolaria/resources/mcp-server"),
PathBuf::from("/usr/local/lib/Tolaria/mcp-server"),
@@ -783,8 +792,7 @@ mod tests {
#[test]
fn mcp_server_dir_candidates_include_deb_capitalized_lib_root() {
let dev_path = Path::new("/repo/mcp-server");
let exe_path = Path::new("/usr/bin/tolaria");
let candidates = mcp_server_dir_candidates(dev_path, exe_path, None);
let candidates = mcp_server_dir_candidates(dev_path, &[]);
assert!(candidates.contains(&PathBuf::from("/usr/lib/Tolaria/mcp-server")));
}
@@ -792,9 +800,8 @@ mod tests {
#[test]
fn mcp_server_dir_candidates_include_linux_appimage_resource_root() {
let dev_path = Path::new("/repo/mcp-server");
let exe_path = Path::new("/tmp/.mount_tolaria/usr/bin/tolaria");
let appdir = Path::new("/tmp/.mount_tolaria");
let candidates = mcp_server_dir_candidates(dev_path, exe_path, Some(appdir));
let resource_roots = vec![PathBuf::from("/tmp/.mount_tolaria/usr")];
let candidates = mcp_server_dir_candidates(dev_path, &resource_roots);
assert!(candidates.contains(&PathBuf::from(
"/tmp/.mount_tolaria/usr/lib/tolaria/resources/mcp-server"

View File

@@ -41,7 +41,8 @@ function renderWithPrioritySort(entries: VaultEntry[]) {
}
function expectVisibleNoteOrder(expectedTitles: string[]) {
const items = screen.getAllByText(new RegExp(expectedTitles.join('|')))
const expectedTitleSet = new Set(expectedTitles)
const items = screen.getAllByText((content) => expectedTitleSet.has(content))
expect(items.map((item) => item.textContent)).toEqual(expectedTitles)
}
@@ -75,10 +76,7 @@ describe('useNoteListSort (via NoteList)', () => {
makeEntry({ path: '/c.md', title: 'Charlie', modifiedAt: 2000 }),
]
renderNoteList({ entries, selection: { kind: 'filter', filter: 'all' } })
const items = screen.getAllByText(/Alpha|Beta|Charlie/)
expect(items[0].textContent).toBe('Beta')
expect(items[1].textContent).toBe('Charlie')
expect(items[2].textContent).toBe('Alpha')
expectVisibleNoteOrder(['Beta', 'Charlie', 'Alpha'])
})
it('reads sort from type document for sectionGroup selection', () => {
@@ -90,10 +88,7 @@ describe('useNoteListSort (via NoteList)', () => {
makeEntry({ path: '/b.md', title: 'Beta', modifiedAt: 2000 }),
]
renderNoteList({ entries, selection: { kind: 'sectionGroup', type: 'Note', label: 'Notes' } })
const items = screen.getAllByText(/Alpha|Beta|Charlie/)
expect(items[0].textContent).toBe('Alpha')
expect(items[1].textContent).toBe('Beta')
expect(items[2].textContent).toBe('Charlie')
expectVisibleNoteOrder(['Alpha', 'Beta', 'Charlie'])
})
it('shows type title as header for sectionGroup selection', () => {