mirror of
https://github.com/Belphemur/CBZOptimizer.git
synced 2025-10-14 20:38:52 +02:00
336 lines
8.4 KiB
Go
336 lines
8.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/belphemur/CBZOptimizer/v2/internal/cbz"
|
|
"github.com/belphemur/CBZOptimizer/v2/internal/manga"
|
|
"github.com/belphemur/CBZOptimizer/v2/internal/utils/errs"
|
|
"github.com/belphemur/CBZOptimizer/v2/pkg/converter/constant"
|
|
)
|
|
|
|
// MockConverter for testing
|
|
type MockConverter struct {
|
|
shouldFail bool
|
|
}
|
|
|
|
func (m *MockConverter) ConvertChapter(chapter *manga.Chapter, quality uint8, split bool, progress func(message string, current uint32, total uint32)) (*manga.Chapter, error) {
|
|
if m.shouldFail {
|
|
return nil, &MockError{message: "mock conversion error"}
|
|
}
|
|
|
|
// Create a copy of the chapter to simulate conversion
|
|
converted := &manga.Chapter{
|
|
FilePath: chapter.FilePath,
|
|
Pages: chapter.Pages,
|
|
ComicInfoXml: chapter.ComicInfoXml,
|
|
IsConverted: true,
|
|
ConvertedTime: time.Now(),
|
|
}
|
|
return converted, nil
|
|
}
|
|
|
|
func (m *MockConverter) Format() constant.ConversionFormat {
|
|
return constant.WebP
|
|
}
|
|
|
|
func (m *MockConverter) PrepareConverter() error {
|
|
if m.shouldFail {
|
|
return &MockError{message: "mock prepare error"}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type MockError struct {
|
|
message string
|
|
}
|
|
|
|
func (e *MockError) Error() string {
|
|
return e.message
|
|
}
|
|
|
|
func TestOptimize(t *testing.T) {
|
|
// Create temporary directory for tests
|
|
tempDir, err := os.MkdirTemp("", "test_optimize")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer errs.CaptureGeneric(&err, os.RemoveAll, tempDir, "failed to remove temporary directory")
|
|
|
|
// Copy test files
|
|
testdataDir := "../../testdata"
|
|
if _, err := os.Stat(testdataDir); os.IsNotExist(err) {
|
|
t.Skip("testdata directory not found, skipping tests")
|
|
}
|
|
|
|
// Copy sample files
|
|
var cbzFile, cbrFile string
|
|
err = filepath.Walk(testdataDir, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !info.IsDir() {
|
|
fileName := strings.ToLower(info.Name())
|
|
if strings.HasSuffix(fileName, ".cbz") && !strings.Contains(fileName, "converted") {
|
|
destPath := filepath.Join(tempDir, "test.cbz")
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(destPath, data, info.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cbzFile = destPath
|
|
} else if strings.HasSuffix(fileName, ".cbr") {
|
|
destPath := filepath.Join(tempDir, "test.cbr")
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(destPath, data, info.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cbrFile = destPath
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if cbzFile == "" {
|
|
t.Skip("No CBZ test file found")
|
|
}
|
|
|
|
// Create a CBR file by copying the CBZ file if no CBR exists
|
|
if cbrFile == "" {
|
|
cbrFile = filepath.Join(tempDir, "test.cbr")
|
|
data, err := os.ReadFile(cbzFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = os.WriteFile(cbrFile, data, 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
inputFile string
|
|
override bool
|
|
expectedOutput string
|
|
shouldDelete bool
|
|
expectError bool
|
|
mockFail bool
|
|
}{
|
|
{
|
|
name: "CBZ file without override",
|
|
inputFile: cbzFile,
|
|
override: false,
|
|
expectedOutput: strings.TrimSuffix(cbzFile, ".cbz") + "_converted.cbz",
|
|
shouldDelete: false,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "CBZ file with override",
|
|
inputFile: cbzFile,
|
|
override: true,
|
|
expectedOutput: cbzFile,
|
|
shouldDelete: false,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "CBR file without override",
|
|
inputFile: cbrFile,
|
|
override: false,
|
|
expectedOutput: strings.TrimSuffix(cbrFile, ".cbr") + "_converted.cbz",
|
|
shouldDelete: false,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "CBR file with override",
|
|
inputFile: cbrFile,
|
|
override: true,
|
|
expectedOutput: strings.TrimSuffix(cbrFile, ".cbr") + ".cbz",
|
|
shouldDelete: true,
|
|
expectError: false,
|
|
},
|
|
{
|
|
name: "Converter failure",
|
|
inputFile: cbzFile,
|
|
override: false,
|
|
expectError: true,
|
|
mockFail: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Create a copy of the input file for this test
|
|
testFile := filepath.Join(tempDir, tt.name+"_"+filepath.Base(tt.inputFile))
|
|
data, err := os.ReadFile(tt.inputFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = os.WriteFile(testFile, data, 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Setup options
|
|
options := &OptimizeOptions{
|
|
ChapterConverter: &MockConverter{shouldFail: tt.mockFail},
|
|
Path: testFile,
|
|
Quality: 85,
|
|
Override: tt.override,
|
|
Split: false,
|
|
}
|
|
|
|
// Run optimization
|
|
err = Optimize(options)
|
|
|
|
if tt.expectError {
|
|
if err == nil {
|
|
t.Error("Expected error but got none")
|
|
}
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
|
|
// Determine expected output path for this test
|
|
expectedOutput := tt.expectedOutput
|
|
if tt.override && strings.HasSuffix(strings.ToLower(testFile), ".cbr") {
|
|
expectedOutput = strings.TrimSuffix(testFile, filepath.Ext(testFile)) + ".cbz"
|
|
} else if !tt.override {
|
|
if strings.HasSuffix(strings.ToLower(testFile), ".cbz") {
|
|
expectedOutput = strings.TrimSuffix(testFile, ".cbz") + "_converted.cbz"
|
|
} else if strings.HasSuffix(strings.ToLower(testFile), ".cbr") {
|
|
expectedOutput = strings.TrimSuffix(testFile, ".cbr") + "_converted.cbz"
|
|
}
|
|
} else {
|
|
expectedOutput = testFile
|
|
}
|
|
|
|
// Verify output file exists
|
|
if _, err := os.Stat(expectedOutput); os.IsNotExist(err) {
|
|
t.Errorf("Expected output file not found: %s", expectedOutput)
|
|
}
|
|
|
|
// Verify output is a valid CBZ
|
|
chapter, err := cbz.LoadChapter(expectedOutput)
|
|
if err != nil {
|
|
t.Errorf("Failed to load converted chapter: %v", err)
|
|
}
|
|
|
|
if !chapter.IsConverted {
|
|
t.Error("Chapter is not marked as converted")
|
|
}
|
|
|
|
// Verify original file deletion for CBR override
|
|
if tt.shouldDelete {
|
|
if _, err := os.Stat(testFile); !os.IsNotExist(err) {
|
|
t.Error("Original CBR file should have been deleted but still exists")
|
|
}
|
|
} else {
|
|
// Verify original file still exists (unless it's the same as output)
|
|
if testFile != expectedOutput {
|
|
if _, err := os.Stat(testFile); os.IsNotExist(err) {
|
|
t.Error("Original file should not have been deleted")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Clean up output file
|
|
os.Remove(expectedOutput)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOptimize_AlreadyConverted(t *testing.T) {
|
|
// Create temporary directory
|
|
tempDir, err := os.MkdirTemp("", "test_optimize_converted")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer errs.CaptureGeneric(&err, os.RemoveAll, tempDir, "failed to remove temporary directory")
|
|
|
|
// Use a converted test file
|
|
testdataDir := "../../testdata"
|
|
if _, err := os.Stat(testdataDir); os.IsNotExist(err) {
|
|
t.Skip("testdata directory not found, skipping tests")
|
|
}
|
|
|
|
var convertedFile string
|
|
err = filepath.Walk(testdataDir, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !info.IsDir() && strings.Contains(strings.ToLower(info.Name()), "converted") {
|
|
destPath := filepath.Join(tempDir, info.Name())
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(destPath, data, info.Mode())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
convertedFile = destPath
|
|
return filepath.SkipDir
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if convertedFile == "" {
|
|
t.Skip("No converted test file found")
|
|
}
|
|
|
|
options := &OptimizeOptions{
|
|
ChapterConverter: &MockConverter{},
|
|
Path: convertedFile,
|
|
Quality: 85,
|
|
Override: false,
|
|
Split: false,
|
|
}
|
|
|
|
err = Optimize(options)
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
|
|
// Should not create a new file since it's already converted
|
|
expectedOutput := strings.TrimSuffix(convertedFile, ".cbz") + "_converted.cbz"
|
|
if _, err := os.Stat(expectedOutput); !os.IsNotExist(err) {
|
|
t.Error("Should not have created a new converted file for already converted chapter")
|
|
}
|
|
}
|
|
|
|
func TestOptimize_InvalidFile(t *testing.T) {
|
|
options := &OptimizeOptions{
|
|
ChapterConverter: &MockConverter{},
|
|
Path: "/nonexistent/file.cbz",
|
|
Quality: 85,
|
|
Override: false,
|
|
Split: false,
|
|
}
|
|
|
|
err := Optimize(options)
|
|
if err == nil {
|
|
t.Error("Expected error for nonexistent file")
|
|
}
|
|
}
|