917 lines
22 KiB
Go
917 lines
22 KiB
Go
// Copyright 2025 eat-pray-ai & OpenWaygate
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package caption
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/eat-pray-ai/yutu/pkg"
|
|
"github.com/eat-pray-ai/yutu/pkg/common"
|
|
"google.golang.org/api/option"
|
|
"google.golang.org/api/youtube/v3"
|
|
)
|
|
|
|
func TestCaption_GetFields(t *testing.T) {
|
|
c := NewCaption().(*Caption)
|
|
if c.GetFields() == nil {
|
|
t.Error("Caption.GetFields() is nil")
|
|
}
|
|
}
|
|
|
|
func TestNewCaption(t *testing.T) {
|
|
type args struct {
|
|
opts []Option
|
|
}
|
|
|
|
svc := &youtube.Service{}
|
|
isAutoSyncedTrue := true
|
|
isAutoSyncedFalse := false
|
|
isCCTrue := true
|
|
isCCFalse := false
|
|
isDraftTrue := true
|
|
isDraftFalse := false
|
|
isEasyReaderTrue := true
|
|
isEasyReaderFalse := false
|
|
isLargeTrue := true
|
|
isLargeFalse := false
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want ICaption[youtube.Caption]
|
|
}{
|
|
{
|
|
name: "with all options",
|
|
args: args{
|
|
opts: []Option{
|
|
WithIds([]string{"caption1", "caption2"}),
|
|
WithFile("/path/to/file.srt"),
|
|
WithAudioTrackType("primary"),
|
|
WithIsAutoSynced(&isAutoSyncedTrue),
|
|
WithIsCC(&isCCTrue),
|
|
WithIsDraft(&isDraftTrue),
|
|
WithIsEasyReader(&isEasyReaderTrue),
|
|
WithIsLarge(&isLargeTrue),
|
|
WithLanguage("en"),
|
|
WithName("English Captions"),
|
|
WithTrackKind("standard"),
|
|
WithOnBehalfOf("channel123"),
|
|
WithOnBehalfOfContentOwner("owner123"),
|
|
WithVideoId("video123"),
|
|
WithTfmt("srt"),
|
|
WithTlang("es"),
|
|
WithService(svc),
|
|
},
|
|
},
|
|
want: &Caption{
|
|
Service: svc,
|
|
Ids: []string{"caption1", "caption2"},
|
|
OnBehalfOfContentOwner: "owner123",
|
|
File: "/path/to/file.srt",
|
|
AudioTrackType: "primary",
|
|
IsAutoSynced: &isAutoSyncedTrue,
|
|
IsCC: &isCCTrue,
|
|
IsDraft: &isDraftTrue,
|
|
IsEasyReader: &isEasyReaderTrue,
|
|
IsLarge: &isLargeTrue,
|
|
Language: "en",
|
|
Name: "English Captions",
|
|
TrackKind: "standard",
|
|
OnBehalfOf: "channel123",
|
|
VideoId: "video123",
|
|
Tfmt: "srt",
|
|
Tlang: "es",
|
|
},
|
|
},
|
|
{
|
|
name: "with no options",
|
|
args: args{
|
|
opts: []Option{},
|
|
},
|
|
want: &Caption{Fields: common.Fields{}},
|
|
},
|
|
{
|
|
name: "with nil boolean options",
|
|
args: args{
|
|
opts: []Option{
|
|
WithIsAutoSynced(nil),
|
|
WithIsCC(nil),
|
|
WithIsDraft(nil),
|
|
WithIsEasyReader(nil),
|
|
WithIsLarge(nil),
|
|
},
|
|
},
|
|
want: &Caption{Fields: common.Fields{}},
|
|
},
|
|
{
|
|
name: "with false boolean options",
|
|
args: args{
|
|
opts: []Option{
|
|
WithIsAutoSynced(&isAutoSyncedFalse),
|
|
WithIsCC(&isCCFalse),
|
|
WithIsDraft(&isDraftFalse),
|
|
WithIsEasyReader(&isEasyReaderFalse),
|
|
WithIsLarge(&isLargeFalse),
|
|
},
|
|
},
|
|
want: &Caption{
|
|
Fields: common.Fields{},
|
|
IsAutoSynced: &isAutoSyncedFalse,
|
|
IsCC: &isCCFalse,
|
|
IsDraft: &isDraftFalse,
|
|
IsEasyReader: &isEasyReaderFalse,
|
|
IsLarge: &isLargeFalse,
|
|
},
|
|
},
|
|
{
|
|
name: "with empty string values",
|
|
args: args{
|
|
opts: []Option{
|
|
WithFile(""),
|
|
WithAudioTrackType(""),
|
|
WithLanguage(""),
|
|
WithName(""),
|
|
WithTrackKind(""),
|
|
WithOnBehalfOf(""),
|
|
WithOnBehalfOfContentOwner(""),
|
|
WithVideoId(""),
|
|
WithTfmt(""),
|
|
WithTlang(""),
|
|
},
|
|
},
|
|
want: &Caption{
|
|
OnBehalfOfContentOwner: "",
|
|
File: "",
|
|
AudioTrackType: "",
|
|
Language: "",
|
|
Name: "",
|
|
TrackKind: "",
|
|
OnBehalfOf: "",
|
|
VideoId: "",
|
|
Tfmt: "",
|
|
Tlang: "",
|
|
},
|
|
},
|
|
{
|
|
name: "with partial options",
|
|
args: args{
|
|
opts: []Option{
|
|
WithIds([]string{"caption1"}),
|
|
WithLanguage("fr"),
|
|
WithVideoId("video456"),
|
|
WithIsCC(&isCCTrue),
|
|
},
|
|
},
|
|
want: &Caption{
|
|
Ids: []string{"caption1"},
|
|
Language: "fr",
|
|
VideoId: "video456",
|
|
IsCC: &isCCTrue,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
if got := NewCaption(tt.args.opts...); !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("%s\nNewCaption() = %v\nwant %v", tt.name, got, tt.want)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_Get(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
opts []Option
|
|
verify func(*http.Request)
|
|
wantLen int
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "get captions with videoId",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("videoId") != "video-id" {
|
|
t.Errorf(
|
|
"expected videoId=video-id, got %s", r.URL.Query().Get("videoId"),
|
|
)
|
|
}
|
|
},
|
|
wantLen: 2,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "get captions with ids",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithIds([]string{"id1", "id2"}),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
ids := r.URL.Query()["id"]
|
|
if len(ids) != 2 || ids[0] != "id1" || ids[1] != "id2" {
|
|
t.Errorf("expected id=[id1 id2], got %v", ids)
|
|
}
|
|
},
|
|
wantLen: 2,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "get captions with onBehalfOf",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithOnBehalfOf("channel-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOf") != "channel-id" {
|
|
t.Errorf(
|
|
"expected onBehalfOf=channel-id, got %s",
|
|
r.URL.Query().Get("onBehalfOf"),
|
|
)
|
|
}
|
|
},
|
|
wantLen: 2,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "get captions with onBehalfOfContentOwner",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithOnBehalfOfContentOwner("content-owner"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOfContentOwner") != "content-owner" {
|
|
t.Errorf(
|
|
"expected onBehalfOfContentOwner=content-owner, got %s",
|
|
r.URL.Query().Get("onBehalfOfContentOwner"),
|
|
)
|
|
}
|
|
},
|
|
wantLen: 2,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
svc := common.NewTestService(
|
|
t, http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.verify != nil {
|
|
tt.verify(r)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write(
|
|
[]byte(`{
|
|
"items": [
|
|
{"id": "1", "snippet": {"videoId": "video-id"}},
|
|
{"id": "2", "snippet": {"videoId": "video-id"}}
|
|
]
|
|
}`),
|
|
)
|
|
},
|
|
),
|
|
)
|
|
|
|
opts := append([]Option{WithService(svc)}, tt.opts...)
|
|
c := NewCaption(opts...)
|
|
got, err := c.Get()
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("Caption.Get() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if len(got) != tt.wantLen {
|
|
t.Errorf(
|
|
"Caption.Get() got length = %v, want %v", len(got), tt.wantLen,
|
|
)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_List(t *testing.T) {
|
|
common.RunListTest(
|
|
t,
|
|
`{"items": [{"id": "caption-1", "snippet": {"videoId": "video-1", "name": "English", "language": "en"}}]}`,
|
|
func(svc *youtube.Service, output string) func(io.Writer) error {
|
|
c := NewCaption(
|
|
WithService(svc),
|
|
WithOutput(output),
|
|
WithVideoId("video-1"),
|
|
)
|
|
return c.List
|
|
},
|
|
)
|
|
}
|
|
|
|
func TestCaption_Insert(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
opts []Option
|
|
verify func(*http.Request)
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "insert caption",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithLanguage("en"),
|
|
WithName("English"),
|
|
WithFile("test_caption.srt"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.Method != "POST" {
|
|
t.Errorf("expected POST, got %s", r.Method)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "insert caption with onBehalfOf",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithFile("test_caption.srt"),
|
|
WithOnBehalfOf("channel-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOf") != "channel-id" {
|
|
t.Errorf(
|
|
"expected onBehalfOf=channel-id, got %s",
|
|
r.URL.Query().Get("onBehalfOf"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "insert caption with onBehalfOfContentOwner",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithFile("test_caption.srt"),
|
|
WithOnBehalfOfContentOwner("content-owner"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOfContentOwner") != "content-owner" {
|
|
t.Errorf(
|
|
"expected onBehalfOfContentOwner=content-owner, got %s",
|
|
r.URL.Query().Get("onBehalfOfContentOwner"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
err := os.WriteFile(
|
|
"test_caption.srt", []byte("1\n00:00:01,000 --> 00:00:04,000\nHello"), 0644,
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("failed to create dummy file: %v", err)
|
|
}
|
|
defer func() {
|
|
_ = os.Remove("test_caption.srt")
|
|
}()
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
svc := common.NewTestService(
|
|
t, http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.verify != nil {
|
|
tt.verify(r)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{"id": "new-caption-id", "snippet": {"videoId": "video-id"}}`))
|
|
},
|
|
),
|
|
)
|
|
|
|
opts := append([]Option{WithService(svc)}, tt.opts...)
|
|
c := NewCaption(opts...)
|
|
var buf bytes.Buffer
|
|
if err := c.Insert(&buf); (err != nil) != tt.wantErr {
|
|
t.Errorf("Caption.Insert() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_Update(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
opts []Option
|
|
verify func(*http.Request)
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "update caption",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithIds([]string{"caption-id"}),
|
|
WithLanguage("es"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
switch r.Method {
|
|
case "PUT":
|
|
if r.URL.Query().Get("part") != "snippet" {
|
|
t.Errorf("expected part=snippet, got %s", r.URL.Query().Get("part"))
|
|
}
|
|
case "GET":
|
|
if r.URL.Query().Get("videoId") != "video-id" {
|
|
t.Errorf(
|
|
"expected videoId=video-id, got %s", r.URL.Query().Get("videoId"),
|
|
)
|
|
}
|
|
default:
|
|
t.Errorf("unexpected method %s", r.Method)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "update caption with onBehalfOf",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithIds([]string{"caption-id"}),
|
|
WithOnBehalfOf("channel-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.Method == "PUT" {
|
|
if r.URL.Query().Get("onBehalfOf") != "channel-id" {
|
|
t.Errorf(
|
|
"expected onBehalfOf=channel-id, got %s",
|
|
r.URL.Query().Get("onBehalfOf"),
|
|
)
|
|
}
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "update caption with onBehalfOfContentOwner",
|
|
opts: []Option{
|
|
WithVideoId("video-id"),
|
|
WithIds([]string{"caption-id"}),
|
|
WithOnBehalfOfContentOwner("content-owner"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.Method == "PUT" {
|
|
if r.URL.Query().Get("onBehalfOfContentOwner") != "content-owner" {
|
|
t.Errorf(
|
|
"expected onBehalfOfContentOwner=content-owner, got %s",
|
|
r.URL.Query().Get("onBehalfOfContentOwner"),
|
|
)
|
|
}
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
svc := common.NewTestService(
|
|
t, http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.verify != nil {
|
|
tt.verify(r)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if r.Method == "GET" {
|
|
_, _ = w.Write(
|
|
[]byte(`{
|
|
"items": [
|
|
{"id": "caption-id", "snippet": {"videoId": "video-id", "language": "en"}}
|
|
]
|
|
}`),
|
|
)
|
|
} else {
|
|
_, _ = w.Write([]byte(`{"id": "caption-id", "snippet": {"videoId": "video-id", "language": "es"}}`))
|
|
}
|
|
},
|
|
),
|
|
)
|
|
|
|
opts := append([]Option{WithService(svc)}, tt.opts...)
|
|
c := NewCaption(opts...)
|
|
var buf bytes.Buffer
|
|
if err := c.Update(&buf); (err != nil) != tt.wantErr {
|
|
t.Errorf("Caption.Update() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_Delete(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
opts []Option
|
|
verify func(*http.Request)
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "delete caption",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.Method != "DELETE" {
|
|
t.Errorf("expected DELETE, got %s", r.Method)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "delete caption with onBehalfOf",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithOnBehalfOf("channel-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOf") != "channel-id" {
|
|
t.Errorf(
|
|
"expected onBehalfOf=channel-id, got %s",
|
|
r.URL.Query().Get("onBehalfOf"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "delete caption with onBehalfOfContentOwner",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithOnBehalfOfContentOwner("content-owner"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOfContentOwner") != "content-owner" {
|
|
t.Errorf(
|
|
"expected onBehalfOfContentOwner=content-owner, got %s",
|
|
r.URL.Query().Get("onBehalfOfContentOwner"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
svc := common.NewTestService(
|
|
t, http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.verify != nil {
|
|
tt.verify(r)
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
},
|
|
),
|
|
)
|
|
|
|
opts := append([]Option{WithService(svc)}, tt.opts...)
|
|
c := NewCaption(opts...)
|
|
var buf bytes.Buffer
|
|
if err := c.Delete(&buf); (err != nil) != tt.wantErr {
|
|
t.Errorf("Caption.Delete() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_Download(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
opts []Option
|
|
verify func(*http.Request)
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "download caption",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithFile("downloaded.srt"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.Method != "GET" {
|
|
t.Errorf("expected GET, got %s", r.Method)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "download caption with tfmt",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithFile("downloaded.srt"),
|
|
WithTfmt("vtt"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("tfmt") != "vtt" {
|
|
t.Errorf("expected tfmt=vtt, got %s", r.URL.Query().Get("tfmt"))
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "download caption with tlang",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithFile("downloaded.srt"),
|
|
WithTlang("es"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("tlang") != "es" {
|
|
t.Errorf("expected tlang=es, got %s", r.URL.Query().Get("tlang"))
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "download caption with onBehalfOf",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithFile("downloaded.srt"),
|
|
WithOnBehalfOf("channel-id"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOf") != "channel-id" {
|
|
t.Errorf(
|
|
"expected onBehalfOf=channel-id, got %s",
|
|
r.URL.Query().Get("onBehalfOf"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "download caption with onBehalfOfContentOwner",
|
|
opts: []Option{
|
|
WithIds([]string{"caption-id"}),
|
|
WithFile("downloaded.srt"),
|
|
WithOnBehalfOfContentOwner("content-owner"),
|
|
},
|
|
verify: func(r *http.Request) {
|
|
if r.URL.Query().Get("onBehalfOfContentOwner") != "content-owner" {
|
|
t.Errorf(
|
|
"expected onBehalfOfContentOwner=content-owner, got %s",
|
|
r.URL.Query().Get("onBehalfOfContentOwner"),
|
|
)
|
|
}
|
|
},
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(
|
|
tt.name, func(t *testing.T) {
|
|
svc := common.NewTestService(
|
|
t, http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if tt.verify != nil {
|
|
tt.verify(r)
|
|
}
|
|
_, _ = w.Write([]byte("1\n00:00:01,000 --> 00:00:04,000\nDownloaded Caption"))
|
|
},
|
|
),
|
|
)
|
|
|
|
opts := append([]Option{WithService(svc)}, tt.opts...)
|
|
c := NewCaption(opts...)
|
|
var buf bytes.Buffer
|
|
if err := c.Download(&buf); (err != nil) != tt.wantErr {
|
|
t.Errorf("Caption.Download() error = %v, wantErr %v", err, tt.wantErr)
|
|
}
|
|
defer func() {
|
|
_ = os.Remove("downloaded.srt")
|
|
}()
|
|
},
|
|
)
|
|
}
|
|
}
|
|
|
|
func TestCaption_Insert_Error(t *testing.T) {
|
|
// Setup pkg.Root for file tests
|
|
tmpDir := t.TempDir()
|
|
f, err := os.OpenRoot(tmpDir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
oldRoot := pkg.Root
|
|
pkg.Root = f
|
|
defer func() { pkg.Root = oldRoot }()
|
|
defer func(f *os.Root) {
|
|
_ = f.Close()
|
|
}(f)
|
|
|
|
svc, _ := youtube.NewService(t.Context(), option.WithAPIKey("test"))
|
|
|
|
// Test: File open error
|
|
c := NewCaption(WithFile("non_existent.srt"), WithService(svc))
|
|
if err := c.Insert(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error for non-existent file, got nil")
|
|
}
|
|
|
|
// Test: API error
|
|
// Create dummy file
|
|
if err := os.WriteFile(
|
|
tmpDir+"/test.srt", []byte("content"), 0644,
|
|
); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
ts := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
},
|
|
),
|
|
)
|
|
defer ts.Close()
|
|
|
|
svc, _ = youtube.NewService(
|
|
t.Context(), option.WithEndpoint(ts.URL), option.WithAPIKey("test"),
|
|
)
|
|
c = NewCaption(WithFile("test.srt"), WithService(svc))
|
|
if err := c.Insert(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error from API, got nil")
|
|
}
|
|
}
|
|
|
|
func TestCaption_Update_Error(t *testing.T) {
|
|
// Setup pkg.Root
|
|
tmpDir := t.TempDir()
|
|
f, err := os.OpenRoot(tmpDir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
oldRoot := pkg.Root
|
|
pkg.Root = f
|
|
defer func() { pkg.Root = oldRoot }()
|
|
defer func(f *os.Root) {
|
|
_ = f.Close()
|
|
}(f)
|
|
|
|
// Test: File open error (when file is specified)
|
|
ts := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{"items": [{"id": "1", "snippet": {"videoId": "v1"}}]}`))
|
|
},
|
|
),
|
|
)
|
|
defer ts.Close()
|
|
svc, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(ts.URL), option.WithAPIKey("test"),
|
|
)
|
|
|
|
c := NewCaption(
|
|
WithFile("non_existent.srt"), WithService(svc), WithVideoId("v1"),
|
|
)
|
|
if err := c.Update(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error for non-existent file, got nil")
|
|
}
|
|
|
|
// Test: Get error
|
|
tsError := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
},
|
|
),
|
|
)
|
|
defer tsError.Close()
|
|
svcError, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(tsError.URL),
|
|
option.WithAPIKey("test"),
|
|
)
|
|
c = NewCaption(WithService(svcError), WithVideoId("v1"))
|
|
if err := c.Update(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error from Get, got nil")
|
|
}
|
|
|
|
// Test: No caption found
|
|
tsEmpty := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{"items": []}`))
|
|
},
|
|
),
|
|
)
|
|
defer tsEmpty.Close()
|
|
svcEmpty, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(tsEmpty.URL),
|
|
option.WithAPIKey("test"),
|
|
)
|
|
c = NewCaption(WithService(svcEmpty), WithVideoId("v1"))
|
|
if err := c.Update(&bytes.Buffer{}); !errors.Is(err, errGetCaption) {
|
|
t.Errorf("expected errGetCaption, got %v", err)
|
|
}
|
|
|
|
// Test: API Update Error
|
|
tsUpdateErr := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "GET" {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_, _ = w.Write([]byte(`{"items": [{"id": "1", "snippet": {"videoId": "v1"}}]}`))
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
},
|
|
),
|
|
)
|
|
defer tsUpdateErr.Close()
|
|
svcUpdateErr, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(tsUpdateErr.URL),
|
|
option.WithAPIKey("test"),
|
|
)
|
|
c = NewCaption(WithService(svcUpdateErr), WithVideoId("v1"))
|
|
if err := c.Update(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error from API Update, got nil")
|
|
}
|
|
}
|
|
|
|
func TestCaption_Delete_Error(t *testing.T) {
|
|
ts := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
},
|
|
),
|
|
)
|
|
defer ts.Close()
|
|
svc, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(ts.URL), option.WithAPIKey("test"),
|
|
)
|
|
|
|
c := NewCaption(WithService(svc), WithIds([]string{"id1"}))
|
|
if err := c.Delete(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error from Delete, got nil")
|
|
}
|
|
}
|
|
|
|
func TestCaption_Download_Error(t *testing.T) {
|
|
// Test API Error
|
|
ts := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
},
|
|
),
|
|
)
|
|
defer ts.Close()
|
|
svc, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(ts.URL), option.WithAPIKey("test"),
|
|
)
|
|
|
|
c := NewCaption(
|
|
WithService(svc), WithIds([]string{"id1"}), WithFile("out.srt"),
|
|
)
|
|
if err := c.Download(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error from Download API, got nil")
|
|
}
|
|
|
|
// Test File Creation Error
|
|
ts2 := httptest.NewServer(
|
|
http.HandlerFunc(
|
|
func(w http.ResponseWriter, r *http.Request) {
|
|
_, _ = w.Write([]byte("content"))
|
|
},
|
|
),
|
|
)
|
|
defer ts2.Close()
|
|
svc2, _ := youtube.NewService(
|
|
t.Context(), option.WithEndpoint(ts2.URL),
|
|
option.WithAPIKey("test"),
|
|
)
|
|
// Use a directory as file path to trigger error.
|
|
tmpDir := t.TempDir()
|
|
c = NewCaption(WithService(svc2), WithIds([]string{"id1"}), WithFile(tmpDir))
|
|
if err := c.Download(&bytes.Buffer{}); err == nil {
|
|
t.Error("expected error for file creation, got nil")
|
|
}
|
|
}
|