176 lines
5.9 KiB
Ruby
176 lines
5.9 KiB
Ruby
# encoding: UTF-8
|
|
|
|
require_relative "test_helper"
|
|
require_relative "../lib/meow/media"
|
|
|
|
module MeowMediaTest
|
|
Media = MeowClient::Media
|
|
|
|
class FakeDownloader
|
|
attr_reader :results, :requests
|
|
|
|
def initialize
|
|
@results = Queue.new
|
|
@requests = []
|
|
end
|
|
|
|
def enqueue(id, uri, allow_insecure_http: false)
|
|
@requests << [id, uri, allow_insecure_http]
|
|
true
|
|
end
|
|
|
|
def close
|
|
end
|
|
end
|
|
|
|
class FakeHandle
|
|
attr_accessor :position_ms
|
|
attr_reader :closed, :restarts, :fade
|
|
|
|
def initialize
|
|
@position_ms = 0
|
|
@closed = false
|
|
@finished = false
|
|
@restarts = []
|
|
end
|
|
|
|
def finished?
|
|
@finished
|
|
end
|
|
|
|
def finish!
|
|
@finished = true
|
|
end
|
|
|
|
def restart(position)
|
|
@finished = false
|
|
@restarts << position
|
|
end
|
|
|
|
def stop(fade = 0)
|
|
@fade = fade
|
|
@closed = true
|
|
end
|
|
|
|
def close
|
|
@closed = true
|
|
end
|
|
end
|
|
|
|
class FakeBackend
|
|
attr_reader :starts
|
|
|
|
def initialize
|
|
@starts = []
|
|
end
|
|
|
|
def start(path, request, volume)
|
|
handle = FakeHandle.new
|
|
@starts << [path, request, volume, handle]
|
|
handle
|
|
end
|
|
end
|
|
|
|
MeowTest.test("Media URL policy accepts safe relative HTTPS audio") do
|
|
uri = Media::URLPolicy.new.resolve("https://media.example/game/", "weather/rain.ogg")
|
|
MeowTest.assert_equal("https://media.example/game/weather/rain.ogg", uri.to_s)
|
|
end
|
|
|
|
MeowTest.test("Media URL policy isolates legacy HTTP from secure requests") do
|
|
policy = Media::URLPolicy.new
|
|
MeowTest.assert_raises(ArgumentError) { policy.resolve("http://example.com/", "sound.mp3") }
|
|
legacy = policy.resolve("http://example.com/", "sound.mp3", nil, :allow_insecure_http => true)
|
|
MeowTest.assert_equal("http://example.com/sound.mp3", legacy.to_s)
|
|
MeowTest.assert_raises(ArgumentError) do
|
|
policy.resolve("http://127.0.0.1/", "sound.mp3", nil, :allow_insecure_http => true)
|
|
end
|
|
MeowTest.assert_raises(ArgumentError) { policy.resolve("https://example.com/", "../secret.mp3") }
|
|
end
|
|
|
|
MeowTest.test("Media manager carries HTTP permission on each request") do
|
|
downloader = FakeDownloader.new
|
|
manager = Media::Manager.new("unused", :downloader => downloader)
|
|
secure = Media::PlayRequest.new(:name => "secure.mp3", :url => "https://media.example/")
|
|
legacy = Media::PlayRequest.new(
|
|
:name => "legacy.mid",
|
|
:url => "http://media.example/",
|
|
:allow_insecure_http => true
|
|
)
|
|
manager.play(secure)
|
|
manager.play(legacy)
|
|
MeowTest.assert_equal(false, downloader.requests[0][2])
|
|
MeowTest.assert_equal(true, downloader.requests[1][2])
|
|
ensure
|
|
manager.close if manager != nil
|
|
end
|
|
|
|
MeowTest.test("Client.Media adapter normalizes play and stop commands") do
|
|
play = Media::ClientMedia.play_request({"name" => "rain.ogg", "type" => "music", "loops" => -1, "caption" => "Rain"})
|
|
stop = Media::ClientMedia.stop_request({"type" => "music", "fadeaway" => true})
|
|
MeowTest.assert_equal("rain.ogg", play.name)
|
|
MeowTest.assert_equal(-1, play.loops)
|
|
MeowTest.assert(stop.fade_away)
|
|
end
|
|
|
|
MeowTest.test("Media stop cancels queued playback before its download completes") do
|
|
downloader = FakeDownloader.new
|
|
backend = FakeBackend.new
|
|
manager = Media::Manager.new("unused", :downloader => downloader, :backend => backend)
|
|
manager.default_url = "https://media.example/game/"
|
|
request = Media::PlayRequest.new(:name => "late.mp3", :kind => "sound", :key => "door")
|
|
id = manager.play(request)
|
|
MeowTest.assert_equal(1, manager.stop(Media::StopRequest.new(:key => "door")))
|
|
downloader.results << Media::DownloadResult.new(:id => id, :path => "cached.mp3", :url => "https://media.example/game/late.mp3")
|
|
manager.tick
|
|
MeowTest.assert_empty(backend.starts)
|
|
ensure
|
|
manager.close if manager != nil
|
|
end
|
|
|
|
MeowTest.test("Media priority prevents lower-priority playback") do
|
|
downloader = FakeDownloader.new
|
|
backend = FakeBackend.new
|
|
manager = Media::Manager.new("unused", :downloader => downloader, :backend => backend)
|
|
manager.default_url = "https://media.example/game/"
|
|
|
|
high = Media::PlayRequest.new(:name => "high.mp3", :kind => "sound", :priority => 80)
|
|
high_id = manager.play(high)
|
|
downloader.results << Media::DownloadResult.new(:id => high_id, :path => "high.mp3", :url => "https://media.example/game/high.mp3")
|
|
manager.tick
|
|
|
|
low = Media::PlayRequest.new(:name => "low.mp3", :kind => "sound", :priority => 20)
|
|
low_id = manager.play(low)
|
|
downloader.results << Media::DownloadResult.new(:id => low_id, :path => "low.mp3", :url => "https://media.example/game/low.mp3")
|
|
manager.tick
|
|
MeowTest.assert_equal(1, backend.starts.size)
|
|
MeowTest.assert_equal("high.mp3", backend.starts[0][0])
|
|
ensure
|
|
manager.close if manager != nil
|
|
end
|
|
|
|
MeowTest.test("Media manager downloads starts loops and selectively stops") do
|
|
downloader = FakeDownloader.new
|
|
backend = FakeBackend.new
|
|
manager = Media::Manager.new("unused", :downloader => downloader, :backend => backend, :music_volume => 0.5)
|
|
manager.default_url = "https://media.example/game/"
|
|
request = Media::PlayRequest.new(:name => "theme.mp3", :kind => "music", :loops => 2, :volume => 80, :caption => "Theme")
|
|
id = manager.play(request)
|
|
downloader.results << Media::DownloadResult.new(:id => id, :path => "cached.mp3", :url => "https://media.example/game/theme.mp3")
|
|
manager.tick
|
|
MeowTest.assert_equal(1, manager.tracks.size)
|
|
MeowTest.assert_equal(0.5, backend.starts[0][2])
|
|
MeowTest.assert_equal(["Theme"], manager.captions)
|
|
MeowTest.assert_equal(["Theme"], manager.drain_captions)
|
|
MeowTest.assert_empty(manager.drain_captions)
|
|
handle = backend.starts[0][3]
|
|
handle.finish!
|
|
manager.tick
|
|
MeowTest.assert_equal([0], handle.restarts)
|
|
manager.stop(Media::StopRequest.new(:kind => "music", :fade_away => true))
|
|
MeowTest.assert(handle.closed)
|
|
MeowTest.assert_equal(5_000, handle.fade)
|
|
ensure
|
|
manager.close if manager != nil
|
|
end
|
|
end
|