feat(ads/seo/release): v1.2.0 with live Google Ads, isolated ad profile, ads.txt, and SEO/AEO/GEO optimization
This commit is contained in:
parent
a88aafa1e5
commit
0e568f1f0a
975 changed files with 130593 additions and 16783 deletions
118
tests/Paca.Tests/App/DownloadFolderOpenGateTests.cs
Normal file
118
tests/Paca.Tests/App/DownloadFolderOpenGateTests.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Paca.App.Utils;
|
||||
using Paca.Tests.Infrastructure;
|
||||
using Xunit;
|
||||
|
||||
namespace Paca.Tests.App;
|
||||
|
||||
public class DownloadFolderOpenGateTests
|
||||
{
|
||||
[Fact]
|
||||
public void Gate480_ExplorerLauncher_Arguments_HaveSelectOutsideQuotes_AndUseShellExecuteTrue()
|
||||
{
|
||||
// DoD: 공백 및 한글/특수문자가 포함된 다운로드 파일명에 대해
|
||||
// explorer.exe 인자 구성 시 /select, 가 큰따옴표 바깥에 위치하고 UseShellExecute = true 여야 함
|
||||
var testDir = Path.Combine(Path.GetTempPath(), "PacaTest_Gate480_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(testDir);
|
||||
try
|
||||
{
|
||||
var testFile = Path.Combine(testDir, "(13) 손만 잡아도 2500만 원 순삭_ 베트남 국제결혼의 비밀!.mp4");
|
||||
File.WriteAllText(testFile, "dummy video data");
|
||||
|
||||
var psi = ExplorerLauncher.BuildProcessStartInfo(testFile, testDir);
|
||||
|
||||
Assert.NotNull(psi);
|
||||
Assert.True(psi.UseShellExecute, "UseShellExecute must be true for Windows Shell explorer invocation");
|
||||
Assert.Equal("explorer.exe", psi.FileName, ignoreCase: true);
|
||||
|
||||
// 중요: "/select,C:\..." 형태는 Windows explorer.exe 가 옵션으로 인식하지 못하고 종료코드 1로 실패함
|
||||
// 올바른 형식: /select,"C:\..."
|
||||
Assert.StartsWith("/select,\"", psi.Arguments);
|
||||
Assert.EndsWith("\"", psi.Arguments);
|
||||
Assert.False(psi.Arguments.StartsWith("\"/select,"), "Arguments must NOT enclose /select within quotes");
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Directory.Delete(testDir, true); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate481_ExplorerLauncher_FallbackToDirectory_WhenFileDoesNotExist()
|
||||
{
|
||||
var testDir = Path.Combine(Path.GetTempPath(), "PacaTest_Gate481_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(testDir);
|
||||
try
|
||||
{
|
||||
var nonExistentFile = Path.Combine(testDir, "deleted_video.mp4");
|
||||
|
||||
var psi = ExplorerLauncher.BuildProcessStartInfo(nonExistentFile, testDir);
|
||||
|
||||
Assert.NotNull(psi);
|
||||
Assert.True(psi.UseShellExecute);
|
||||
// 파일이 없으면 상위 폴더(testDir) 자체를 직접 열도록 구성
|
||||
Assert.Equal(Path.GetFullPath(testDir), Path.GetFullPath(psi.FileName), ignoreCase: true);
|
||||
Assert.True(string.IsNullOrEmpty(psi.Arguments));
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Directory.Delete(testDir, true); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate482_ExplorerLauncher_RelativePath_ResolvedWithOutputFolder()
|
||||
{
|
||||
var testDir = Path.Combine(Path.GetTempPath(), "PacaTest_Gate482_" + Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(testDir);
|
||||
try
|
||||
{
|
||||
const string fileName = "relative_clip.mp4";
|
||||
var fullPath = Path.Combine(testDir, fileName);
|
||||
File.WriteAllText(fullPath, "content");
|
||||
|
||||
// 상대 경로가 넘어왔을 때 OutputFolder 기준으로 전체 경로 해석 검증
|
||||
var psi = ExplorerLauncher.BuildProcessStartInfo(fileName, testDir);
|
||||
|
||||
Assert.NotNull(psi);
|
||||
Assert.True(psi.UseShellExecute);
|
||||
Assert.Equal("explorer.exe", psi.FileName, ignoreCase: true);
|
||||
Assert.Contains(fullPath, psi.Arguments);
|
||||
Assert.StartsWith("/select,\"", psi.Arguments);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Directory.Delete(testDir, true); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate483_OpenInExplorer_SourceCode_DoesNotUseArgumentListWithUseShellExecuteFalse()
|
||||
{
|
||||
// DoD: MainWindow.xaml.cs의 OpenInExplorer가 ArgumentList.Add(/select...) + UseShellExecute = false 조합을 사용하지 않아야 함
|
||||
var mwCs = File.ReadAllText(SourceTree.AppPath("MainWindow.xaml.cs"));
|
||||
|
||||
Assert.DoesNotContain("psi.ArgumentList.Add($\"/select,{selectFile}\");", mwCs);
|
||||
Assert.DoesNotContain("new System.Diagnostics.ProcessStartInfo(\"explorer.exe\") { UseShellExecute = false }", mwCs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate484_ExplorerLauncher_CreatesDirectory_IfOutputFolderDoesNotExist()
|
||||
{
|
||||
var nonExistentDir = Path.Combine(Path.GetTempPath(), "PacaTest_Gate484_AutoCreate_" + Guid.NewGuid().ToString("N"));
|
||||
Assert.False(Directory.Exists(nonExistentDir));
|
||||
|
||||
try
|
||||
{
|
||||
var psi = ExplorerLauncher.BuildProcessStartInfo(null, nonExistentDir);
|
||||
Assert.NotNull(psi);
|
||||
Assert.True(Directory.Exists(nonExistentDir), "BuildProcessStartInfo or Launcher must ensure the output folder exists");
|
||||
}
|
||||
finally
|
||||
{
|
||||
try { Directory.Delete(nonExistentDir, true); } catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue