package service import ( "archive/zip" "bytes" "strings" "testing" ) func TestParseDramaSourceRejectsDisguisedAndExecutableContent(t *testing.T) { cases := []struct { name string filename string data []byte raw string }{ {name: "pdf renamed txt", filename: "novel.txt", data: []byte("%PDF-1.7\ncontent")}, {name: "zip renamed txt", filename: "novel.txt", data: []byte{'P', 'K', 3, 4, 1, 2, 3}}, {name: "html after long prefix", filename: "novel.txt", data: []byte(strings.Repeat("正文", 3000) + "")}, {name: "script pasted", raw: "小说正文\njavascript:alert(1)"}, {name: "binary pasted", raw: "正文\x00内容"}, } for _, test := range cases { t.Run(test.name, func(t *testing.T) { if _, _, err := parseDramaSource(test.filename, test.data, test.raw); err == nil { t.Fatal("expected unsafe import to be rejected") } }) } } func TestExtractDOCXReadsParagraphsAndValidatesWordPackage(t *testing.T) { valid := makeTestDOCX(t, ``, nil) text, err := extractDOCX(valid) if err != nil { t.Fatalf("extractDOCX returned error: %v", err) } if !strings.Contains(text, "第一章 开始") || !strings.Contains(text, "这是正文") { t.Fatalf("unexpected extracted text: %q", text) } fake := makeTestDOCX(t, ``, nil) if _, err := extractDOCX(fake); err == nil { t.Fatal("expected ZIP with fake DOCX structure to be rejected") } macro := makeTestDOCX(t, ``, map[string]string{"word/vbaProject.bin": "macro"}) if _, err := extractDOCX(macro); err == nil { t.Fatal("expected macro-enabled package to be rejected") } } func TestSplitDramaChaptersPreservesOriginalText(t *testing.T) { source := "作品说明\n\n第一章 初见\n正文一\n\n第二章 重逢\n正文二" chapters := splitDramaChapters(source) if len(chapters) != 2 { t.Fatalf("expected 2 chapters, got %d", len(chapters)) } joined := strings.TrimSpace(chapters[0].Content + "\n\n" + chapters[1].Content) if joined != source { t.Fatalf("chapter splitting lost or duplicated text:\nwant: %q\n got: %q", source, joined) } if chapters[0].Title != "第一章 初见" || chapters[1].Title != "第二章 重逢" { t.Fatalf("unexpected chapter titles: %#v", chapters) } if chapters := splitDramaChapters("没有章节标题的完整正文"); chapters != nil { t.Fatalf("text without chapter titles must require single-episode confirmation: %#v", chapters) } } func makeTestDOCX(t *testing.T, contentTypes string, extras map[string]string) []byte { t.Helper() var buffer bytes.Buffer writer := zip.NewWriter(&buffer) files := map[string]string{ "[Content_Types].xml": contentTypes, "word/document.xml": `第一章 开始这是正文`, } for name, content := range extras { files[name] = content } for name, content := range files { entry, err := writer.Create(name) if err != nil { t.Fatal(err) } if _, err = entry.Write([]byte(content)); err != nil { t.Fatal(err) } } if err := writer.Close(); err != nil { t.Fatal(err) } return buffer.Bytes() }