Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+217
View File
@@ -0,0 +1,217 @@
package laosiji
import (
"context"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
)
type roundTripFunc func(*http.Request) (*http.Response, error)
func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
func preserveConfig(t *testing.T) {
t.Helper()
old := Config{
AppID: Appid,
APIKey: APIKey,
APIUrl: APIUrl,
ImageYuan: IMAGEYUAN,
NoticeURL: NoticeURL,
}
t.Cleanup(func() {
InitConfig(old)
})
}
func TestConfiguredRejectsMissingCredentials(t *testing.T) {
preserveConfig(t)
InitConfig(Config{})
if Configured() {
t.Fatal("empty configuration must not be ready")
}
_, err := SystemDomains(context.Background())
if err == nil || !strings.Contains(err.Error(), "appId,apiKey,apiUrl") {
t.Fatalf("expected a diagnostic configuration error, got %v", err)
}
}
func TestMovieM3u8PathNormalization(t *testing.T) {
tests := map[string]string{
"": "",
"demo.m3u8": "laosiji/m3m/demo.m3u8",
"m3m/demo.m3u8": "laosiji/m3m/demo.m3u8",
"laosiji/m3m/demo.m3u8": "laosiji/m3m/demo.m3u8",
"https://cdn.example.com/m3m/demo.m3u8?token=ignored": "laosiji/m3m/demo.m3u8",
"https://cdn.example.com/rk130/hevc/demo/index.m3u8": "laosiji/rk130/hevc/demo/index.m3u8",
"laosiji/rk130/hevc/demo/index.m3u8?token=also-ignored": "laosiji/rk130/hevc/demo/index.m3u8",
}
for input, want := range tests {
if got := MovieM3u8SourcePath(input); got != want {
t.Errorf("MovieM3u8SourcePath(%q) = %q, want %q", input, got, want)
}
}
}
func TestTranscodeTaskNoNeedIsExplicit(t *testing.T) {
sourceURL := "https://app.example/api/app/vid/h5/light/m3u8/source.m3u8"
result := transcodeTaskToResult(SystemDomainsResp{MovieSourceCDN: "https://cdn.example"}, transcodeTask{
Status: transcodeNoNeedStatus,
FileURL: sourceURL,
}, sourceURL, TranscodeFileID(sourceURL))
if !result.Done || !result.NoNeed {
t.Fatalf("status=4 must be done and no-need: %+v", result)
}
if result.HevcURL != sourceURL {
t.Fatalf("no-need diagnostic URL = %q, want %q", result.HevcURL, sourceURL)
}
}
func TestTranscodeSuccessWithoutFileIsFailed(t *testing.T) {
result := transcodeTaskToResult(SystemDomainsResp{}, transcodeTask{
Status: transcodeSuccessStatus,
}, "https://app.example/source.m3u8", "file-id")
if result.Done || !result.Failed {
t.Fatalf("empty successful task must fail locally instead of staying pending: %+v", result)
}
if !strings.Contains(result.ErrorMsg, "without transcode_file") {
t.Fatalf("missing diagnostic error: %+v", result)
}
}
func TestTranscodeFailureRedactsCredentials(t *testing.T) {
preserveConfig(t)
const (
appID = "app-id-secret"
apiKey = "api-key-secret"
uploadKey = "upload key+secret"
)
InitConfig(Config{
AppID: appID,
APIKey: apiKey,
APIUrl: "https://api.example",
})
result := transcodeTaskToResult(SystemDomainsResp{UploadKey: uploadKey}, transcodeTask{
Status: transcodeFailedStatus,
TranscodeError: fmt.Sprintf(
"failure app=%s api=%s upload=%s encoded=%s",
appID,
apiKey,
uploadKey,
url.QueryEscape(uploadKey),
),
}, "https://app.example/source.m3u8", "file-id")
if !result.Failed {
t.Fatalf("negative cloud status must be failed: %+v", result)
}
for _, secret := range []string{appID, apiKey, uploadKey, url.QueryEscape(uploadKey)} {
if strings.Contains(result.ErrorMsg, secret) {
t.Fatalf("transcode error leaked credential %q: %s", secret, result.ErrorMsg)
}
}
if !strings.Contains(result.ErrorMsg, "[REDACTED]") {
t.Fatalf("transcode error did not show redaction marker: %s", result.ErrorMsg)
}
}
func TestUploadNetworkErrorRedactsKey(t *testing.T) {
preserveConfig(t)
InitConfig(Config{
AppID: "app-id-secret",
APIKey: "1234567890abcdef",
APIUrl: "https://api.example",
})
uploadKey := "upload key+secret"
oldClient := uploadHTTPClient
uploadHTTPClient = &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("dial failed for %s", req.URL.String())
})}
t.Cleanup(func() {
uploadHTTPClient = oldClient
})
_, err := uploadAPICall(context.Background(), "https://upload.example/query", map[string]string{
"key": uploadKey,
})
if err == nil {
t.Fatal("expected network error")
}
errText := err.Error()
if strings.Contains(errText, uploadKey) || strings.Contains(errText, url.QueryEscape(uploadKey)) {
t.Fatalf("network error leaked upload key: %s", errText)
}
if !strings.Contains(errText, "[REDACTED]") {
t.Fatalf("network error did not show redaction marker: %s", errText)
}
}
func TestMoviePostNon2xxIsDiagnosticAndRedacted(t *testing.T) {
preserveConfig(t)
const (
appID = "app-id-secret"
apiKey = "1234567890abcdef"
)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusBadGateway)
_, _ = fmt.Fprintf(w, "failure app=%s key=%s %s", appID, apiKey, strings.Repeat("x", 500))
}))
defer server.Close()
InitConfig(Config{AppID: appID, APIKey: apiKey, APIUrl: server.URL})
err := moviePost(context.Background(), server.URL, map[string]interface{}{}, &struct{}{})
if err == nil || !strings.Contains(err.Error(), "status:502") {
t.Fatalf("expected HTTP status diagnostic, got %v", err)
}
if strings.Contains(err.Error(), appID) || strings.Contains(err.Error(), apiKey) {
t.Fatalf("HTTP error leaked credentials: %s", err)
}
if !strings.Contains(err.Error(), "[REDACTED]") || !strings.HasSuffix(err.Error(), "...") {
t.Fatalf("HTTP error was not safely redacted/truncated: %s", err)
}
}
func TestQueryH264ToH265TaskUsesExplicitStableFileID(t *testing.T) {
const fileID = "stable-file-id"
oldClient := uploadHTTPClient
uploadHTTPClient = &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
if got := req.URL.Query().Get("file_id"); got != fileID {
t.Fatalf("query file_id = %q, want %q", got, fileID)
}
return &http.Response{
StatusCode: http.StatusOK,
Header: make(http.Header),
Body: io.NopCloser(strings.NewReader(
`{"status":"y","data":{"file_id":"stable-file-id","status":1}}`,
)),
Request: req,
}, nil
})}
t.Cleanup(func() {
uploadHTTPClient = oldClient
})
result, found, err := QueryH264ToH265Task(
context.Background(),
fileID,
"https://app.example/source.m3u8?hevc_exp=1&hevc_sig=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
SystemDomainsResp{UploadURL: "https://upload.example", UploadKey: "upload-key"},
)
if err != nil || !found {
t.Fatalf("explicit task query failed: found=%v err=%v", found, err)
}
if result.FileID != fileID {
t.Fatalf("result file ID = %q, want %q", result.FileID, fileID)
}
}