Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/app/service/content/exec_script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ export default class ExecScript {
this.sandboxContext?.emitEvent(event, eventId, data);
}

valueUpdate(data: ValueUpdateDataEncoded) {
this.sandboxContext?.valueUpdate(data);
valueUpdate(storageName: string, uuid: string, data: ValueUpdateDataEncoded[]) {
this.sandboxContext?.valueUpdate(storageName, uuid, data);
}

execContext: any;
Expand Down
173 changes: 122 additions & 51 deletions src/app/service/content/gm_api/gm_api.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { describe, expect, it, vi } from "vitest";
import { describe, expect, it, type Mock, vi } from "vitest";
import ExecScript from "../exec_script";
import type { ScriptLoadInfo } from "@App/app/service/service_worker/types";
import type { GMInfoEnv, ScriptFunc } from "../types";
import { compileScript, compileScriptCode } from "../utils";
import type { Message } from "@Packages/message/types";
import { encodeRValue } from "@App/pkg/utils/message_value";
import { v4 as uuidv4 } from "uuid";
import { getStorageName } from "@App/pkg/utils/utils";
const nilFn: ScriptFunc = () => {};

const scriptRes = {
Expand Down Expand Up @@ -107,6 +108,40 @@ describe.concurrent("window.*", () => {
});

describe.concurrent("GM Api", () => {
const valueDaoUpdatetimeFix = (
mockSendMessage: Mock<(...args: any[]) => any>,
exec: ExecScript,
script: ScriptLoadInfo
) => {
const forceUpdateTimeRefreshIdx = mockSendMessage.mock.calls.findIndex((entry) => {
return entry?.[0]?.data?.api === "internalApiWaitForFreshValueState";
});
if (forceUpdateTimeRefreshIdx >= 0) {
const actualCall = mockSendMessage.mock.calls[forceUpdateTimeRefreshIdx][0];
expect(mockSendMessage).toHaveBeenNthCalledWith(
forceUpdateTimeRefreshIdx + 1,
expect.objectContaining({
action: "content/runtime/gmApi",
data: {
api: "internalApiWaitForFreshValueState",
params: [expect.stringMatching(/^.+::\d+$/)],
runFlag: expect.any(String),
uuid: undefined,
},
})
);
exec.valueUpdate(getStorageName(script), script.uuid, [
{
id: actualCall.data.params[0],
entries: [["TEST_NON_EXIST_REMOVAL", encodeRValue(undefined), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: getStorageName(script),
sender: { runFlag: exec.sandboxContext!.runFlag, tabId: -2 },
updatetime: Date.now(),
},
]);
}
};
it.concurrent("GM_getValue", async () => {
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
script.value = { test: "ok" };
Expand All @@ -123,10 +158,15 @@ describe.concurrent("GM Api", () => {
script.value = { test: "ok" };
script.metadata.grant = ["GM.getValue"];
script.code = `return GM.getValue("test").then(v=>v+"!");`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret).toEqual("ok!");
});

Expand All @@ -135,10 +175,15 @@ describe.concurrent("GM Api", () => {
script.value = { test1: "23", test2: "45", test3: "67" };
script.metadata.grant = ["GM_listValues"];
script.code = `return GM_listValues().join("-");`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret).toEqual("test1-test2-test3");
});

Expand All @@ -151,22 +196,32 @@ describe.concurrent("GM Api", () => {
script.value.test1 = "40";
script.metadata.grant = ["GM_listValues"];
script.code = `return GM_listValues().join("-");`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
expect(ret).toEqual("test5-test2-test3-test1"); // TM也沒有sort
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret).toEqual("test5-test2-test3-test1"); // TM也没有sort
});

it.concurrent("GM.listValues", async () => {
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
script.value = { test1: "23", test2: "45", test3: "67" };
script.metadata.grant = ["GM.listValues"];
script.code = `return GM.listValues().then(v=>v.join("-"));`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret).toEqual("test1-test2-test3");
});

Expand All @@ -179,11 +234,16 @@ describe.concurrent("GM Api", () => {
script.value.test1 = "40";
script.metadata.grant = ["GM.listValues"];
script.code = `return GM.listValues().then(v=>v.join("-"));`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
expect(ret).toEqual("test5-test2-test3-test1"); // TM也沒有sort
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret).toEqual("test5-test2-test3-test1"); // TM也没有sort
});

it.concurrent("GM_getValues", async () => {
Expand Down Expand Up @@ -212,10 +272,15 @@ describe.concurrent("GM Api", () => {
script.value = { test1: "23", test2: 45, test3: "67" };
script.metadata.grant = ["GM.getValues"];
script.code = `return GM.getValues(["test2", "test3", "test1"]).then(v=>v);`;
// @ts-ignore
const exec = new ExecScript(script, undefined, undefined, nilFn, envInfo);
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
const mockMessage = {
sendMessage: mockSendMessage,
} as unknown as Message;
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
exec.scriptFunc = compileScript(compileScriptCode(script));
const ret = await exec.exec();
const retPromise = exec.exec();
valueDaoUpdatetimeFix(mockSendMessage, exec, script);
const ret = await retPromise;
expect(ret.test1).toEqual("23");
expect(ret.test2).toEqual(45);
expect(ret.test3).toEqual("67");
Expand Down Expand Up @@ -499,7 +564,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValues",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the object payload
keyValuePairs1,
],
Expand All @@ -523,7 +588,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValues",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the object payload
keyValuePairs2,
],
Expand Down Expand Up @@ -573,7 +638,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValues",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the object payload
keyValuePairs1,
],
Expand All @@ -592,7 +657,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValue",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the string payload
"b",
],
Expand Down Expand Up @@ -643,7 +708,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValues",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the object payload
keyValuePairs1,
],
Expand All @@ -667,7 +732,7 @@ describe.concurrent("GM_value", () => {
api: "GM_setValues",
params: [
// event id
expect.stringMatching(/^.+::\d$/),
expect.stringMatching(/^.+::\d+$/),
// the string payload
keyValuePairs2,
],
Expand Down Expand Up @@ -702,14 +767,16 @@ describe.concurrent("GM_value", () => {
const retPromise = exec.exec();
expect(mockSendMessage).toHaveBeenCalledTimes(1);
// 模拟值变化
exec.valueUpdate({
id: "id-1",
entries: [["param1", encodeRValue(123), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: script.uuid,
sender: { runFlag: exec.sandboxContext!.runFlag, tabId: -2 },
valueUpdated: true,
});
exec.valueUpdate(getStorageName(script), script.uuid, [
{
id: "id-1",
entries: [["param1", encodeRValue(123), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: script.uuid,
sender: { runFlag: exec.sandboxContext!.runFlag, tabId: -2 },
updatetime: Date.now(),
},
]);
const ret = await retPromise;
expect(ret).toEqual({ name: "param1", oldValue: undefined, newValue: 123, remote: false });
});
Expand Down Expand Up @@ -737,14 +804,16 @@ describe.concurrent("GM_value", () => {
const retPromise = exec.exec();
expect(mockSendMessage).toHaveBeenCalledTimes(1);
// 模拟值变化
exec.valueUpdate({
id: "id-2",
entries: [["param2", encodeRValue(456), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: "testStorage",
sender: { runFlag: "user", tabId: -2 },
valueUpdated: true,
});
exec.valueUpdate(getStorageName(script), script.uuid, [
{
id: "id-2",
entries: [["param2", encodeRValue(456), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: "testStorage",
sender: { runFlag: "user", tabId: -2 },
updatetime: Date.now(),
},
]);
const ret2 = await retPromise;
expect(ret2).toEqual({ name: "param2", oldValue: undefined, newValue: 456, remote: true });
});
Expand Down Expand Up @@ -772,14 +841,16 @@ describe.concurrent("GM_value", () => {
expect(id).toBeTypeOf("string");
expect(id.length).greaterThan(0);
// 触发valueUpdate
exec.valueUpdate({
id: id,
entries: [["a", encodeRValue(123), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: script.uuid,
sender: { runFlag: exec.sandboxContext!.runFlag, tabId: -2 },
valueUpdated: true,
});
exec.valueUpdate(getStorageName(script), script.uuid, [
{
id: id,
entries: [["a", encodeRValue(123), encodeRValue(undefined)]],
uuid: script.uuid,
storageName: script.uuid,
sender: { runFlag: exec.sandboxContext!.runFlag, tabId: -2 },
updatetime: Date.now(),
},
]);

const ret = await retPromise;
expect(ret).toEqual(123);
Expand Down
Loading
Loading