Skip to content

Commit 6312e21

Browse files
committed
test: fix weak, redundant, and missing test assertions
- Remove redundant AppSettingsManager roundtrip test (T-03) - Fix vacuously true temp file check to scan for *.tmp (T-04) - Add RecentPipelines validation tests: relative, null byte, long, whitespace (T-05) - Rename Redo_CapsCombinedStackAt25 to Redo_ReAddsToUndoStack_RespectingCap (T-06) - Merge status assertion into File_not_matching_extension_is_dropped, delete duplicate (T-14) - Strengthen SortNode FlushAsync assertion with order verification (T-16) - Remove dead node variable in FlushAsync_exception test (T-17) - Add content verification to FolderOutput copy/move tests (T-10/T-11) Co-Authored-By: Rooty
1 parent e7cf66d commit 6312e21

6 files changed

Lines changed: 67 additions & 56 deletions

File tree

tests/FlowForge.Tests/Nodes/FilterNodeTests.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public async Task File_not_matching_extension_is_dropped()
5757

5858
IEnumerable<FileJob> result = await node.TransformAsync(job, dryRun: true);
5959
result.Should().BeEmpty();
60+
job.Status.Should().Be(FileJobStatus.Skipped);
6061
}
6162

6263
[Fact]
@@ -156,26 +157,6 @@ public async Task Multiple_conditions_all_must_match()
156157
resultExtOnly.Should().BeEmpty();
157158
}
158159

159-
[Fact]
160-
public async Task File_not_matching_extension_is_marked_skipped()
161-
{
162-
var node = new FilterNode(NullLogger<FilterNode>.Instance);
163-
node.Configure(MakeConfig(new[]
164-
{
165-
new { field = "extension", @operator = "equals", value = ".jpg" }
166-
}));
167-
168-
var job = new FileJob
169-
{
170-
OriginalPath = FakePath("document.pdf"),
171-
CurrentPath = FakePath("document.pdf")
172-
};
173-
174-
IEnumerable<FileJob> result = await node.TransformAsync(job, dryRun: true);
175-
result.Should().BeEmpty();
176-
job.Status.Should().Be(FileJobStatus.Skipped);
177-
}
178-
179160
[Fact]
180161
public async Task Regex_timeout_sets_failed_and_returns_empty()
181162
{

tests/FlowForge.Tests/Nodes/FolderOutputNodeTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ public async Task Copy_mode_preserves_source_file()
3333
await node.ConsumeAsync(job, dryRun: false);
3434

3535
File.Exists(sourcePath).Should().BeTrue("copy mode should preserve the source file");
36-
File.Exists(Path.Combine(dir.OutputPath, "photo.jpg")).Should().BeTrue();
36+
string destPath = Path.Combine(dir.OutputPath, "photo.jpg");
37+
File.Exists(destPath).Should().BeTrue();
38+
File.ReadAllText(destPath).Should().Be("test content: photo.jpg");
3739
}
3840

3941
[Fact]
@@ -51,7 +53,9 @@ public async Task Move_mode_removes_source_file()
5153
await node.ConsumeAsync(job, dryRun: false);
5254

5355
File.Exists(sourcePath).Should().BeFalse("move mode should remove the source file");
54-
File.Exists(Path.Combine(dir.OutputPath, "photo.jpg")).Should().BeTrue();
56+
string destPath = Path.Combine(dir.OutputPath, "photo.jpg");
57+
File.Exists(destPath).Should().BeTrue();
58+
File.ReadAllText(destPath).Should().Be("test content: photo.jpg");
5559
}
5660

5761
[Fact]

tests/FlowForge.Tests/Nodes/SortNodeTests.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public async Task FlushAsync_returns_all_buffered_jobs()
5252
IEnumerable<FileJob> result = await node.FlushAsync();
5353

5454
result.Should().HaveCount(3);
55+
result.Select(j => j.FileName).Should().ContainInOrder("a.txt", "b.txt", "c.txt");
5556
}
5657

5758
[Fact]
@@ -198,13 +199,6 @@ public async Task FlushAsync_respects_cancellation_token()
198199
[Fact]
199200
public async Task FlushAsync_exception_marks_all_jobs_failed()
200201
{
201-
var node = new SortNode(NullLogger<SortNode>.Instance);
202-
// "size" field requires files to exist on disk — non-existent paths will cause an exception
203-
// during OrderBy when it tries to read file sizes
204-
node.Configure(MakeConfig(new { field = "size", direction = "asc" }));
205-
206-
// Buffer jobs with non-existent paths — GetFileSize returns 0 for missing files,
207-
// so we use an invalid sort field instead
208202
var node2 = new SortNode(NullLogger<SortNode>.Instance);
209203
node2.Configure(MakeConfig(new { field = "INVALID_FIELD", direction = "asc" }));
210204

tests/FlowForge.Tests/Settings/AppSettingsManagerTests.cs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ public async Task Save_atomic_tmp_file_does_not_exist_after_save()
8787

8888
await manager.SaveAsync(new AppSettings());
8989

90-
string tmpPath = settingsPath + ".tmp";
91-
File.Exists(tmpPath).Should().BeFalse();
90+
// Verify no temp files of any name were left behind (GUID-named .tmp files)
91+
Directory.GetFiles(dir.Path, "*.tmp").Should().BeEmpty();
9292
File.Exists(settingsPath).Should().BeTrue();
9393
}
9494

