mirror of
https://github.com/certd/certd.git
synced 2026-08-02 11:04:49 +08:00
846 lines
24 KiB
TypeScript
846 lines
24 KiB
TypeScript
import assert from "node:assert/strict";
|
|
|
|
import { canEditStorePlugin, getPluginFullName, isOnlinePluginUpgradeAvailable, parseOnlinePluginFullName, PluginService } from "./plugin-service.js";
|
|
|
|
type RepoOptions = {
|
|
marketRows?: any[];
|
|
installedRows?: any[];
|
|
queryRows?: any[];
|
|
existingStoreRows?: any[];
|
|
};
|
|
|
|
function createPluginRepositoryMock(options: RepoOptions = {}) {
|
|
const state = {
|
|
savedRows: [] as any[],
|
|
updates: [] as any[],
|
|
queryRows: options.queryRows || options.marketRows || [],
|
|
installedRows: options.installedRows || [],
|
|
existingStoreRows: options.existingStoreRows || [],
|
|
};
|
|
|
|
function buildQueryBuilder() {
|
|
const flags: {
|
|
storeOnly: boolean;
|
|
installedOnly: boolean;
|
|
notBuiltIn: boolean;
|
|
keyword: string;
|
|
fullName: string;
|
|
author: string;
|
|
name: string;
|
|
pluginType: string;
|
|
whereQuery: Record<string, any>;
|
|
offset: number;
|
|
limit?: number;
|
|
} = {
|
|
storeOnly: false,
|
|
installedOnly: false,
|
|
notBuiltIn: false,
|
|
keyword: "",
|
|
fullName: "",
|
|
author: "",
|
|
name: "",
|
|
pluginType: "",
|
|
whereQuery: {},
|
|
offset: 0,
|
|
};
|
|
|
|
function getFilteredList(options?: { paginate?: boolean }) {
|
|
let list = (state.savedRows.length ? state.savedRows : state.queryRows).slice();
|
|
for (const key of Object.keys(flags.whereQuery)) {
|
|
list = list.filter(item => item[key] === flags.whereQuery[key]);
|
|
}
|
|
if (flags.notBuiltIn) {
|
|
list = list.filter(item => item.type !== "builtIn");
|
|
}
|
|
if (flags.storeOnly) {
|
|
list = list.filter(item => item.type === "store");
|
|
}
|
|
if (flags.installedOnly) {
|
|
list = list.filter(item => item.type !== "store" || item.installed === true);
|
|
}
|
|
if (flags.keyword) {
|
|
const keyword = flags.keyword.toLowerCase();
|
|
list = list.filter(item => {
|
|
const searchable = [item.fullName, item.author, item.name, item.title, item.desc, item.group, item.pluginType].filter(Boolean).join(" ").toLowerCase();
|
|
return searchable.includes(keyword);
|
|
});
|
|
}
|
|
if (!options?.paginate) {
|
|
return list;
|
|
}
|
|
return list.slice(flags.offset, flags.limit == null ? undefined : flags.offset + flags.limit);
|
|
}
|
|
|
|
const builder = {
|
|
where(expr: any, params?: any) {
|
|
applyExpr(expr, params);
|
|
return builder;
|
|
},
|
|
andWhere(expr: any, params?: any) {
|
|
applyExpr(expr, params);
|
|
return builder;
|
|
},
|
|
orWhere(expr: any, params?: any) {
|
|
applyExpr(expr, params);
|
|
return builder;
|
|
},
|
|
orderBy() {
|
|
return builder;
|
|
},
|
|
addOrderBy() {
|
|
return builder;
|
|
},
|
|
offset(value: number) {
|
|
flags.offset = value;
|
|
return builder;
|
|
},
|
|
limit(value: number) {
|
|
flags.limit = value;
|
|
return builder;
|
|
},
|
|
setFindOptions() {
|
|
return builder;
|
|
},
|
|
getMany() {
|
|
return getFilteredList({ paginate: true });
|
|
},
|
|
getCount() {
|
|
return getFilteredList().length;
|
|
},
|
|
getOne() {
|
|
return (
|
|
state.installedRows.find(item => {
|
|
if (item.type !== "store") {
|
|
return false;
|
|
}
|
|
if (item.installed !== true) {
|
|
return false;
|
|
}
|
|
if (flags.fullName && item.fullName !== flags.fullName && `${item.author || ""}/${item.name || ""}` !== flags.fullName && item.name !== flags.fullName) {
|
|
return false;
|
|
}
|
|
if (flags.author && item.author !== flags.author) {
|
|
return false;
|
|
}
|
|
if (flags.name && item.name !== flags.name) {
|
|
return false;
|
|
}
|
|
if (flags.pluginType && item.pluginType !== flags.pluginType) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}) || null
|
|
);
|
|
},
|
|
};
|
|
|
|
function applyExpr(expr: any, params?: any) {
|
|
if (typeof expr?.whereFactory === "function") {
|
|
expr.whereFactory(builder);
|
|
return;
|
|
}
|
|
if (expr && typeof expr === "object") {
|
|
flags.whereQuery = { ...flags.whereQuery, ...expr };
|
|
return;
|
|
}
|
|
if (typeof expr !== "string") {
|
|
return;
|
|
}
|
|
if (expr.includes("type != :type") && params?.type === "builtIn") {
|
|
flags.notBuiltIn = true;
|
|
}
|
|
if (expr.includes("item.type = :type") && params?.type === "store") {
|
|
flags.storeOnly = true;
|
|
}
|
|
if (expr.includes("main.installed") || expr.includes("plugin.installed")) {
|
|
flags.installedOnly = true;
|
|
}
|
|
if (expr.includes("LOWER(COALESCE(item.fullName, '')) LIKE :keyword") && params?.keyword) {
|
|
flags.keyword = `${params.keyword}`.replace(/%/g, "");
|
|
}
|
|
if (expr.includes("plugin.fullName = :fullName") && params?.fullName) {
|
|
flags.fullName = params.fullName;
|
|
}
|
|
if (expr.includes("plugin.author = :author AND plugin.name = :name") && params?.author && params?.name) {
|
|
flags.author = params.author;
|
|
flags.name = params.name;
|
|
}
|
|
if (expr.includes("plugin.pluginType = :pluginType") && params?.pluginType) {
|
|
flags.pluginType = params.pluginType;
|
|
}
|
|
}
|
|
|
|
return builder;
|
|
}
|
|
|
|
return {
|
|
state,
|
|
create(record: any) {
|
|
return record;
|
|
},
|
|
async find(options?: any) {
|
|
if (options?.where?.type === "store") {
|
|
return state.existingStoreRows;
|
|
}
|
|
return [];
|
|
},
|
|
async save(records: any[] | any) {
|
|
const list = Array.isArray(records) ? records : [records];
|
|
state.savedRows.push(...list);
|
|
return records;
|
|
},
|
|
async update(where: any, value: any) {
|
|
state.updates.push({ where, value });
|
|
},
|
|
createQueryBuilder() {
|
|
return buildQueryBuilder();
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("PluginService online plugins", () => {
|
|
it("parses online plugin full name", () => {
|
|
assert.deepEqual(parseOnlinePluginFullName("greper/DeployToDemo"), {
|
|
author: "greper",
|
|
name: "DeployToDemo",
|
|
});
|
|
|
|
assert.throws(() => parseOnlinePluginFullName("greper/deploy:DeployToDemo"), /插件标识格式错误/);
|
|
assert.throws(() => parseOnlinePluginFullName("DeployToDemo"), /插件标识格式错误/);
|
|
});
|
|
|
|
it("detects when an online plugin can upgrade the installed version", () => {
|
|
assert.equal(isOnlinePluginUpgradeAvailable("1.0.0", "1.0.1"), true);
|
|
assert.equal(isOnlinePluginUpgradeAvailable("v1.2.0", "1.2.0"), false);
|
|
assert.equal(isOnlinePluginUpgradeAvailable("2.0.0", "1.9.9"), false);
|
|
assert.equal(isOnlinePluginUpgradeAvailable("beta", "beta2"), true);
|
|
});
|
|
|
|
it("allows editing store plugins without developerId or owned by bound user", () => {
|
|
assert.equal(canEditStorePlugin(undefined, undefined), true);
|
|
assert.equal(canEditStorePlugin(0, undefined), true);
|
|
assert.equal(canEditStorePlugin(12, 12), true);
|
|
assert.equal(canEditStorePlugin(12, 13), false);
|
|
assert.equal(canEditStorePlugin(12, undefined), false);
|
|
});
|
|
|
|
it("uses fullName for plugin registration and falls back to name when author is empty", () => {
|
|
assert.equal(getPluginFullName({ fullName: "developer/plugin", author: "other", name: "different" }), "developer/plugin");
|
|
assert.equal(getPluginFullName({ author: "developer", name: "plugin" }), "developer/plugin");
|
|
assert.equal(getPluginFullName({ author: "", name: "plugin" }), "plugin");
|
|
assert.equal(getPluginFullName({ name: "developer/plugin", author: "developer" }), "developer/plugin");
|
|
});
|
|
|
|
it("marks online plugins with local installation state", async () => {
|
|
const service = new PluginService();
|
|
service.repository = createPluginRepositoryMock({
|
|
marketRows: [
|
|
{
|
|
type: "store",
|
|
fullName: "greper/DeployToDemo",
|
|
author: "greper",
|
|
name: "DeployToDemo",
|
|
pluginType: "deploy",
|
|
latest: "1.0.1",
|
|
title: "Deploy Demo",
|
|
},
|
|
],
|
|
installedRows: [
|
|
{
|
|
type: "store",
|
|
id: 3,
|
|
fullName: "greper/DeployToDemo",
|
|
author: "greper",
|
|
name: "DeployToDemo",
|
|
pluginType: "deploy",
|
|
version: "1.0.0",
|
|
disabled: false,
|
|
installed: true,
|
|
content: "name: DeployToDemo",
|
|
},
|
|
],
|
|
}) as any;
|
|
|
|
const list = await service.onlinePluginList({});
|
|
|
|
assert.equal(list.length, 1);
|
|
assert.equal(list[0].installed, true);
|
|
assert.equal(list[0].installedVersion, "1.0.0");
|
|
assert.equal(list[0].upgradeAvailable, true);
|
|
assert.equal(list[0].localPluginId, 3);
|
|
});
|
|
|
|
it("does not treat uninstalled market rows as installed plugins", async () => {
|
|
const service = new PluginService();
|
|
service.repository = createPluginRepositoryMock({
|
|
marketRows: [
|
|
{
|
|
type: "store",
|
|
fullName: "developer/new-plugin",
|
|
author: "developer",
|
|
name: "new-plugin",
|
|
pluginType: "access",
|
|
latest: "1.0.0",
|
|
},
|
|
],
|
|
installedRows: [],
|
|
}) as any;
|
|
|
|
const list = await service.onlinePluginList({});
|
|
|
|
assert.equal(list.length, 1);
|
|
assert.equal(list[0].installed, false);
|
|
assert.equal(list[0].upgradeAvailable, false);
|
|
});
|
|
|
|
it("syncs online plugin list metadata into pi_plugin and saves the sync time", async () => {
|
|
const service = new PluginService();
|
|
const savedSettings: any[] = [];
|
|
const requestCalls: any[] = [];
|
|
let createdAtLt: number | undefined;
|
|
service.plusService = {
|
|
async register() {},
|
|
async request(config: any) {
|
|
requestCalls.push(config);
|
|
assert.equal(config.url, "/activation/plugin/page");
|
|
assert.equal(config.data.page.limit, 200);
|
|
assert.equal(typeof config.data.createdAtLt, "number");
|
|
if (createdAtLt === undefined) {
|
|
createdAtLt = config.data.createdAtLt;
|
|
} else {
|
|
assert.equal(config.data.createdAtLt, createdAtLt);
|
|
}
|
|
if (config.data.page.start === 0) {
|
|
return {
|
|
page: {
|
|
start: 0,
|
|
limit: 200,
|
|
total: 201,
|
|
},
|
|
list: Array.from({ length: 200 }, (_, index) => ({
|
|
author: "developer",
|
|
name: `plugin-${index + 1}`,
|
|
pluginType: "deploy",
|
|
title: `plugin ${index + 1}`,
|
|
latest: "1.0.0",
|
|
status: "published",
|
|
aiCheckStatus: "passed",
|
|
})),
|
|
};
|
|
}
|
|
assert.equal(config.data.page.start, 200);
|
|
return {
|
|
page: {
|
|
start: 200,
|
|
limit: 200,
|
|
total: 201,
|
|
},
|
|
list: [
|
|
{
|
|
author: "developer",
|
|
name: "plugin-201",
|
|
pluginType: "deploy",
|
|
title: "plugin 201",
|
|
latest: "1.0.0",
|
|
status: "published",
|
|
aiCheckStatus: "passed",
|
|
},
|
|
],
|
|
};
|
|
},
|
|
} as any;
|
|
service.sysSettingsService = {
|
|
async getSetting() {
|
|
return { lastSyncTime: 0 };
|
|
},
|
|
async saveSetting(setting: any) {
|
|
savedSettings.push(setting);
|
|
},
|
|
} as any;
|
|
const repository = createPluginRepositoryMock({
|
|
existingStoreRows: [
|
|
{
|
|
id: 1,
|
|
type: "store",
|
|
fullName: "developer/old-plugin",
|
|
author: "developer",
|
|
name: "old-plugin",
|
|
pluginType: "deploy",
|
|
},
|
|
],
|
|
queryRows: [],
|
|
});
|
|
service.repository = repository as any;
|
|
|
|
const res = await service.syncOnlinePluginList();
|
|
|
|
assert.equal(requestCalls.length, 2);
|
|
assert.equal(res.length, 201);
|
|
assert.equal(repository.state.savedRows.length, 201);
|
|
assert.equal(repository.state.savedRows[0].fullName, "developer/plugin-1");
|
|
assert.equal(repository.state.savedRows[0].aiCheckStatus, "passed");
|
|
assert.equal(savedSettings.length, 1);
|
|
assert.equal(typeof savedSettings[0].lastSyncTime, "number");
|
|
assert.equal(savedSettings[0].lastSyncTime > 0, true);
|
|
});
|
|
|
|
it("page includes synced store plugins without installed state", async () => {
|
|
const service = new PluginService();
|
|
const installedRow = {
|
|
id: 2,
|
|
type: "store",
|
|
fullName: "developer/installed",
|
|
author: "developer",
|
|
name: "installed",
|
|
pluginType: "deploy",
|
|
latest: "1.0.1",
|
|
version: "1.0.0",
|
|
installed: true,
|
|
content: "name: installed",
|
|
};
|
|
service.repository = createPluginRepositoryMock({
|
|
queryRows: [
|
|
{
|
|
id: 1,
|
|
type: "store",
|
|
fullName: "developer/market-only",
|
|
author: "developer",
|
|
name: "market-only",
|
|
pluginType: "deploy",
|
|
latest: "1.0.0",
|
|
content: "",
|
|
},
|
|
installedRow,
|
|
{
|
|
id: 3,
|
|
type: "store",
|
|
name: "custom-one",
|
|
pluginType: "deploy",
|
|
content: "name: custom-one",
|
|
},
|
|
],
|
|
installedRows: [installedRow],
|
|
}) as any;
|
|
|
|
const res = await service.page({
|
|
page: {
|
|
offset: 0,
|
|
limit: 20,
|
|
},
|
|
query: {
|
|
type: "store",
|
|
},
|
|
} as any);
|
|
|
|
assert.equal(res.total, 3);
|
|
assert.deepEqual(
|
|
res.records.map((item: any) => item.name),
|
|
["market-only", "installed", "custom-one"]
|
|
);
|
|
assert.equal((res.records[0] as any).installed, false);
|
|
assert.equal((res.records[1] as any).installed, true);
|
|
assert.equal((res.records[1] as any).localPluginId, installedRow.id);
|
|
assert.equal((res.records[1] as any).upgradeAvailable, true);
|
|
});
|
|
|
|
it("registerFromDb skips uninstalled market rows", async () => {
|
|
const service = new PluginService();
|
|
const registered: string[] = [];
|
|
service.repository = createPluginRepositoryMock({
|
|
queryRows: [
|
|
{
|
|
id: 1,
|
|
type: "builtIn",
|
|
name: "builtin-plugin",
|
|
},
|
|
{
|
|
id: 2,
|
|
type: "store",
|
|
fullName: "developer/market-only",
|
|
author: "developer",
|
|
name: "market-only",
|
|
pluginType: "deploy",
|
|
installed: false,
|
|
content: "",
|
|
},
|
|
{
|
|
id: 3,
|
|
type: "store",
|
|
fullName: "developer/installed",
|
|
author: "developer",
|
|
name: "installed",
|
|
pluginType: "deploy",
|
|
installed: true,
|
|
content: "name: installed",
|
|
},
|
|
{
|
|
id: 4,
|
|
type: "store",
|
|
name: "custom-one",
|
|
pluginType: "deploy",
|
|
installed: true,
|
|
content: "name: custom-one",
|
|
},
|
|
],
|
|
}) as any;
|
|
service.registerPlugin = async plugin => {
|
|
registered.push(plugin.name);
|
|
};
|
|
|
|
await service.registerFromDb();
|
|
|
|
assert.deepEqual(registered, ["installed", "custom-one"]);
|
|
});
|
|
|
|
it("downloads and imports online plugin content as store plugin", async () => {
|
|
const service = new PluginService();
|
|
let importReq: any;
|
|
const downloadUpdates: any[] = [];
|
|
|
|
service.plusService = {
|
|
async register() {},
|
|
async request(config: any) {
|
|
assert.equal(config.url, "/activation/plugin/download");
|
|
assert.deepEqual(config.data, { fullName: "greper/DeployToDemo", version: "1.0.1" });
|
|
return {
|
|
fullName: "greper/DeployToDemo",
|
|
content: "name: DeployToDemo\npluginType: deploy\nauthor: greper\ncontent: |\n return class Demo {}\n",
|
|
plugin: {
|
|
fullName: "greper/DeployToDemo",
|
|
downloadCount: 88,
|
|
},
|
|
version: {
|
|
version: "1.0.1",
|
|
},
|
|
};
|
|
},
|
|
} as any;
|
|
const repository = createPluginRepositoryMock() as any;
|
|
repository.update = async (where: any, value: any) => {
|
|
downloadUpdates.push({ where, value });
|
|
return {};
|
|
};
|
|
service.repository = repository;
|
|
service.importPlugin = async req => {
|
|
importReq = req;
|
|
return { id: 9 };
|
|
};
|
|
|
|
const res = await service.installOnlinePlugin({ fullName: "greper/DeployToDemo", version: "1.0.1" });
|
|
|
|
assert.equal(res.id, 9);
|
|
assert.equal(res.fullName, "greper/DeployToDemo");
|
|
assert.equal(importReq.override, true);
|
|
assert.equal(importReq.type, "store");
|
|
assert.match(importReq.content, /DeployToDemo/);
|
|
assert.deepEqual(downloadUpdates[0].where, {
|
|
type: "store",
|
|
fullName: "greper/DeployToDemo",
|
|
});
|
|
});
|
|
|
|
it("fills missing yaml version from online plugin version before import", async () => {
|
|
const service = new PluginService();
|
|
let importReq: any;
|
|
|
|
service.plusService = {
|
|
async register() {},
|
|
async request() {
|
|
return {
|
|
fullName: "developer/testtest2",
|
|
content: "name: testtest2\npluginType: access\nauthor: developer\ncontent: |\n return class DemoAccess {}\n",
|
|
plugin: {
|
|
fullName: "developer/testtest2",
|
|
},
|
|
version: {
|
|
version: "1.0.0",
|
|
},
|
|
};
|
|
},
|
|
} as any;
|
|
service.repository = createPluginRepositoryMock() as any;
|
|
service.importPlugin = async req => {
|
|
importReq = req;
|
|
return { id: 10 };
|
|
};
|
|
|
|
await service.installOnlinePlugin({ fullName: "developer/testtest2" });
|
|
|
|
assert.match(importReq.content, /version: 1\.0\.0/);
|
|
});
|
|
|
|
it("preserves synced market ownership when installing plugin content", async () => {
|
|
const service = new PluginService();
|
|
let updatedPlugin: any;
|
|
|
|
service.repository = {
|
|
async findOne() {
|
|
return {
|
|
id: 7,
|
|
type: "store",
|
|
appId: 3,
|
|
developerId: 12,
|
|
fullName: "greper/online-plugin",
|
|
latest: "1.0.1",
|
|
status: "published",
|
|
downloadCount: 20,
|
|
syncTime: 123,
|
|
};
|
|
},
|
|
} as any;
|
|
service.update = async plugin => {
|
|
updatedPlugin = plugin;
|
|
};
|
|
|
|
await service.importPlugin({
|
|
type: "store",
|
|
override: true,
|
|
content: "name: online-plugin\npluginType: deploy\nauthor: greper\ncontent: |\n return class Demo {}\n",
|
|
});
|
|
|
|
assert.equal(updatedPlugin.id, 7);
|
|
assert.equal(updatedPlugin.appId, 3);
|
|
assert.equal(updatedPlugin.developerId, 12);
|
|
assert.equal(updatedPlugin.latest, "1.0.1");
|
|
assert.equal(updatedPlugin.status, "published");
|
|
assert.equal(updatedPlugin.downloadCount, 20);
|
|
assert.equal(updatedPlugin.syncTime, 123);
|
|
assert.equal(updatedPlugin.installed, true);
|
|
});
|
|
|
|
it("marks an uninstalled market plugin as installed after importing it again", async () => {
|
|
const service = new PluginService();
|
|
let updatedPlugin: any;
|
|
|
|
service.repository = {
|
|
async findOne() {
|
|
return {
|
|
id: 7,
|
|
type: "store",
|
|
developerId: 12,
|
|
fullName: "greper/online-plugin",
|
|
installed: false,
|
|
content: "",
|
|
};
|
|
},
|
|
} as any;
|
|
service.update = async plugin => {
|
|
updatedPlugin = plugin;
|
|
};
|
|
|
|
await service.importPlugin({
|
|
type: "store",
|
|
override: true,
|
|
content: "name: online-plugin\npluginType: deploy\nauthor: greper\ncontent: |\n return class Demo {}\n",
|
|
});
|
|
|
|
assert.equal(updatedPlugin.installed, true);
|
|
});
|
|
|
|
it("publishes a local store plugin through activation with exported content", async () => {
|
|
const service = new PluginService();
|
|
let requestConfig: any;
|
|
let registered = false;
|
|
|
|
service.sysSettingsService = {
|
|
async getSetting() {
|
|
return { bindUserId: 12 };
|
|
},
|
|
} as any;
|
|
service.plusService = {
|
|
async register() {
|
|
registered = true;
|
|
},
|
|
async request(config: any) {
|
|
requestConfig = config;
|
|
return { plugin: { fullName: "developer/custom-one" }, version: { version: "1.2.3" } };
|
|
},
|
|
} as any;
|
|
service.info = async () => {
|
|
return {
|
|
id: 7,
|
|
type: "store",
|
|
name: "custom-one",
|
|
version: "1.2.3",
|
|
} as any;
|
|
};
|
|
service.exportPlugin = async () => {
|
|
return "name: custom-one\nversion: 1.2.3\n";
|
|
};
|
|
|
|
const res = await service.publishLocalPlugin({ id: 7 });
|
|
|
|
assert.equal(registered, true);
|
|
assert.equal(res.plugin.fullName, "developer/custom-one");
|
|
assert.equal(requestConfig.url, "/activation/plugin/publish");
|
|
assert.equal(requestConfig.method, "post");
|
|
assert.deepEqual(requestConfig.data, {
|
|
userId: 12,
|
|
content: "name: custom-one\nversion: 1.2.3\n",
|
|
version: "1.2.3",
|
|
minAppVersion: "",
|
|
maxAppVersion: "",
|
|
});
|
|
});
|
|
|
|
it("gets and creates online plugin author for the bound user", async () => {
|
|
const service = new PluginService();
|
|
const requestConfigs: any[] = [];
|
|
|
|
service.sysSettingsService = {
|
|
async getSetting() {
|
|
return { bindUserId: 23 };
|
|
},
|
|
} as any;
|
|
service.plusService = {
|
|
async register() {},
|
|
async request(config: any) {
|
|
requestConfigs.push(config);
|
|
if (config.url === "/activation/plugin/author/get") {
|
|
return {
|
|
registered: false,
|
|
};
|
|
}
|
|
return {
|
|
id: 5,
|
|
name: "developer",
|
|
};
|
|
},
|
|
} as any;
|
|
|
|
const authorGet = await service.getOnlinePluginAuthor();
|
|
const authorAdd = await service.addOnlinePluginAuthor({
|
|
name: "developer",
|
|
displayName: "Developer",
|
|
});
|
|
|
|
assert.equal(authorGet.registered, false);
|
|
assert.equal(authorAdd.name, "developer");
|
|
assert.deepEqual(requestConfigs[0], {
|
|
url: "/activation/plugin/author/get",
|
|
method: "post",
|
|
data: {
|
|
userId: 23,
|
|
},
|
|
});
|
|
assert.deepEqual(requestConfigs[1], {
|
|
url: "/activation/plugin/author/add",
|
|
method: "post",
|
|
data: {
|
|
userId: 23,
|
|
name: "developer",
|
|
displayName: "Developer",
|
|
avatar: "",
|
|
desc: "",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("gets local plugin publish management info with author and market versions", async () => {
|
|
const service = new PluginService();
|
|
service.sysSettingsService = {
|
|
async getSetting() {
|
|
return { bindUserId: 12 };
|
|
},
|
|
} as any;
|
|
service.info = async () => {
|
|
return {
|
|
id: 7,
|
|
type: "store",
|
|
name: "custom-one",
|
|
title: "Custom One",
|
|
pluginType: "deploy",
|
|
group: "cdn",
|
|
version: "1.0.0",
|
|
} as any;
|
|
};
|
|
service.getOnlinePluginAuthor = async () => {
|
|
return {
|
|
registered: true,
|
|
author: {
|
|
id: 2,
|
|
name: "developer",
|
|
},
|
|
};
|
|
};
|
|
service.onlinePluginDetail = async req => {
|
|
assert.equal(req.fullName, "developer/custom-one");
|
|
return {
|
|
plugin: {
|
|
fullName: "developer/custom-one",
|
|
status: "reviewing",
|
|
},
|
|
versions: [
|
|
{
|
|
version: "1.0.0",
|
|
status: "reviewing",
|
|
reviewStatus: "ai_pending",
|
|
},
|
|
],
|
|
};
|
|
};
|
|
|
|
const info = await service.getOnlinePluginPublishInfo({ id: 7 });
|
|
|
|
assert.equal(info.localPlugin.name, "custom-one");
|
|
assert.equal(info.authorRegistered, true);
|
|
assert.equal(info.marketPlugin?.fullName, "developer/custom-one");
|
|
assert.equal(info.versions[0].reviewStatus, "ai_pending");
|
|
});
|
|
|
|
it("uninstalls synced store plugins without deleting market metadata", async () => {
|
|
const service = new PluginService();
|
|
const updates: any[] = [];
|
|
const deleted: number[] = [];
|
|
const unregistered: number[] = [];
|
|
|
|
service.repository = {
|
|
async update(where: any, values: any) {
|
|
updates.push({ where, values });
|
|
},
|
|
} as any;
|
|
service.info = async (id: number) => {
|
|
if (id === 7) {
|
|
return {
|
|
id,
|
|
type: "store",
|
|
developerId: 12,
|
|
fullName: "developer/online-plugin",
|
|
installed: true,
|
|
content: "name: online-plugin",
|
|
metadata: "input: {}",
|
|
extra: "dependPackages: {}",
|
|
version: "1.0.0",
|
|
disabled: true,
|
|
} as any;
|
|
}
|
|
return {
|
|
id,
|
|
type: "store",
|
|
fullName: "local/local-plugin",
|
|
content: "name: local-plugin",
|
|
} as any;
|
|
};
|
|
service.unRegisterById = async id => {
|
|
unregistered.push(id);
|
|
};
|
|
service.delete = (async (id: any) => {
|
|
deleted.push(Number(id));
|
|
}) as any;
|
|
|
|
await service.deleteByIds([7, 8]);
|
|
|
|
assert.deepEqual(unregistered, [7, 8]);
|
|
assert.deepEqual(deleted, [8]);
|
|
assert.deepEqual(updates, [
|
|
{
|
|
where: { id: 7 },
|
|
values: {
|
|
installed: false,
|
|
disabled: false,
|
|
},
|
|
},
|
|
]);
|
|
});
|
|
});
|