246 lines
14 KiB
Go
246 lines
14 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/metadata"
|
|
appv1 "stream.api/internal/api/proto/app/v1"
|
|
"stream.api/internal/database/model"
|
|
"stream.api/internal/middleware"
|
|
)
|
|
|
|
func testInternalMetadataContext() context.Context {
|
|
return metadata.NewOutgoingContext(context.Background(), metadata.Pairs(
|
|
middleware.ActorMarkerMetadataKey, testTrustedMarker,
|
|
))
|
|
}
|
|
|
|
func testInvalidInternalMetadataContext() context.Context {
|
|
return metadata.NewOutgoingContext(context.Background(), metadata.Pairs(
|
|
middleware.ActorMarkerMetadataKey, "wrong-marker",
|
|
))
|
|
}
|
|
|
|
func TestGetVideoMetadata(t *testing.T) {
|
|
t.Run("happy path with owner defaults", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
admin := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "admin@example.com", Role: ptrString("ADMIN")})
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "paid@example.com", Role: ptrString("USER"), PlanID: ptrString("plan-paid")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now, AdID: nil}
|
|
if err := db.Create(&video).Error; err != nil {
|
|
t.Fatalf("create video: %v", err)
|
|
}
|
|
if err := db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "video.example.com"}).Error; err != nil {
|
|
t.Fatalf("create domain: %v", err)
|
|
}
|
|
if err := db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: user.ID, Name: "default-ad", VastTagURL: "https://ads.example.com/vast", IsDefault: true, IsActive: ptrBool(true)}).Error; err != nil {
|
|
t.Fatalf("create ad template: %v", err)
|
|
}
|
|
if err := db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "banner", Label: "promo", Value: "https://ads.example.com/banner", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create popup ad: %v", err)
|
|
}
|
|
if err := db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: user.ID, Name: "default-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create player config: %v", err)
|
|
}
|
|
services := newTestAppServices(t, db)
|
|
_ = admin
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
resp, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
if err != nil {
|
|
t.Fatalf("GetVideoMetadata error = %v", err)
|
|
}
|
|
if resp.GetVideo().GetId() != video.ID {
|
|
t.Fatalf("video id = %q, want %q", resp.GetVideo().GetId(), video.ID)
|
|
}
|
|
if resp.GetAdTemplate().GetName() != "default-ad" {
|
|
t.Fatalf("ad template name = %q", resp.GetAdTemplate().GetName())
|
|
}
|
|
if resp.GetActivePopupAd().GetLabel() != "promo" {
|
|
t.Fatalf("popup label = %q", resp.GetActivePopupAd().GetLabel())
|
|
}
|
|
if resp.GetDefaultPlayerConfig().GetName() != "default-player" {
|
|
t.Fatalf("player config name = %q", resp.GetDefaultPlayerConfig().GetName())
|
|
}
|
|
if len(resp.GetDomains()) != 1 {
|
|
t.Fatalf("domains len = %d, want 1", len(resp.GetDomains()))
|
|
}
|
|
})
|
|
|
|
t.Run("missing ad template returns failed precondition", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "paid@example.com", Role: ptrString("USER"), PlanID: ptrString("plan-paid")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now}
|
|
_ = db.Create(&video).Error
|
|
_ = db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "video.example.com"}).Error
|
|
_ = db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "banner", Label: "promo", Value: "https://ads.example.com/banner", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
_ = db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: user.ID, Name: "default-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
assertGRPCCode(t, err, codes.FailedPrecondition)
|
|
})
|
|
|
|
t.Run("missing popup ad returns failed precondition", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "paid@example.com", Role: ptrString("USER"), PlanID: ptrString("plan-paid")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now}
|
|
_ = db.Create(&video).Error
|
|
_ = db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "video.example.com"}).Error
|
|
_ = db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: user.ID, Name: "default-ad", VastTagURL: "https://ads.example.com/vast", IsDefault: true, IsActive: ptrBool(true)}).Error
|
|
_ = db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: user.ID, Name: "default-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
assertGRPCCode(t, err, codes.FailedPrecondition)
|
|
})
|
|
|
|
t.Run("missing player config returns failed precondition", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "paid@example.com", Role: ptrString("USER"), PlanID: ptrString("plan-paid")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now}
|
|
_ = db.Create(&video).Error
|
|
_ = db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "video.example.com"}).Error
|
|
_ = db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: user.ID, Name: "default-ad", VastTagURL: "https://ads.example.com/vast", IsDefault: true, IsActive: ptrBool(true)}).Error
|
|
_ = db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "banner", Label: "promo", Value: "https://ads.example.com/banner", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
assertGRPCCode(t, err, codes.FailedPrecondition)
|
|
})
|
|
|
|
t.Run("missing domains returns failed precondition", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "paid@example.com", Role: ptrString("USER"), PlanID: ptrString("plan-paid")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now}
|
|
_ = db.Create(&video).Error
|
|
_ = db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: user.ID, Name: "default-ad", VastTagURL: "https://ads.example.com/vast", IsDefault: true, IsActive: ptrBool(true)}).Error
|
|
_ = db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: user.ID, Type: "banner", Label: "promo", Value: "https://ads.example.com/banner", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
_ = db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: user.ID, Name: "default-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
assertGRPCCode(t, err, codes.FailedPrecondition)
|
|
})
|
|
|
|
t.Run("free user falls back to system admin config", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
admin := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "admin@example.com", Role: ptrString("ADMIN")})
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "free@example.com", Role: ptrString("USER")})
|
|
now := time.Now().UTC()
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now}
|
|
if err := db.Create(&video).Error; err != nil {
|
|
t.Fatalf("create video: %v", err)
|
|
}
|
|
if err := db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "free.example.com"}).Error; err != nil {
|
|
t.Fatalf("create domain: %v", err)
|
|
}
|
|
if err := db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: admin.ID, Name: "system-ad", VastTagURL: "https://ads.example.com/system", IsDefault: true, IsActive: ptrBool(true)}).Error; err != nil {
|
|
t.Fatalf("create system ad template: %v", err)
|
|
}
|
|
if err := db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: admin.ID, Type: "banner", Label: "system-popup", Value: "https://ads.example.com/system-popup", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create system popup ad: %v", err)
|
|
}
|
|
if err := db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: admin.ID, Name: "system-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create system player config: %v", err)
|
|
}
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
resp, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
if err != nil {
|
|
t.Fatalf("GetVideoMetadata error = %v", err)
|
|
}
|
|
if resp.GetAdTemplate().GetName() != "system-ad" {
|
|
t.Fatalf("ad template = %q, want system-ad", resp.GetAdTemplate().GetName())
|
|
}
|
|
if resp.GetActivePopupAd().GetLabel() != "system-popup" {
|
|
t.Fatalf("popup label = %q, want system-popup", resp.GetActivePopupAd().GetLabel())
|
|
}
|
|
if resp.GetDefaultPlayerConfig().GetName() != "system-player" {
|
|
t.Fatalf("player config = %q, want system-player", resp.GetDefaultPlayerConfig().GetName())
|
|
}
|
|
if len(resp.GetDomains()) != 1 || resp.GetDomains()[0].GetName() != "free.example.com" {
|
|
t.Fatalf("domains = %#v, want owner domains", resp.GetDomains())
|
|
}
|
|
})
|
|
|
|
t.Run("video ad id takes precedence over fallback ad template", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
admin := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "admin@example.com", Role: ptrString("ADMIN")})
|
|
user := seedTestUser(t, db, model.User{ID: uuid.NewString(), Email: "free@example.com", Role: ptrString("USER")})
|
|
now := time.Now().UTC()
|
|
videoAd := model.AdTemplate{ID: uuid.NewString(), UserID: user.ID, Name: "video-ad", VastTagURL: "https://ads.example.com/video", IsDefault: false, IsActive: ptrBool(true)}
|
|
if err := db.Create(&videoAd).Error; err != nil {
|
|
t.Fatalf("create video ad template: %v", err)
|
|
}
|
|
video := model.Video{ID: uuid.NewString(), UserID: user.ID, Title: "video", URL: "https://cdn.example.com/video.mp4", Status: ptrString("ready"), CreatedAt: &now, UpdatedAt: now, AdID: &videoAd.ID}
|
|
if err := db.Create(&video).Error; err != nil {
|
|
t.Fatalf("create video: %v", err)
|
|
}
|
|
if err := db.Create(&model.Domain{ID: uuid.NewString(), UserID: user.ID, Name: "free.example.com"}).Error; err != nil {
|
|
t.Fatalf("create domain: %v", err)
|
|
}
|
|
if err := db.Create(&model.AdTemplate{ID: uuid.NewString(), UserID: admin.ID, Name: "system-ad", VastTagURL: "https://ads.example.com/system", IsDefault: true, IsActive: ptrBool(true)}).Error; err != nil {
|
|
t.Fatalf("create system ad template: %v", err)
|
|
}
|
|
if err := db.Create(&model.PopupAd{ID: uuid.NewString(), UserID: admin.ID, Type: "banner", Label: "system-popup", Value: "https://ads.example.com/system-popup", IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create system popup ad: %v", err)
|
|
}
|
|
if err := db.Create(&model.PlayerConfig{ID: uuid.NewString(), UserID: admin.ID, Name: "system-player", IsDefault: true, IsActive: ptrBool(true), CreatedAt: &now, UpdatedAt: now}).Error; err != nil {
|
|
t.Fatalf("create system player config: %v", err)
|
|
}
|
|
services := newTestAppServices(t, db)
|
|
_ = admin
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
resp, err := client.GetVideoMetadata(testInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: video.ID})
|
|
if err != nil {
|
|
t.Fatalf("GetVideoMetadata error = %v", err)
|
|
}
|
|
if resp.GetAdTemplate().GetName() != "video-ad" {
|
|
t.Fatalf("ad template = %q, want video-ad", resp.GetAdTemplate().GetName())
|
|
}
|
|
})
|
|
|
|
t.Run("invalid marker returns unauthenticated", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(testInvalidInternalMetadataContext(), &appv1.GetVideoMetadataRequest{VideoId: uuid.NewString()})
|
|
assertGRPCCode(t, err, codes.Unauthenticated)
|
|
})
|
|
|
|
t.Run("missing marker returns unauthenticated", func(t *testing.T) {
|
|
db := newTestDB(t)
|
|
services := newTestAppServices(t, db)
|
|
conn, cleanup := newTestGRPCServer(t, services)
|
|
defer cleanup()
|
|
client := newVideoMetadataClient(conn)
|
|
_, err := client.GetVideoMetadata(context.Background(), &appv1.GetVideoMetadataRequest{VideoId: uuid.NewString()})
|
|
assertGRPCCode(t, err, codes.Unauthenticated)
|
|
})
|
|
}
|