fix: 保留插件配置空字符串值

This commit is contained in:
sunlei 2026-06-18 03:17:23 +08:00
parent 9d0935897b
commit 167a4bba6c
2 changed files with 50 additions and 11 deletions

View File

@ -48,7 +48,7 @@ export class QqbotConfigService {
const record = await this.configRepository.findOne({
where: { configKey },
});
return record?.configValue || undefined;
return record?.configValue ?? undefined;
}
/**

View File

@ -27,16 +27,9 @@ describe('QQBot plugin host bridge', () => {
SAMPLE_TOKEN: 'token-1',
SAMPLE_EMPTY: undefined,
};
const configService = {
/**
* Reads the fixture config value requested by a plugin host call.
* @param configKey - Package-owned config key from the host call arguments.
* @returns Stored fixture value or `undefined` when the key is absent.
*/
getConfigValue: jest.fn(
async (configKey: string) => configValues[configKey],
),
} as unknown as QqbotConfigService;
const configService = new QqbotConfigService(
createConfigRepository(configValues),
);
const dictService = {
getDictByKey: jest.fn(),
getDictItemsByKey: jest.fn(),
@ -84,6 +77,23 @@ describe('QQBot plugin host bridge', () => {
});
});
it('preserves configured empty string values in config snapshots', async () => {
configValues.SAMPLE_EMPTY = '';
await expect(
bridge.handleHostCall(createDescriptor(), {
args: { keys: ['SAMPLE_EMPTY'] },
method: 'getConfigMany',
pluginKey: 'sample',
}),
).resolves.toEqual({
ok: true,
value: {
SAMPLE_EMPTY: '',
},
});
});
it('rejects JSON reads that try to escape the package root', async () => {
await expect(
bridge.handleHostCall(createDescriptor(), {
@ -195,3 +205,32 @@ describe('QQBot plugin host bridge', () => {
};
}
});
/**
* Creates a minimal config repository that lets QqbotConfigService read fixture values through its real raw-value method.
* @param values - Config key/value fixture; absent keys behave like missing records.
* @returns Repository-shaped fixture used by QqbotConfigService in host bridge tests.
*/
function createConfigRepository(
values: Record<string, string | undefined>,
): ConstructorParameters<typeof QqbotConfigService>[0] {
/**
* Finds one QQBot config fixture using the TypeORM `where.configKey` query shape.
* @param query - TypeORM-style lookup object produced by QqbotConfigService.
* @returns Fixture record with the stored config value, or `null` when the key is not present.
*/
const findOne = async (query: { where?: { configKey?: string } }) => {
const configKey = query.where?.configKey;
if (
!configKey ||
!Object.prototype.hasOwnProperty.call(values, configKey)
) {
return null;
}
return { configValue: values[configKey] };
};
return {
findOne: jest.fn(findOne),
} as unknown as ConstructorParameters<typeof QqbotConfigService>[0];
}