mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-02-25 18:55:32 -06:00
Add notification on subscription live stream
This commit is contained in:
@@ -34,7 +34,9 @@ export const UserNotificationType = {
|
||||
|
||||
MY_VIDEO_STUDIO_EDITION_FINISHED: 19,
|
||||
|
||||
NEW_USER_REGISTRATION_REQUEST: 20
|
||||
NEW_USER_REGISTRATION_REQUEST: 20,
|
||||
|
||||
NEW_LIVE_FROM_SUBSCRIPTION: 21
|
||||
} as const
|
||||
|
||||
export type UserNotificationType_Type = typeof UserNotificationType[keyof typeof UserNotificationType]
|
||||
|
||||
@@ -119,12 +119,13 @@ export class LiveCommand extends AbstractCommand {
|
||||
}
|
||||
|
||||
async quickCreate (options: OverrideCommandOptions & {
|
||||
name: string
|
||||
saveReplay: boolean
|
||||
permanentLive: boolean
|
||||
privacy?: VideoPrivacyType
|
||||
videoPasswords?: string[]
|
||||
}) {
|
||||
const { saveReplay, permanentLive, privacy = VideoPrivacy.PUBLIC, videoPasswords } = options
|
||||
const { name = 'live', saveReplay, permanentLive, privacy = VideoPrivacy.PUBLIC, videoPasswords } = options
|
||||
|
||||
const replaySettings = privacy === VideoPrivacy.PASSWORD_PROTECTED
|
||||
? { privacy: VideoPrivacy.PRIVATE }
|
||||
@@ -134,7 +135,7 @@ export class LiveCommand extends AbstractCommand {
|
||||
...options,
|
||||
|
||||
fields: {
|
||||
name: 'live',
|
||||
name,
|
||||
permanentLive,
|
||||
saveReplay,
|
||||
replaySettings,
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
checkNewInstanceFollower,
|
||||
checkAutoInstanceFollowing,
|
||||
checkVideoAutoBlacklistForModerators,
|
||||
checkVideoIsPublished,
|
||||
checkMyVideoIsPublished,
|
||||
checkNewVideoFromSubscription
|
||||
} from '@tests/shared/notifications.js'
|
||||
|
||||
@@ -487,7 +487,7 @@ describe('Test moderation notifications', function () {
|
||||
it('Should not send video publish notification if auto-blacklisted', async function () {
|
||||
this.timeout(120000)
|
||||
|
||||
await checkVideoIsPublished({ ...userBaseParams, videoName, shortUUID, checkType: 'absence' })
|
||||
await checkMyVideoIsPublished({ ...userBaseParams, videoName, shortUUID, checkType: 'absence' })
|
||||
})
|
||||
|
||||
it('Should not send a local user subscription notification if auto-blacklisted', async function () {
|
||||
@@ -576,7 +576,7 @@ describe('Test moderation notifications', function () {
|
||||
const { shortUUID } = await servers[0].videos.upload({ token: userToken1, attributes })
|
||||
|
||||
await wait(6000)
|
||||
await checkVideoIsPublished({ ...userBaseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
await checkMyVideoIsPublished({ ...userBaseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
await checkNewVideoFromSubscription({ ...adminBaseParamsServer1, videoName: name, shortUUID, checkType: 'absence' })
|
||||
await checkNewVideoFromSubscription({ ...adminBaseParamsServer2, videoName: name, shortUUID, checkType: 'absence' })
|
||||
})
|
||||
|
||||
@@ -10,10 +10,12 @@ import {
|
||||
prepareNotificationsTest,
|
||||
CheckerBaseParams,
|
||||
checkNewVideoFromSubscription,
|
||||
checkVideoIsPublished,
|
||||
checkMyVideoIsPublished,
|
||||
checkVideoStudioEditionIsFinished,
|
||||
checkMyVideoImportIsFinished,
|
||||
checkNewActorFollow
|
||||
checkNewActorFollow,
|
||||
checkNewLiveFromSubscription,
|
||||
waitUntilNotification
|
||||
} from '@tests/shared/notifications.js'
|
||||
import { FIXTURE_URLS } from '@tests/shared/tests.js'
|
||||
import { uploadRandomVideoOnServers } from '@tests/shared/videos.js'
|
||||
@@ -209,6 +211,82 @@ describe('Test user notifications', function () {
|
||||
|
||||
await checkNewVideoFromSubscription({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('New live from my subscription notification', function () {
|
||||
let baseParams: CheckerBaseParams
|
||||
|
||||
async function createAndStreamLive (server: PeerTubeServer) {
|
||||
const name = 'video live ' + buildUUID()
|
||||
|
||||
const streamDate = new Date()
|
||||
const { video } = await server.live.quickCreate({ name, permanentLive: true, saveReplay: false })
|
||||
await waitJobs(servers)
|
||||
|
||||
const ffmpegCommand = await server.live.sendRTMPStreamInVideo({ videoId: video.uuid })
|
||||
|
||||
return { name, video, ffmpegCommand, streamDate }
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
baseParams = {
|
||||
server: servers[0],
|
||||
emails,
|
||||
socketNotifications: userNotifications,
|
||||
token: userAccessToken
|
||||
}
|
||||
|
||||
await servers[0].config.enableLive({ allowReplay: false })
|
||||
|
||||
await servers[0].subscriptions.add({ token: userAccessToken, targetUri: 'root_channel@' + servers[0].host })
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should not send a notification when a live is created', async function () {
|
||||
this.timeout(100000)
|
||||
|
||||
const name = 'video live ' + buildUUID()
|
||||
|
||||
const { video } = await servers[0].live.quickCreate({ name, permanentLive: true, saveReplay: false })
|
||||
await waitJobs(servers)
|
||||
await checkNewLiveFromSubscription({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'absence' })
|
||||
})
|
||||
|
||||
it('Should send a local notification when streaming in the live', async function () {
|
||||
this.timeout(100000)
|
||||
|
||||
const { name, video, ffmpegCommand, streamDate } = await createAndStreamLive(servers[0])
|
||||
|
||||
await waitUntilNotification({
|
||||
server: servers[0],
|
||||
token: userAccessToken,
|
||||
notificationType: UserNotificationType.NEW_LIVE_FROM_SUBSCRIPTION,
|
||||
fromDate: streamDate
|
||||
})
|
||||
|
||||
await checkNewLiveFromSubscription({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
|
||||
await stopFfmpeg(ffmpegCommand)
|
||||
await waitJobs(servers)
|
||||
})
|
||||
|
||||
it('Should send a remote notification when streaming in the live ', async function () {
|
||||
this.timeout(100000)
|
||||
|
||||
const { name, video, ffmpegCommand, streamDate } = await createAndStreamLive(servers[1])
|
||||
|
||||
await waitUntilNotification({
|
||||
server: servers[0],
|
||||
token: userAccessToken,
|
||||
notificationType: UserNotificationType.NEW_LIVE_FROM_SUBSCRIPTION,
|
||||
fromDate: streamDate
|
||||
})
|
||||
await checkNewLiveFromSubscription({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
|
||||
await stopFfmpeg(ffmpegCommand)
|
||||
await waitJobs(servers)
|
||||
})
|
||||
})
|
||||
|
||||
describe('My video is published', function () {
|
||||
@@ -229,7 +307,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 1)
|
||||
await waitJobs(servers)
|
||||
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
})
|
||||
|
||||
it('Should not send a notification if the wait transcoding is false', async function () {
|
||||
@@ -250,7 +328,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true, fixture: 'video_short_240p.mp4' })
|
||||
await waitJobs(servers)
|
||||
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
it('Should send a notification with a transcoded video', async function () {
|
||||
@@ -259,7 +337,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true })
|
||||
await waitJobs(servers)
|
||||
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
it('Should send a notification when an imported video is transcoded', async function () {
|
||||
@@ -277,7 +355,7 @@ describe('Test user notifications', function () {
|
||||
const { video } = await servers[1].imports.importVideo({ attributes })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
it('Should send a notification when the scheduled update has been proceeded', async function () {
|
||||
@@ -296,7 +374,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
|
||||
|
||||
await wait(6000)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
it('Should not send a notification before the video is published', async function () {
|
||||
@@ -314,7 +392,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID } = await uploadRandomVideoOnServers(servers, 2, data)
|
||||
|
||||
await wait(6000)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'absence' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -354,7 +432,7 @@ describe('Test user notifications', function () {
|
||||
await servers[1].live.waitUntilReplacedByReplay({ videoId: shortUUID })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: 'non permanent live', shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: 'non permanent live', shortUUID, checkType: 'presence' })
|
||||
})
|
||||
|
||||
it('Should send a notification is a live replay of a permanent live is published', async function () {
|
||||
@@ -386,7 +464,7 @@ describe('Test user notifications', function () {
|
||||
const video = await findExternalSavedVideo(servers[1], liveDetails)
|
||||
expect(video).to.exist
|
||||
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: video.name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: video.name, shortUUID: video.shortUUID, checkType: 'presence' })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -408,7 +486,7 @@ describe('Test user notifications', function () {
|
||||
const { name, shortUUID, id } = await uploadRandomVideoOnServers(servers, 2, { waitTranscoding: true })
|
||||
|
||||
await waitJobs(servers)
|
||||
await checkVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
await checkMyVideoIsPublished({ ...baseParams, videoName: name, shortUUID, checkType: 'presence' })
|
||||
|
||||
const tasks: VideoStudioTask[] = [
|
||||
{
|
||||
|
||||
@@ -7,7 +7,8 @@ import {
|
||||
UserNotification,
|
||||
UserNotificationSetting,
|
||||
UserNotificationSettingValue,
|
||||
UserNotificationType
|
||||
UserNotificationType,
|
||||
UserNotificationType_Type
|
||||
} from '@peertube/peertube-models'
|
||||
import {
|
||||
ConfigCommand,
|
||||
@@ -17,11 +18,13 @@ import {
|
||||
setAccessTokensToServers,
|
||||
setDefaultAccountAvatar,
|
||||
setDefaultChannelAvatar,
|
||||
setDefaultVideoChannel
|
||||
setDefaultVideoChannel,
|
||||
waitJobs
|
||||
} from '@peertube/peertube-server-commands'
|
||||
import { expect } from 'chai'
|
||||
import { inspect } from 'util'
|
||||
import { MockSmtpServer } from './mock-servers/index.js'
|
||||
import { wait } from '@peertube/peertube-core-utils'
|
||||
|
||||
type CheckerBaseParams = {
|
||||
server: PeerTubeServer
|
||||
@@ -55,6 +58,24 @@ function getAllNotificationsSettings (): UserNotificationSetting {
|
||||
}
|
||||
}
|
||||
|
||||
async function waitUntilNotification (options: {
|
||||
server: PeerTubeServer
|
||||
notificationType: UserNotificationType_Type
|
||||
token: string
|
||||
fromDate: Date
|
||||
}) {
|
||||
const { server, fromDate, notificationType, token } = options
|
||||
|
||||
do {
|
||||
const { data } = await server.notifications.list({ start: 0, count: 5, token })
|
||||
if (data.some(n => n.type === notificationType && new Date(n.createdAt) >= fromDate)) break
|
||||
|
||||
await wait(500)
|
||||
} while (true)
|
||||
|
||||
await waitJobs([ server ])
|
||||
}
|
||||
|
||||
async function checkNewVideoFromSubscription (options: CheckerBaseParams & {
|
||||
videoName: string
|
||||
shortUUID: string
|
||||
@@ -85,7 +106,37 @@ async function checkNewVideoFromSubscription (options: CheckerBaseParams & {
|
||||
await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
|
||||
}
|
||||
|
||||
async function checkVideoIsPublished (options: CheckerBaseParams & {
|
||||
async function checkNewLiveFromSubscription (options: CheckerBaseParams & {
|
||||
videoName: string
|
||||
shortUUID: string
|
||||
checkType: CheckerType
|
||||
}) {
|
||||
const { videoName, shortUUID } = options
|
||||
const notificationType = UserNotificationType.NEW_LIVE_FROM_SUBSCRIPTION
|
||||
|
||||
function notificationChecker (notification: UserNotification, checkType: CheckerType) {
|
||||
if (checkType === 'presence') {
|
||||
expect(notification).to.not.be.undefined
|
||||
expect(notification.type).to.equal(notificationType)
|
||||
|
||||
checkVideo(notification.video, videoName, shortUUID)
|
||||
checkActor(notification.video.channel)
|
||||
} else {
|
||||
expect(notification).to.satisfy((n: UserNotification) => {
|
||||
return n === undefined || n.type !== UserNotificationType.NEW_LIVE_FROM_SUBSCRIPTION || n.video.name !== videoName
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function emailNotificationFinder (email: object) {
|
||||
const text = email['text']
|
||||
return text.indexOf(shortUUID) !== -1 && text.indexOf('Your subscription') !== -1
|
||||
}
|
||||
|
||||
await checkNotification({ ...options, notificationChecker, emailNotificationFinder })
|
||||
}
|
||||
|
||||
async function checkMyVideoIsPublished (options: CheckerBaseParams & {
|
||||
videoName: string
|
||||
shortUUID: string
|
||||
checkType: CheckerType
|
||||
@@ -780,10 +831,13 @@ export {
|
||||
|
||||
getAllNotificationsSettings,
|
||||
|
||||
waitUntilNotification,
|
||||
|
||||
checkMyVideoImportIsFinished,
|
||||
checkUserRegistered,
|
||||
checkAutoInstanceFollowing,
|
||||
checkVideoIsPublished,
|
||||
checkMyVideoIsPublished,
|
||||
checkNewLiveFromSubscription,
|
||||
checkNewVideoFromSubscription,
|
||||
checkNewActorFollow,
|
||||
checkNewCommentOnMyVideo,
|
||||
@@ -841,10 +895,9 @@ async function checkNotification (options: CheckerBaseParams & {
|
||||
|
||||
if (check.mail) {
|
||||
// Last email
|
||||
const email = emails
|
||||
.slice()
|
||||
.reverse()
|
||||
.find(e => emailNotificationFinder(e))
|
||||
const email = emails.slice()
|
||||
.reverse()
|
||||
.find(e => emailNotificationFinder(e))
|
||||
|
||||
if (checkType === 'presence') {
|
||||
const texts = emails.map(e => e.text)
|
||||
|
||||
Reference in New Issue
Block a user