mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-28 18:22:42 -08:00
fix(plugin): gate aniskip lookups to subminer contexts
This commit is contained in:
@@ -3,7 +3,9 @@ local function run_plugin_scenario(config)
|
||||
|
||||
local recorded = {
|
||||
async_calls = {},
|
||||
sync_calls = {},
|
||||
script_messages = {},
|
||||
events = {},
|
||||
osd = {},
|
||||
logs = {},
|
||||
}
|
||||
@@ -34,7 +36,12 @@ local function run_plugin_scenario(config)
|
||||
return config.chapter_list or {}
|
||||
end
|
||||
|
||||
function mp.get_script_directory()
|
||||
return "plugin/subminer"
|
||||
end
|
||||
|
||||
function mp.command_native(command)
|
||||
recorded.sync_calls[#recorded.sync_calls + 1] = command
|
||||
local args = command.args or {}
|
||||
if args[1] == "ps" then
|
||||
return {
|
||||
@@ -44,6 +51,13 @@ local function run_plugin_scenario(config)
|
||||
}
|
||||
end
|
||||
if args[1] == "curl" then
|
||||
local url = args[#args] or ""
|
||||
if type(url) == "string" and url:find("myanimelist", 1, true) then
|
||||
return { status = 0, stdout = config.mal_lookup_stdout or "{}", stderr = "" }
|
||||
end
|
||||
if type(url) == "string" and url:find("api.aniskip.com", 1, true) then
|
||||
return { status = 0, stdout = config.aniskip_stdout or "{}", stderr = "" }
|
||||
end
|
||||
return { status = 0, stdout = "{}", stderr = "" }
|
||||
end
|
||||
return { status = 0, stdout = "", stderr = "" }
|
||||
@@ -52,6 +66,22 @@ local function run_plugin_scenario(config)
|
||||
function mp.command_native_async(command, callback)
|
||||
recorded.async_calls[#recorded.async_calls + 1] = command
|
||||
if callback then
|
||||
local args = command.args or {}
|
||||
if args[1] == "ps" then
|
||||
callback(true, { status = 0, stdout = config.process_list or "", stderr = "" }, nil)
|
||||
return
|
||||
end
|
||||
if args[1] == "curl" then
|
||||
local url = args[#args] or ""
|
||||
if type(url) == "string" and url:find("myanimelist", 1, true) then
|
||||
callback(true, { status = 0, stdout = config.mal_lookup_stdout or "{}", stderr = "" }, nil)
|
||||
return
|
||||
end
|
||||
if type(url) == "string" and url:find("api.aniskip.com", 1, true) then
|
||||
callback(true, { status = 0, stdout = config.aniskip_stdout or "{}", stderr = "" }, nil)
|
||||
return
|
||||
end
|
||||
end
|
||||
callback(true, { status = 0, stdout = "", stderr = "" }, nil)
|
||||
end
|
||||
end
|
||||
@@ -67,12 +97,18 @@ local function run_plugin_scenario(config)
|
||||
end
|
||||
|
||||
function mp.add_key_binding(_keys, _name, _fn) end
|
||||
function mp.register_event(_name, _fn) end
|
||||
function mp.register_event(name, fn)
|
||||
if recorded.events[name] == nil then
|
||||
recorded.events[name] = {}
|
||||
end
|
||||
recorded.events[name][#recorded.events[name] + 1] = fn
|
||||
end
|
||||
function mp.add_hook(_name, _prio, _fn) end
|
||||
function mp.observe_property(_name, _kind, _fn) end
|
||||
function mp.osd_message(message, _duration)
|
||||
recorded.osd[#recorded.osd + 1] = message
|
||||
end
|
||||
function mp.set_osd_ass(...) end
|
||||
function mp.get_time()
|
||||
return 0
|
||||
end
|
||||
@@ -90,8 +126,8 @@ local function run_plugin_scenario(config)
|
||||
local utils = {}
|
||||
|
||||
function options.read_options(target, _name)
|
||||
if config.socket_path then
|
||||
target.socket_path = config.socket_path
|
||||
for key, value in pairs(config.option_overrides or {}) do
|
||||
target[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
@@ -108,7 +144,35 @@ local function run_plugin_scenario(config)
|
||||
return table.concat(parts, "/")
|
||||
end
|
||||
|
||||
function utils.parse_json(_json)
|
||||
function utils.parse_json(json)
|
||||
if json == "__MAL_FOUND__" then
|
||||
return {
|
||||
categories = {
|
||||
{
|
||||
items = {
|
||||
{
|
||||
id = 99,
|
||||
name = "Sample Show",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
end
|
||||
if json == "__ANISKIP_FOUND__" then
|
||||
return {
|
||||
found = true,
|
||||
results = {
|
||||
{
|
||||
skip_type = "op",
|
||||
interval = {
|
||||
start_time = 12.3,
|
||||
end_time = 45.6,
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
end
|
||||
return {}, nil
|
||||
end
|
||||
|
||||
@@ -149,7 +213,7 @@ local function run_plugin_scenario(config)
|
||||
return utils
|
||||
end
|
||||
|
||||
local ok, err = pcall(dofile, "plugin/subminer.lua")
|
||||
local ok, err = pcall(dofile, "plugin/subminer/main.lua")
|
||||
if not ok then
|
||||
return nil, err, recorded
|
||||
end
|
||||
@@ -168,6 +232,39 @@ local function find_start_call(async_calls)
|
||||
local args = call.args or {}
|
||||
for i = 1, #args do
|
||||
if args[i] == "--start" then
|
||||
return call
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function has_sync_command(sync_calls, executable)
|
||||
for _, call in ipairs(sync_calls) do
|
||||
local args = call.args or {}
|
||||
if args[1] == executable then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function has_async_command(async_calls, executable)
|
||||
for _, call in ipairs(async_calls) do
|
||||
local args = call.args or {}
|
||||
if args[1] == executable then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function has_async_curl_for(async_calls, needle)
|
||||
for _, call in ipairs(async_calls) do
|
||||
local args = call.args or {}
|
||||
if args[1] == "curl" then
|
||||
local url = args[#args] or ""
|
||||
if type(url) == "string" and url:find(needle, 1, true) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -175,11 +272,22 @@ local function find_start_call(async_calls)
|
||||
return false
|
||||
end
|
||||
|
||||
local function fire_event(recorded, name)
|
||||
local listeners = recorded.events[name] or {}
|
||||
for _, listener in ipairs(listeners) do
|
||||
listener()
|
||||
end
|
||||
end
|
||||
|
||||
local binary_path = "/tmp/subminer-binary"
|
||||
|
||||
do
|
||||
local recorded, err = run_plugin_scenario({
|
||||
process_list = "",
|
||||
option_overrides = {
|
||||
binary_path = binary_path,
|
||||
auto_start = "no",
|
||||
},
|
||||
files = {
|
||||
[binary_path] = true,
|
||||
},
|
||||
@@ -187,7 +295,62 @@ do
|
||||
assert_true(recorded ~= nil, "plugin failed to load for cold-start scenario: " .. tostring(err))
|
||||
assert_true(recorded.script_messages["subminer-start"] ~= nil, "subminer-start script message not registered")
|
||||
recorded.script_messages["subminer-start"]("texthooker=no")
|
||||
assert_true(find_start_call(recorded.async_calls), "expected cold-start to invoke --start command when process is absent")
|
||||
assert_true(find_start_call(recorded.async_calls) ~= nil, "expected cold-start to invoke --start command when process is absent")
|
||||
assert_true(
|
||||
not has_sync_command(recorded.sync_calls, "ps"),
|
||||
"expected cold-start start command to avoid synchronous process list scan"
|
||||
)
|
||||
end
|
||||
|
||||
do
|
||||
local recorded, err = run_plugin_scenario({
|
||||
process_list = "",
|
||||
option_overrides = {
|
||||
binary_path = binary_path,
|
||||
auto_start = "no",
|
||||
},
|
||||
media_title = "Random Movie",
|
||||
files = {
|
||||
[binary_path] = true,
|
||||
},
|
||||
})
|
||||
assert_true(recorded ~= nil, "plugin failed to load for non-subminer file-load scenario: " .. tostring(err))
|
||||
fire_event(recorded, "file-loaded")
|
||||
assert_true(not has_sync_command(recorded.sync_calls, "ps"), "file-loaded should avoid synchronous process checks")
|
||||
assert_true(not has_sync_command(recorded.sync_calls, "curl"), "file-loaded should avoid synchronous AniSkip network calls")
|
||||
assert_true(
|
||||
not has_async_curl_for(recorded.async_calls, "myanimelist.net/search/prefix.json"),
|
||||
"file-loaded without SubMiner context should skip AniSkip MAL lookup"
|
||||
)
|
||||
assert_true(
|
||||
not has_async_curl_for(recorded.async_calls, "api.aniskip.com"),
|
||||
"file-loaded without SubMiner context should skip AniSkip API lookup"
|
||||
)
|
||||
end
|
||||
|
||||
do
|
||||
local recorded, err = run_plugin_scenario({
|
||||
process_list = "",
|
||||
option_overrides = {
|
||||
binary_path = binary_path,
|
||||
auto_start = "no",
|
||||
},
|
||||
media_title = "Sample Show S01E01",
|
||||
mal_lookup_stdout = "__MAL_FOUND__",
|
||||
aniskip_stdout = "__ANISKIP_FOUND__",
|
||||
files = {
|
||||
[binary_path] = true,
|
||||
},
|
||||
})
|
||||
assert_true(recorded ~= nil, "plugin failed to load for script-message AniSkip scenario: " .. tostring(err))
|
||||
assert_true(recorded.script_messages["subminer-aniskip-refresh"] ~= nil, "subminer-aniskip-refresh script message not registered")
|
||||
recorded.script_messages["subminer-aniskip-refresh"]()
|
||||
assert_true(not has_sync_command(recorded.sync_calls, "curl"), "AniSkip refresh should not perform synchronous curl calls")
|
||||
assert_true(has_async_command(recorded.async_calls, "curl"), "AniSkip refresh should perform async curl calls")
|
||||
assert_true(
|
||||
has_async_curl_for(recorded.async_calls, "myanimelist.net/search/prefix.json"),
|
||||
"AniSkip refresh should perform MAL lookup even when app is not running"
|
||||
)
|
||||
end
|
||||
|
||||
print("plugin start gate regression tests: OK")
|
||||
|
||||
Reference in New Issue
Block a user