mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-09-05 23:56:50 +08:00
feat: basic aria2 integration
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
package aria2dl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
storconfig "github.com/krau/SaveAny-Bot/config/storage"
|
||||
"github.com/krau/SaveAny-Bot/pkg/aria2"
|
||||
storenum "github.com/krau/SaveAny-Bot/pkg/enums/storage"
|
||||
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
||||
)
|
||||
|
||||
type mockStorage struct {
|
||||
name string
|
||||
savePath string
|
||||
}
|
||||
|
||||
func (m *mockStorage) Name() string {
|
||||
return m.name
|
||||
}
|
||||
|
||||
func (m *mockStorage) Type() storenum.StorageType {
|
||||
return storenum.StorageType("mock")
|
||||
}
|
||||
|
||||
func (m *mockStorage) Init(ctx context.Context, config storconfig.StorageConfig) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockStorage) Save(ctx context.Context, reader io.Reader, path string) error {
|
||||
m.savePath = path
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockStorage) Exists(ctx context.Context, path string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *mockStorage) JoinStoragePath(path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
type mockProgress struct {
|
||||
started bool
|
||||
done bool
|
||||
doneErr error
|
||||
progress int
|
||||
}
|
||||
|
||||
func (m *mockProgress) OnStart(ctx context.Context, task *Task) {
|
||||
m.started = true
|
||||
}
|
||||
|
||||
func (m *mockProgress) OnProgress(ctx context.Context, task *Task, status *aria2.Status) {
|
||||
m.progress++
|
||||
}
|
||||
|
||||
func (m *mockProgress) OnDone(ctx context.Context, task *Task, err error) {
|
||||
m.done = true
|
||||
m.doneErr = err
|
||||
}
|
||||
|
||||
func TestTaskCreation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mockStor := &mockStorage{name: "test-storage"}
|
||||
mockProg := &mockProgress{}
|
||||
|
||||
task := NewTask(
|
||||
"test-task-id",
|
||||
ctx,
|
||||
"test-gid",
|
||||
[]string{"http://example.com/file.zip"},
|
||||
nil,
|
||||
mockStor,
|
||||
"/test/path",
|
||||
mockProg,
|
||||
)
|
||||
|
||||
if task.ID != "test-task-id" {
|
||||
t.Errorf("Expected task ID to be 'test-task-id', got '%s'", task.ID)
|
||||
}
|
||||
|
||||
if task.GID != "test-gid" {
|
||||
t.Errorf("Expected GID to be 'test-gid', got '%s'", task.GID)
|
||||
}
|
||||
|
||||
if task.Type() != tasktype.TaskTypeAria2 {
|
||||
t.Errorf("Expected task type to be TaskTypeAria2, got '%s'", task.Type())
|
||||
}
|
||||
|
||||
if task.TaskID() != "test-task-id" {
|
||||
t.Errorf("Expected TaskID() to return 'test-task-id', got '%s'", task.TaskID())
|
||||
}
|
||||
|
||||
if task.Storage.Name() != "test-storage" {
|
||||
t.Errorf("Expected storage name to be 'test-storage', got '%s'", task.Storage.Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestProgressTracker(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mockStor := &mockStorage{name: "test-storage"}
|
||||
mockProg := &mockProgress{}
|
||||
|
||||
task := NewTask(
|
||||
"test-task-id",
|
||||
ctx,
|
||||
"test-gid",
|
||||
[]string{"http://example.com/file.zip"},
|
||||
nil,
|
||||
mockStor,
|
||||
"/test/path",
|
||||
mockProg,
|
||||
)
|
||||
|
||||
// Test OnStart
|
||||
mockProg.OnStart(ctx, task)
|
||||
if !mockProg.started {
|
||||
t.Error("Expected OnStart to set started to true")
|
||||
}
|
||||
|
||||
// Test OnProgress
|
||||
status := &aria2.Status{
|
||||
GID: "test-gid",
|
||||
Status: "active",
|
||||
TotalLength: "1000000",
|
||||
CompletedLength: "500000",
|
||||
DownloadSpeed: "100000",
|
||||
}
|
||||
mockProg.OnProgress(ctx, task, status)
|
||||
if mockProg.progress != 1 {
|
||||
t.Errorf("Expected progress to be 1, got %d", mockProg.progress)
|
||||
}
|
||||
|
||||
// Test OnDone
|
||||
mockProg.OnDone(ctx, task, nil)
|
||||
if !mockProg.done {
|
||||
t.Error("Expected OnDone to set done to true")
|
||||
}
|
||||
if mockProg.doneErr != nil {
|
||||
t.Errorf("Expected doneErr to be nil, got %v", mockProg.doneErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTaskTitle(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mockStor := &mockStorage{name: "test-storage"}
|
||||
|
||||
task := NewTask(
|
||||
"test-task-id",
|
||||
ctx,
|
||||
"test-gid-123",
|
||||
[]string{"http://example.com/file.zip"},
|
||||
nil,
|
||||
mockStor,
|
||||
"/test/path",
|
||||
nil,
|
||||
)
|
||||
|
||||
title := task.Title()
|
||||
expectedSubstr := "test-gid-123"
|
||||
if len(title) == 0 {
|
||||
t.Error("Expected title to not be empty")
|
||||
}
|
||||
|
||||
// Check if title contains the GID
|
||||
found := false
|
||||
for i := 0; i < len(title)-len(expectedSubstr)+1; i++ {
|
||||
if title[i:i+len(expectedSubstr)] == expectedSubstr {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("Expected title to contain GID '%s', got '%s'", expectedSubstr, title)
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextCancellation(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
mockStor := &mockStorage{name: "test-storage"}
|
||||
mockProg := &mockProgress{}
|
||||
|
||||
task := NewTask(
|
||||
"test-task-id",
|
||||
ctx,
|
||||
"test-gid",
|
||||
[]string{"http://example.com/file.zip"},
|
||||
nil, // nil client will cause Execute to fail/timeout
|
||||
mockStor,
|
||||
"/test/path",
|
||||
mockProg,
|
||||
)
|
||||
|
||||
// Just verify the task structure is valid
|
||||
if task.ctx.Err() != nil {
|
||||
t.Error("Context should not be cancelled yet")
|
||||
}
|
||||
|
||||
// Wait for context to timeout
|
||||
<-ctx.Done()
|
||||
if ctx.Err() == nil {
|
||||
t.Error("Context should be cancelled after timeout")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user