Files
podcast-search-go/search/itunes_search_test.go
2025-03-28 22:27:08 +08:00

332 lines
9.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package search
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestSearchPodcasts_EmptyTerm(t *testing.T) {
// 创建iTunes搜索提供者
provider := NewITunesProvider()
// 使用空搜索词调用SearchPodcasts
result, err := provider.SearchPodcasts("", nil)
// 验证返回错误
if err == nil {
t.Error("期望返回错误,但没有")
}
// 验证错误消息
expectedErrMsg := "搜索词不能为空"
if err.Error() != expectedErrMsg {
t.Errorf("期望错误消息为 %q但得到 %q", expectedErrMsg, err.Error())
}
// 验证结果为nil
if result != nil {
t.Errorf("期望结果为nil但得到 %+v", result)
}
}
func TestSearchPodcasts_SuccessfulSearch(t *testing.T) {
// 创建测试服务器
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 验证请求方法
if r.Method != http.MethodGet {
t.Errorf("期望请求方法为GET但得到 %s", r.Method)
}
// 验证请求路径
if r.URL.Path != "/search" {
t.Errorf("期望请求路径为/search但得到 %s", r.URL.Path)
}
// 验证查询参数
query := r.URL.Query()
if query.Get("term") != "golang" {
t.Errorf("期望term参数为golang但得到 %s", query.Get("term"))
}
if query.Get("entity") != "podcast" {
t.Errorf("期望entity参数为podcast但得到 %s", query.Get("entity"))
}
if query.Get("media") != "podcast" {
t.Errorf("期望media参数为podcast但得到 %s", query.Get("media"))
}
// 返回模拟响应
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// 创建模拟响应数据
response := map[string]interface{}{
"resultCount": 2,
"results": []map[string]interface{}{
{
"collectionId": 1234567890,
"collectionName": "Go编程语言",
"artistName": "Go开发者",
"feedUrl": "https://example.com/feed1",
"artworkUrl100": "https://example.com/artwork1_100.jpg",
"artworkUrl600": "https://example.com/artwork1_600.jpg",
"genres": []string{"Technology", "Education"},
},
{
"collectionId": 9876543210,
"collectionName": "Golang讨论",
"artistName": "Golang爱好者",
"feedUrl": "https://example.com/feed2",
"artworkUrl100": "https://example.com/artwork2_100.jpg",
"artworkUrl600": "https://example.com/artwork2_600.jpg",
"genres": []string{"Technology"},
},
},
}
// 将响应数据编码为JSON并写入响应
json.NewEncoder(w).Encode(response)
}))
defer server.Close()
// 创建iTunes搜索提供者并设置测试服务器URL
provider := &ITunesProvider{
SearchAPIEndpoint: server.URL,
FeedAPIEndpoint: "https://itunes.apple.com",
GenresMap: initITunesGenres(),
Client: &http.Client{Timeout: 20 * time.Second},
}
// 调用SearchPodcasts
result, err := provider.SearchPodcasts("golang", nil)
// 验证没有错误
if err != nil {
t.Fatalf("期望没有错误,但得到 %v", err)
}
// 验证结果
if result == nil {
t.Fatal("期望结果不为nil但得到nil")
}
// 验证结果计数
if result.ResultCount != 2 {
t.Errorf("期望结果计数为2但得到 %d", result.ResultCount)
}
// 验证结果成功标志
if !result.Successful {
t.Error("期望结果成功标志为true但得到false")
}
// 验证结果项目数量
if len(result.Items) != 2 {
t.Errorf("期望结果项目数量为2但得到 %d", len(result.Items))
}
// 验证第一个结果项目
item1 := result.Items[0]
if item1.CollectionID != 1234567890 {
t.Errorf("期望第一个项目的CollectionID为1234567890但得到 %d", item1.CollectionID)
}
if item1.Title != "Go编程语言" {
t.Errorf("期望第一个项目的Title为'Go编程语言',但得到 %s", item1.Title)
}
if item1.Author != "Go开发者" {
t.Errorf("期望第一个项目的Author为'Go开发者',但得到 %s", item1.Author)
}
if item1.FeedURL != "https://example.com/feed1" {
t.Errorf("期望第一个项目的FeedURL为'https://example.com/feed1',但得到 %s", item1.FeedURL)
}
if item1.ArtworkURL != "https://example.com/artwork1_100.jpg" {
t.Errorf("期望第一个项目的ArtworkURL为'https://example.com/artwork1_100.jpg',但得到 %s", item1.ArtworkURL)
}
if item1.ArtworkURL600 != "https://example.com/artwork1_600.jpg" {
t.Errorf("期望第一个项目的ArtworkURL600为'https://example.com/artwork1_600.jpg',但得到 %s", item1.ArtworkURL600)
}
if len(item1.Genres) != 2 || item1.Genres[0] != "Technology" || item1.Genres[1] != "Education" {
t.Errorf("期望第一个项目的Genres为[Technology, Education],但得到 %v", item1.Genres)
}
// 验证第二个结果项目
item2 := result.Items[1]
if item2.CollectionID != 9876543210 {
t.Errorf("期望第二个项目的CollectionID为9876543210但得到 %d", item2.CollectionID)
}
if item2.Title != "Golang讨论" {
t.Errorf("期望第二个项目的Title为'Golang讨论',但得到 %s", item2.Title)
}
}
func TestSearchPodcasts_WithOptions(t *testing.T) {
// 创建测试服务器
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 验证查询参数
query := r.URL.Query()
// 验证基本参数
if query.Get("term") != "golang" {
t.Errorf("期望term参数为golang但得到 %s", query.Get("term"))
}
// 验证选项参数
if query.Get("country") != "cn" {
t.Errorf("期望country参数为cn但得到 %s", query.Get("country"))
}
if query.Get("genreId") != "1318" { // Technology的ID
t.Errorf("期望genreId参数为1318但得到 %s", query.Get("genreId"))
}
if query.Get("attribute") != "titleTerm" {
t.Errorf("期望attribute参数为titleTerm但得到 %s", query.Get("attribute"))
}
if query.Get("limit") != "10" {
t.Errorf("期望limit参数为10但得到 %s", query.Get("limit"))
}
if query.Get("language") != "zh-cn" {
t.Errorf("期望language参数为zh-cn但得到 %s", query.Get("language"))
}
if query.Get("explicit") != "No" {
t.Errorf("期望explicit参数为No但得到 %s", query.Get("explicit"))
}
// 返回模拟响应
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
// 创建模拟响应数据
response := map[string]interface{}{
"resultCount": 1,
"results": []map[string]interface{}{
{
"collectionId": 1234567890,
"collectionName": "Go编程语言",
"artistName": "Go开发者",
"feedUrl": "https://example.com/feed1",
"artworkUrl100": "https://example.com/artwork1_100.jpg",
"artworkUrl600": "https://example.com/artwork1_600.jpg",
"genres": []string{"Technology"},
},
},
}
// 将响应数据编码为JSON并写入响应
json.NewEncoder(w).Encode(response)
}))
defer server.Close()
// 创建iTunes搜索提供者并设置测试服务器URL
provider := &ITunesProvider{
SearchAPIEndpoint: server.URL,
FeedAPIEndpoint: "https://itunes.apple.com",
GenresMap: initITunesGenres(),
Client: &http.Client{Timeout: 20 * time.Second},
}
// 创建搜索选项
options := &SearchOptions{
Country: "cn",
Genre: "Technology",
Attribute: "titleTerm",
Limit: 10,
Language: "zh-cn",
Explicit: false,
}
// 调用SearchPodcasts
result, err := provider.SearchPodcasts("golang", options)
// 验证没有错误
if err != nil {
t.Fatalf("期望没有错误,但得到 %v", err)
}
// 验证结果
if result == nil {
t.Fatal("期望结果不为nil但得到nil")
}
// 验证结果计数
if result.ResultCount != 1 {
t.Errorf("期望结果计数为1但得到 %d", result.ResultCount)
}
// 验证结果项目数量
if len(result.Items) != 1 {
t.Errorf("期望结果项目数量为1但得到 %d", len(result.Items))
}
}
func TestSearchPodcasts_APIError(t *testing.T) {
// 创建测试服务器,返回错误状态码
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusInternalServerError)
}))
defer server.Close()
// 创建iTunes搜索提供者并设置测试服务器URL
provider := &ITunesProvider{
SearchAPIEndpoint: server.URL,
FeedAPIEndpoint: "https://itunes.apple.com",
GenresMap: initITunesGenres(),
Client: &http.Client{Timeout: 20 * time.Second},
}
// 调用SearchPodcasts
result, err := provider.SearchPodcasts("golang", nil)
// 验证返回错误
if err == nil {
t.Error("期望返回错误,但没有")
}
// 验证错误消息包含状态码
expectedErrMsg := "API请求失败状态码: 500"
if err.Error() != expectedErrMsg {
t.Errorf("期望错误消息包含 %q但得到 %q", expectedErrMsg, err.Error())
}
// 验证结果为nil
if result != nil {
t.Errorf("期望结果为nil但得到 %+v", result)
}
}
func TestSearchPodcasts_InvalidJSON(t *testing.T) {
// 创建测试服务器返回无效的JSON
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"resultCount": 1, "results": [invalid json]`))
}))
defer server.Close()
// 创建iTunes搜索提供者并设置测试服务器URL
provider := &ITunesProvider{
SearchAPIEndpoint: server.URL,
FeedAPIEndpoint: "https://itunes.apple.com",
GenresMap: initITunesGenres(),
Client: &http.Client{Timeout: 20 * time.Second},
}
// 调用SearchPodcasts
result, err := provider.SearchPodcasts("golang", nil)
// 验证返回错误
if err == nil {
t.Error("期望返回错误,但没有")
}
// 验证错误消息包含解析失败
if err != nil && err.Error() != "解析响应失败: invalid character 'i' looking for beginning of value" {
t.Errorf("期望错误消息包含解析失败,但得到 %q", err.Error())
}
// 验证结果为nil
if result != nil {
t.Errorf("期望结果为nil但得到 %+v", result)
}
}