mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-19 19:51:20 -08:00
fix(vast): [PKG-VAST-03] preserve npm initialization with explicit workspace mode
This commit is contained in:
1 parent
314a1c3163
commit
c162d2b3b3
27 files changed
+13189
-191
No files matched your search
@@ -0,0 +1,181 @@
|
||||
import assert from 'node:assert/strict'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Published and candidate callback contracts use controlled SDKs.
|
||||
import test from 'node:test'
|
||||
import { deferred, vastEnvironment, vastImplementations } from './helpers/vast.js'
|
||||
|
||||
const implementations = await vastImplementations()
|
||||
const source = implementations.find(item => item.name === 'source')
|
||||
|
||||
for (const implementation of implementations.filter(item => item.name === 'source' || item.published)) {
|
||||
test(`${implementation.name}: npm callback receives an allocated SDK and original data fields without changing SDK defaults`, async () => {
|
||||
const env = vastEnvironment(implementation)
|
||||
const host = env.host()
|
||||
let context
|
||||
await env.factory((value) => {
|
||||
context = value
|
||||
assert.equal(env.state.players.length, 1)
|
||||
assert.equal(value.imaPlayer, env.state.players[0])
|
||||
assert.equal(value.$container, host.parent.children[0])
|
||||
assert.equal(value.id, value.$container.id)
|
||||
assert.match(value.id, /^art-\d/)
|
||||
value.imaPlayer.addEventListener('custom', () => {})
|
||||
for (const key of ['imaPlayer', 'id', '$container']) {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(value, key)
|
||||
assert.equal(descriptor.get, undefined)
|
||||
assert.equal(descriptor.writable, true)
|
||||
assert.equal(descriptor.enumerable, true)
|
||||
assert.equal(descriptor.configurable, true)
|
||||
}
|
||||
})(host.art)
|
||||
const player = env.state.players[0]
|
||||
assert.equal(player.args[3].enablePreloading, undefined)
|
||||
assert.equal(player.args[3].restoreCustomPlaybackStateOnAdBreakComplete, undefined)
|
||||
assert.equal(context.$container.style.backgroundColor, undefined)
|
||||
assert.equal(context.$container.style.pointerEvents, undefined)
|
||||
context.playUrl('/first.xml')
|
||||
player.emit('AdStarted')
|
||||
context.playUrl('/second.xml')
|
||||
assert.equal(player.requests.length, 2, 'The published wrapper forwards both explicit requests')
|
||||
})
|
||||
}
|
||||
|
||||
test('VAST explicit workspace mode retains lazy initialization and caller option identities', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
const host = env.host()
|
||||
let context
|
||||
await env.factory((value) => {
|
||||
context = value
|
||||
assert.equal(value.imaPlayer, null)
|
||||
assert.equal(value.container, null)
|
||||
assert.equal(env.state.players.length, 0)
|
||||
value.playerOptions.custom = 'before initialization'
|
||||
}, { compatibility: 'workspace-1.2' })(host.art)
|
||||
const player = context.init()
|
||||
assert.equal(player.args[3], context.adsRenderingSettings)
|
||||
assert.equal(player.args[4], context.playerOptions)
|
||||
assert.equal(player.args[4].custom, 'before initialization')
|
||||
assert.equal(player.args[3].enablePreloading, true)
|
||||
assert.equal(player.args[3].restoreCustomPlaybackStateOnAdBreakComplete, true)
|
||||
assert.match(context.container.id, /^art-vast-/)
|
||||
context.playUrl('/first.xml')
|
||||
player.emit('AdStarted')
|
||||
context.playUrl('/suppressed.xml')
|
||||
assert.equal(player.requests.length, 1)
|
||||
host.art.destroy()
|
||||
assert.equal(player.destroyCalls, 1)
|
||||
assert.equal(context.imaPlayer, null)
|
||||
})
|
||||
|
||||
test('VAST default initializes even without a callback and releases on core destruction', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
const host = env.host()
|
||||
await env.factory()(host.art)
|
||||
assert.equal(env.state.players.length, 1)
|
||||
host.art.destroy()
|
||||
assert.equal(env.state.players[0].destroyCalls, 1)
|
||||
assert.equal(host.parent.children.length, 0)
|
||||
})
|
||||
|
||||
test('VAST eager constructor failure rejects registration before callback and removes owned DOM', async () => {
|
||||
const failure = new Error('eager allocation failed')
|
||||
const env = vastEnvironment(source, { constructError: failure })
|
||||
const host = env.host()
|
||||
let called = false
|
||||
await assert.rejects(env.factory(() => {
|
||||
called = true
|
||||
})(host.art), error => error === failure)
|
||||
assert.equal(called, false)
|
||||
assert.equal(host.parent.children.length, 0)
|
||||
assert.equal(host.listeners.get('destroy').size, 0)
|
||||
})
|
||||
|
||||
test('VAST eager allocation reentered by core destruction never invokes callback', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
const host = env.host()
|
||||
env.state.onConstruct = () => host.art.destroy()
|
||||
let called = false
|
||||
await env.factory(() => {
|
||||
called = true
|
||||
})(host.art)
|
||||
assert.equal(called, false)
|
||||
assert.equal(env.state.players[0].destroyCalls, 1)
|
||||
assert.equal(host.parent.children.length, 0)
|
||||
})
|
||||
|
||||
test('VAST eager callback cancellation releases the live SDK without rewriting its published snapshots', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
const host = env.host()
|
||||
const gate = deferred()
|
||||
const started = deferred()
|
||||
let context
|
||||
const pending = env.factory(async (value) => {
|
||||
context = value
|
||||
started.resolve()
|
||||
await gate.promise
|
||||
value.playUrl('/too-late.xml')
|
||||
})(host.art)
|
||||
await started.promise
|
||||
const player = context.imaPlayer
|
||||
assert(player)
|
||||
const container = context.$container
|
||||
host.art.destroy()
|
||||
gate.resolve()
|
||||
await pending
|
||||
assert.equal(context.imaPlayer, player)
|
||||
assert.equal(context.$container, container)
|
||||
assert.equal(container.parentNode, null)
|
||||
assert.equal(player.destroyCalls, 1)
|
||||
assert.equal(player.requests.length, 0)
|
||||
assert.equal(context.init(), null)
|
||||
})
|
||||
|
||||
test('VAST default callback rejection releases allocation and keeps the original failure', async () => {
|
||||
for (const destroyError of [null, new Error('secondary cleanup')]) {
|
||||
const env = vastEnvironment(source, { destroyError })
|
||||
const host = env.host()
|
||||
const failure = new Error('callback failed')
|
||||
let context
|
||||
await assert.rejects(env.factory((value) => {
|
||||
context = value
|
||||
return Promise.reject(failure)
|
||||
})(host.art), error => error === failure)
|
||||
assert.equal(env.state.players[0].destroyCalls, 1)
|
||||
assert.equal(host.parent.children.length, 0)
|
||||
assert.equal(host.listeners.get('destroy').size, 0)
|
||||
assert.equal(context.init(), null)
|
||||
}
|
||||
})
|
||||
|
||||
test('VAST default explicit destroy and recreation update aliases without reusing disposed resources', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
const host = env.host()
|
||||
let context
|
||||
const result = await env.factory((value) => {
|
||||
context = value
|
||||
})(host.art)
|
||||
const first = context.imaPlayer
|
||||
const firstId = context.id
|
||||
result.destroy()
|
||||
result.destroy()
|
||||
assert.equal(context.imaPlayer, first)
|
||||
assert.equal(first.destroyCalls, 1)
|
||||
context.playUrl('/fresh.xml')
|
||||
assert.notEqual(context.imaPlayer, first)
|
||||
assert.notEqual(context.id, firstId)
|
||||
assert.equal(context.$container, context.container)
|
||||
assert.equal(context.imaPlayer.requests[0].adTagUrl, '/fresh.xml')
|
||||
assert.equal(host.parent.children.length, 1)
|
||||
host.art.destroy()
|
||||
assert.deepEqual(env.state.players.map(player => player.destroyCalls), [1, 1])
|
||||
})
|
||||
|
||||
test('VAST rejects an unknown mode before loading the SDK and snapshots a valid mode once', async () => {
|
||||
const env = vastEnvironment(source)
|
||||
assert.throws(() => env.factory(undefined, { compatibility: 'typo' }), /Unsupported VAST compatibility mode/)
|
||||
assert.equal(env.state.loads, 0)
|
||||
const options = { compatibility: 'workspace-1.2' }
|
||||
const attach = env.factory(undefined, options)
|
||||
options.compatibility = 'changed later'
|
||||
await attach(env.host().art)
|
||||
assert.equal(env.state.players.length, 0)
|
||||
})
|
||||
Reference in new issue
Block a user