diff --git a/web/pkg/feeds/feeds_test.go b/web/pkg/feeds/feeds_test.go new file mode 100644 index 0000000..8ea73f5 --- /dev/null +++ b/web/pkg/feeds/feeds_test.go @@ -0,0 +1,73 @@ +//go:generate mockgen -source=interfaces.go -destination=interfaces_mock_test.go -package=feeds + +package feeds + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/mxpv/podsync/web/pkg/api" + "github.com/stretchr/testify/require" +) + +func TestService_CreateFeed(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + id := NewMockid(ctrl) + id.EXPECT().Generate(gomock.Any()).Times(1).Return("123", nil) + + storage := NewMockstorage(ctrl) + storage.EXPECT().CreateFeed(gomock.Any()).Times(1).Return(nil) + + s := service{ + id: id, + storage: storage, + builders: map[api.Provider]builder{api.Youtube: nil}, + } + + req := &api.CreateFeedRequest{ + URL: "youtube.com/channel/123", + PageSize: 50, + Quality: api.HighQuality, + Format: api.VideoFormat, + } + + hashId, err := s.CreateFeed(context.Background(), req) + require.NoError(t, err) + require.Equal(t, "123", hashId) +} + +func TestService_GetFeed(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + feed := &api.Feed{Provider: api.Youtube} + + storage := NewMockstorage(ctrl) + storage.EXPECT().GetFeed("123").Times(1).Return(feed, nil) + + bld := NewMockbuilder(ctrl) + bld.EXPECT().Build(feed).Return(nil, nil) + + s := service{ + storage: storage, + builders: map[api.Provider]builder{api.Youtube: bld}, + } + + _, err := s.GetFeed("123") + require.NoError(t, err) +} + +func TestService_GetMetadata(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + storage := NewMockstorage(ctrl) + storage.EXPECT().GetFeed("123").Times(1).Return(&api.Feed{}, nil) + + s := service{storage: storage} + _, err := s.GetMetadata("123") + require.NoError(t, err) +} diff --git a/web/pkg/feeds/interfaces_mock_test.go b/web/pkg/feeds/interfaces_mock_test.go new file mode 100644 index 0000000..4374c45 --- /dev/null +++ b/web/pkg/feeds/interfaces_mock_test.go @@ -0,0 +1,131 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: interfaces.go + +package feeds + +import ( + gomock "github.com/golang/mock/gomock" + podcast "github.com/mxpv/podcast" + api "github.com/mxpv/podsync/web/pkg/api" + reflect "reflect" +) + +// Mockid is a mock of id interface +type Mockid struct { + ctrl *gomock.Controller + recorder *MockidMockRecorder +} + +// MockidMockRecorder is the mock recorder for Mockid +type MockidMockRecorder struct { + mock *Mockid +} + +// NewMockid creates a new mock instance +func NewMockid(ctrl *gomock.Controller) *Mockid { + mock := &Mockid{ctrl: ctrl} + mock.recorder = &MockidMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *Mockid) EXPECT() *MockidMockRecorder { + return _m.recorder +} + +// Generate mocks base method +func (_m *Mockid) Generate(feed *api.Feed) (string, error) { + ret := _m.ctrl.Call(_m, "Generate", feed) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Generate indicates an expected call of Generate +func (_mr *MockidMockRecorder) Generate(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Generate", reflect.TypeOf((*Mockid)(nil).Generate), arg0) +} + +// Mockstorage is a mock of storage interface +type Mockstorage struct { + ctrl *gomock.Controller + recorder *MockstorageMockRecorder +} + +// MockstorageMockRecorder is the mock recorder for Mockstorage +type MockstorageMockRecorder struct { + mock *Mockstorage +} + +// NewMockstorage creates a new mock instance +func NewMockstorage(ctrl *gomock.Controller) *Mockstorage { + mock := &Mockstorage{ctrl: ctrl} + mock.recorder = &MockstorageMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *Mockstorage) EXPECT() *MockstorageMockRecorder { + return _m.recorder +} + +// CreateFeed mocks base method +func (_m *Mockstorage) CreateFeed(feed *api.Feed) error { + ret := _m.ctrl.Call(_m, "CreateFeed", feed) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateFeed indicates an expected call of CreateFeed +func (_mr *MockstorageMockRecorder) CreateFeed(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "CreateFeed", reflect.TypeOf((*Mockstorage)(nil).CreateFeed), arg0) +} + +// GetFeed mocks base method +func (_m *Mockstorage) GetFeed(hashId string) (*api.Feed, error) { + ret := _m.ctrl.Call(_m, "GetFeed", hashId) + ret0, _ := ret[0].(*api.Feed) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFeed indicates an expected call of GetFeed +func (_mr *MockstorageMockRecorder) GetFeed(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "GetFeed", reflect.TypeOf((*Mockstorage)(nil).GetFeed), arg0) +} + +// Mockbuilder is a mock of builder interface +type Mockbuilder struct { + ctrl *gomock.Controller + recorder *MockbuilderMockRecorder +} + +// MockbuilderMockRecorder is the mock recorder for Mockbuilder +type MockbuilderMockRecorder struct { + mock *Mockbuilder +} + +// NewMockbuilder creates a new mock instance +func NewMockbuilder(ctrl *gomock.Controller) *Mockbuilder { + mock := &Mockbuilder{ctrl: ctrl} + mock.recorder = &MockbuilderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (_m *Mockbuilder) EXPECT() *MockbuilderMockRecorder { + return _m.recorder +} + +// Build mocks base method +func (_m *Mockbuilder) Build(feed *api.Feed) (*podcast.Podcast, error) { + ret := _m.ctrl.Call(_m, "Build", feed) + ret0, _ := ret[0].(*podcast.Podcast) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Build indicates an expected call of Build +func (_mr *MockbuilderMockRecorder) Build(arg0 interface{}) *gomock.Call { + return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Build", reflect.TypeOf((*Mockbuilder)(nil).Build), arg0) +} diff --git a/web/pkg/feeds/url.go b/web/pkg/feeds/url.go index 9ae2d13..a658d1f 100644 --- a/web/pkg/feeds/url.go +++ b/web/pkg/feeds/url.go @@ -9,6 +9,10 @@ import ( ) func parseURL(link string) (*api.Feed, error) { + if !strings.HasPrefix(link, "http") { + link = "https://" + link + } + parsed, err := url.Parse(link) if err != nil { err = errors.Wrapf(err, "failed to parse url: %s", link) diff --git a/web/pkg/feeds/url_test.go b/web/pkg/feeds/url_test.go index bdcf518..10a2969 100644 --- a/web/pkg/feeds/url_test.go +++ b/web/pkg/feeds/url_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestParseYTPlaylist(t *testing.T) { +func TestParseYoutubeURL_Playlist(t *testing.T) { link, _ := url.ParseRequestURI("https://www.youtube.com/playlist?list=PLCB9F975ECF01953C") kind, id, err := parseYoutubeURL(link) require.NoError(t, err) @@ -16,7 +16,7 @@ func TestParseYTPlaylist(t *testing.T) { require.Equal(t, "PLCB9F975ECF01953C", id) } -func TestParseYTChannel(t *testing.T) { +func TestParseYoutubeURL_Channel(t *testing.T) { link, _ := url.ParseRequestURI("https://www.youtube.com/channel/UC5XPnUk8Vvv_pWslhwom6Og") kind, id, err := parseYoutubeURL(link) require.NoError(t, err) @@ -30,7 +30,7 @@ func TestParseYTChannel(t *testing.T) { require.Equal(t, "UCrlakW-ewUT8sOod6Wmzyow", id) } -func TestParseYTUser(t *testing.T) { +func TestParseYoutubeURL_User(t *testing.T) { link, _ := url.ParseRequestURI("https://youtube.com/user/fxigr1") kind, id, err := parseYoutubeURL(link) require.NoError(t, err) @@ -38,7 +38,7 @@ func TestParseYTUser(t *testing.T) { require.Equal(t, "fxigr1", id) } -func TestHandleInvalidYTLink(t *testing.T) { +func TestParseYoutubeURL_InvalidLink(t *testing.T) { link, _ := url.ParseRequestURI("https://www.youtube.com/user///") _, _, err := parseYoutubeURL(link) require.Error(t, err) @@ -48,7 +48,7 @@ func TestHandleInvalidYTLink(t *testing.T) { require.Error(t, err) } -func TestParseVimeoGroupLink(t *testing.T) { +func TestParseVimeoURL_Group(t *testing.T) { link, _ := url.ParseRequestURI("https://vimeo.com/groups/109") kind, id, err := parseVimeoURL(link) require.NoError(t, err) @@ -74,7 +74,7 @@ func TestParseVimeoGroupLink(t *testing.T) { require.Equal(t, "109", id) } -func TestParseVimeoChannelLink(t *testing.T) { +func TestParseVimeoURL_Channel(t *testing.T) { link, _ := url.ParseRequestURI("https://vimeo.com/channels/staffpicks") kind, id, err := parseVimeoURL(link) require.NoError(t, err) @@ -88,7 +88,7 @@ func TestParseVimeoChannelLink(t *testing.T) { require.Equal(t, "staffpicks", id) } -func TestParseVimeoUserLink(t *testing.T) { +func TestParseVimeoURL_User(t *testing.T) { link, _ := url.ParseRequestURI("https://vimeo.com/awhitelabelproduct") kind, id, err := parseVimeoURL(link) require.NoError(t, err) @@ -96,7 +96,7 @@ func TestParseVimeoUserLink(t *testing.T) { require.Equal(t, "awhitelabelproduct", id) } -func TestParseInvalidVimeoLink(t *testing.T) { +func TestParseVimeoURL_InvalidLink(t *testing.T) { link, _ := url.ParseRequestURI("http://www.apple.com") _, _, err := parseVimeoURL(link) require.Error(t, err) diff --git a/web/pkg/id/hashids.go b/web/pkg/id/hashids.go index d589fc9..0df931c 100644 --- a/web/pkg/id/hashids.go +++ b/web/pkg/id/hashids.go @@ -45,6 +45,9 @@ func NewIdGenerator() (*hashId, error) { data.MinLength = minLength data.Salt = salt data.Alphabet = alphabet - hid := hd.NewWithData(data) + hid, err := hd.NewWithData(data) + if err != nil { + return nil, err + } return &hashId{hid}, nil }