332 lines
9.9 KiB
Go
332 lines
9.9 KiB
Go
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)
|
||
}
|
||
}
|