feat: 实现媒体播放功能,支持本地文件和重定向,添加相关测试用例
This commit is contained in:
112
backend/app/services/media_delivery_test.go
Normal file
112
backend/app/services/media_delivery_test.go
Normal file
@@ -0,0 +1,112 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"quyun/v2/app/commands/testx"
|
||||
"quyun/v2/database"
|
||||
"quyun/v2/database/models"
|
||||
"quyun/v2/pkg/consts"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
_ "go.ipao.vip/atom"
|
||||
"go.ipao.vip/atom/contracts"
|
||||
"go.ipao.vip/gen/types"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type MediaDeliveryTestSuiteInjectParams struct {
|
||||
dig.In
|
||||
|
||||
DB *sql.DB
|
||||
Initials []contracts.Initial `group:"initials"` // nolint:structcheck
|
||||
}
|
||||
|
||||
type MediaDeliveryTestSuite struct {
|
||||
suite.Suite
|
||||
MediaDeliveryTestSuiteInjectParams
|
||||
}
|
||||
|
||||
func Test_MediaDelivery(t *testing.T) {
|
||||
providers := testx.Default().With(Provide)
|
||||
|
||||
testx.Serve(providers, t, func(p MediaDeliveryTestSuiteInjectParams) {
|
||||
suite.Run(t, &MediaDeliveryTestSuite{MediaDeliveryTestSuiteInjectParams: p})
|
||||
})
|
||||
}
|
||||
|
||||
func (s *MediaDeliveryTestSuite) Test_ResolvePlay_LocalFile() {
|
||||
Convey("MediaDelivery.ResolvePlay local provider", s.T(), func() {
|
||||
ctx := s.T().Context()
|
||||
now := time.Now().UTC()
|
||||
tenantID := int64(1)
|
||||
viewerUserID := int64(2)
|
||||
|
||||
database.Truncate(ctx, s.DB, models.TableNameContentAsset, models.TableNameMediaAsset, models.TableNameContent)
|
||||
|
||||
content := &models.Content{
|
||||
TenantID: tenantID,
|
||||
UserID: viewerUserID,
|
||||
Title: "t",
|
||||
Description: "",
|
||||
Status: consts.ContentStatusPublished,
|
||||
Visibility: consts.ContentVisibilityPublic,
|
||||
PreviewSeconds: 60,
|
||||
PreviewDownloadable: false,
|
||||
PublishedAt: now,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
So(content.Create(ctx), ShouldBeNil)
|
||||
|
||||
objectKey := "tenants/1/users/2/video/test.bin"
|
||||
asset := &models.MediaAsset{
|
||||
TenantID: tenantID,
|
||||
UserID: viewerUserID,
|
||||
Type: consts.MediaAssetTypeVideo,
|
||||
Status: consts.MediaAssetStatusReady,
|
||||
Provider: "local",
|
||||
Bucket: "",
|
||||
ObjectKey: objectKey,
|
||||
Meta: types.JSON([]byte(`{"content_type":"application/octet-stream"}`)),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
So(asset.Create(ctx), ShouldBeNil)
|
||||
|
||||
binding := &models.ContentAsset{
|
||||
TenantID: tenantID,
|
||||
UserID: viewerUserID,
|
||||
ContentID: content.ID,
|
||||
AssetID: asset.ID,
|
||||
Role: consts.ContentAssetRolePreview,
|
||||
Sort: 1,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
So(binding.Create(ctx), ShouldBeNil)
|
||||
|
||||
root := s.T().TempDir()
|
||||
So(os.Setenv(envLocalMediaRoot, root), ShouldBeNil)
|
||||
defer os.Unsetenv(envLocalMediaRoot)
|
||||
|
||||
fullPath := filepath.Join(root, filepath.FromSlash(objectKey))
|
||||
So(os.MkdirAll(filepath.Dir(fullPath), 0o755), ShouldBeNil)
|
||||
So(os.WriteFile(fullPath, []byte("hello"), 0o644), ShouldBeNil)
|
||||
|
||||
token, _, err := MediaDelivery.CreatePlayToken(tenantID, content.ID, asset.ID, consts.ContentAssetRolePreview, viewerUserID, 0, now)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
res, err := MediaDelivery.ResolvePlay(ctx, tenantID, token)
|
||||
So(err, ShouldBeNil)
|
||||
So(res.Kind, ShouldEqual, MediaPlayResolutionKindLocalFile)
|
||||
So(res.LocalFilePath, ShouldEqual, fullPath)
|
||||
So(res.ContentType, ShouldEqual, "application/octet-stream")
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user