Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/knowledgebase/gui-architecture-deferred.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Plans: `docs/plans/2026-06-03-012`, `021`–`029`, `033`–`057`. Surface refere
| Directory picker init/sync → `SettingsService` | Done | plan `075`, PR #123 |
| Mod context menu + global flyout → `MenuBuilderService` | Done | plan `072`, PR #130 |

**Headless tests:** `dotnet test src/ModSync.Tests/ModSync.Tests.csproj --filter SettingsService` (plan `077`); `--filter MenuBuilderService` (plan `072`); `--filter DialogServiceTests` / `FileSystemServiceTests` (plan `113`).
**Headless tests:** `dotnet test src/ModSync.Tests/ModSync.Tests.csproj --filter SettingsService` (plan `077`); `--filter MenuBuilderService` (plan `072`); `--filter FilterItemModel` (plan `112`).
**Headless tests:** `dotnet test src/ModSync.Tests/ModSync.Tests.csproj --filter SettingsService` (plan `077`); `--filter MenuBuilderService` (plan `072`); `--filter FileTreeNode` (plan `111`).
**Headless tests:** `dotnet test src/ModSync.Tests/ModSync.Tests.csproj --filter SettingsService` (plan `077`); `--filter MenuBuilderService` (plan `072`); `--filter ArchiveEnumerationService` (plan `110`).
Expand Down
19 changes: 19 additions & 0 deletions docs/plans/2026-06-04-113-test-dialog-filesystem-service-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: "test: DialogService and FileSystemService basics"
status: shipped
pr: pending
---

# test: DialogService and FileSystemService basics

## Problem

`DialogService` path-folder helper and `FileSystemService` watcher/dispose lifecycle had no dedicated tests.

## Solution

Add `DialogServiceTests` and `FileSystemServiceTests` for constructor validation, empty-path handling, and safe dispose/stop paths.

## Verification

`dotnet test src/ModSync.Tests/ModSync.Tests.csproj --filter "FullyQualifiedName~DialogServiceTests|FullyQualifiedName~FileSystemServiceTests"
32 changes: 32 additions & 0 deletions src/ModSync.Tests/DialogServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2021-2025 ModSync
// Licensed under the Business Source License 1.1 (BSL 1.1).
// See LICENSE.txt file in the project root for full license information.

using System;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Headless.XUnit;
using ModSync.Services;
using Xunit;

namespace ModSync.Tests
{
[Collection(HeadlessTestApp.CollectionName)]
public sealed class DialogServiceTests
{
[Fact(DisplayName = "Constructor rejects null parent window")]
public void Constructor_NullParentWindow_Throws()
{
Assert.Throws<ArgumentNullException>(() => new DialogService(null));
}

[AvaloniaFact(DisplayName = "GetStorageFolderFromPathAsync returns null for empty path")]
public async Task GetStorageFolderFromPathAsync_EmptyPath_ReturnsNull()
{
var service = new DialogService(new Window());

Assert.Null(await service.GetStorageFolderFromPathAsync(string.Empty));
Assert.Null(await service.GetStorageFolderFromPathAsync(null));
}
}
}
33 changes: 33 additions & 0 deletions src/ModSync.Tests/FileSystemServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2021-2025 ModSync
// Licensed under the Business Source License 1.1 (BSL 1.1).
// See LICENSE.txt file in the project root for full license information.

using ModSync.Services;
using Xunit;

namespace ModSync.Tests
{
public sealed class FileSystemServiceTests
{
[Fact(DisplayName = "SetupModDirectoryWatcher does not throw when watcher disabled")]
public void SetupModDirectoryWatcher_Disabled_DoesNotThrow()
{
FileSystemService.SetupModDirectoryWatcher("/tmp", _ => { });
}

[Fact(DisplayName = "StopWatcher does not throw on fresh service")]
public void StopWatcher_FreshService_DoesNotThrow()
{
using var service = new FileSystemService();
service.StopWatcher();
}

[Fact(DisplayName = "Dispose can be called multiple times")]
public void Dispose_MultipleCalls_DoesNotThrow()
{
var service = new FileSystemService();
service.Dispose();
service.Dispose();
}
}
}
Loading