@@ -104,28 +104,4 @@ public async Task SaveAsync_with_null_settings_throws_ArgumentNullException()
104104

105105
await act.Should().ThrowAsync<ArgumentNullException>();
106106
}
107-
108-
[Fact]
109-
public async Task Custom_settings_values_preserved_through_save_and_load()
110-
{
111-
using var dir = new TempDirectory();
112-
string settingsPath = Path.Combine(dir.Path, "settings.json");
113-
114-
var manager = new AppSettingsManager(settingsPath, NullLogger<AppSettingsManager>.Instance);
115-
var custom = new AppSettings
116-
{
117-
DefaultInputFolder = "/mnt/data/photos",
118-
DefaultOutputFolder = "/mnt/data/processed",
119-
MaxConcurrency = 16,
120-
RecentPipelines = new List<string> { "/mnt/data/pipelines/batch.ffpipe" },
121-
};
122-
123-
await manager.SaveAsync(custom);
124-
AppSettings loaded = await manager.LoadAsync();
125-
126-
loaded.DefaultInputFolder.Should().Be("/mnt/data/photos");
127-
loaded.DefaultOutputFolder.Should().Be("/mnt/data/processed");
128-
loaded.MaxConcurrency.Should().Be(16);
129-
loaded.RecentPipelines.Should().Equal("/mnt/data/pipelines/batch.ffpipe");
130-
}
131107
}

tests/FlowForge.Tests/Settings/AppSettingsRecentTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,60 @@ public void Validate_keeps_valid_MaxConcurrency()
101101

102102
settings.MaxConcurrency.Should().Be(4);
103103
}
104+
105+
[Fact]
106+
public void Validate_removes_relative_path_from_RecentPipelines()
107+
{
108+
var settings = new AppSettings
109+
{
110+
RecentPipelines = new List<string> { "relative/path.ffpipe", Path.Combine(Path.GetTempPath(), "valid.ffpipe") }
111+
};
112+
settings.Validate();
113+
114+
settings.RecentPipelines.Should().ContainSingle()
115+
.Which.Should().Contain("valid.ffpipe");
116+
}
117+
118+
[Fact]
119+
public void Validate_removes_null_byte_path_from_RecentPipelines()
120+
{
121+
var settings = new AppSettings
122+
{
123+
RecentPipelines = new List<string> { Path.Combine(Path.GetTempPath(), "ok.ffpipe"), "/tmp/evil\0.ffpipe" }
124+
};
125+
settings.Validate();
126+
127+
settings.RecentPipelines.Should().ContainSingle()
128+
.Which.Should().Contain("ok.ffpipe");
129+
}
130+
131+
[Fact]
132+
public void Validate_removes_excessively_long_path_from_RecentPipelines()
133+
{
134+
var settings = new AppSettings
135+
{
136+
RecentPipelines = new List<string>
137+
{
138+
Path.Combine(Path.GetTempPath(), "good.ffpipe"),
139+
"/" + new string('a', 5000) + ".ffpipe"
140+
}
141+
};
142+
settings.Validate();
143+
144+
settings.RecentPipelines.Should().ContainSingle()
145+
.Which.Should().Contain("good.ffpipe");
146+
}
147+
148+
[Fact]
149+
public void Validate_removes_whitespace_only_entries()
150+
{
151+
var settings = new AppSettings
152+
{
153+
RecentPipelines = new List<string> { " ", Path.Combine(Path.GetTempPath(), "real.ffpipe") }
154+
};
155+
settings.Validate();
156+
157+
settings.RecentPipelines.Should().ContainSingle()
158+
.Which.Should().Contain("real.ffpipe");
159+
}
104160
}

tests/FlowForge.Tests/UndoRedo/UndoRedoManagerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ public void StateChanged_FiresOnPushExecuted()
246246
}
247247

248248
[Fact]
249-
public void Redo_CapsCombinedStackAt25()
249+
public void Redo_ReAddsToUndoStack_RespectingCap()
250250
{
251251
var manager = new UndoRedoManager();
252252

0 commit comments

Comments
 (0)