mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-07 06:17:07 +08:00
test: 恢复表情导出保护并补充语音回归测试
This commit is contained in:
@@ -584,6 +584,19 @@ const detectAssetExtension = (buffer: Buffer): string | null => {
|
|||||||
return 'webp'
|
return 'webp'
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
const htmlArchiveStickerResourceIsValid = async (
|
||||||
|
outputDir: string,
|
||||||
|
value?: string
|
||||||
|
): Promise<boolean> => {
|
||||||
|
const filePath = htmlArchiveResourcePath(outputDir, value)
|
||||||
|
if (!filePath) return false
|
||||||
|
try {
|
||||||
|
return detectAssetExtension(await fs.readFile(filePath)) !== null
|
||||||
|
} catch (error) {
|
||||||
|
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
async function readAvatarAsset(
|
async function readAvatarAsset(
|
||||||
source: string
|
source: string
|
||||||
): Promise<{ extension: string; buffer: Buffer } | null> {
|
): Promise<{ extension: string; buffer: Buffer } | null> {
|
||||||
@@ -1338,12 +1351,28 @@ async function runSingleExport(
|
|||||||
const reusableImageQuality =
|
const reusableImageQuality =
|
||||||
previous?.exportMediaQuality === 'original' ||
|
previous?.exportMediaQuality === 'original' ||
|
||||||
(request.preferOriginal === false && previous?.exportMediaQuality === 'thumbnail')
|
(request.preferOriginal === false && previous?.exportMediaQuality === 'thumbnail')
|
||||||
|
let reusableMediaExists = false
|
||||||
|
if (reusableMediaType && previous?.exportMediaUrl) {
|
||||||
|
reusableMediaExists = await resourceExists(previous.exportMediaUrl)
|
||||||
|
if (
|
||||||
|
reusableMediaExists &&
|
||||||
|
reusableMediaType === 'sticker' &&
|
||||||
|
!(await htmlArchiveStickerResourceIsValid(outputDir, previous.exportMediaUrl))
|
||||||
|
) {
|
||||||
|
reusableMediaExists = false
|
||||||
|
resourceExistence.set(previous.exportMediaUrl, Promise.resolve(false))
|
||||||
|
delete previous.exportMediaUrl
|
||||||
|
delete previous.exportMediaType
|
||||||
|
delete previous.exportMediaName
|
||||||
|
delete previous.exportMediaQuality
|
||||||
|
}
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
reusableMediaType &&
|
reusableMediaType &&
|
||||||
previous?.exportMediaUrl &&
|
previous?.exportMediaUrl &&
|
||||||
(!previous.exportMediaType || previous.exportMediaType === reusableMediaType) &&
|
(!previous.exportMediaType || previous.exportMediaType === reusableMediaType) &&
|
||||||
(reusableMediaType !== 'image' || reusableImageQuality) &&
|
(reusableMediaType !== 'image' || reusableImageQuality) &&
|
||||||
(await resourceExists(previous.exportMediaUrl))
|
reusableMediaExists
|
||||||
) {
|
) {
|
||||||
message.exportMediaUrl = previous.exportMediaUrl
|
message.exportMediaUrl = previous.exportMediaUrl
|
||||||
message.exportMediaType = reusableMediaType
|
message.exportMediaType = reusableMediaType
|
||||||
|
|||||||
@@ -2,6 +2,29 @@ import { describe, expect, it, vi } from 'vitest'
|
|||||||
import { VoiceService } from '../../src/main/voice-service'
|
import { VoiceService } from '../../src/main/voice-service'
|
||||||
|
|
||||||
describe('VoiceService batch lookup', () => {
|
describe('VoiceService batch lookup', () => {
|
||||||
|
it('writes the decoded sample rate and duration into batch WAV output', async () => {
|
||||||
|
const getVoiceDataBatch = vi.fn().mockResolvedValue([{ success: true, hex: '0102' }])
|
||||||
|
const service = new VoiceService({ getVoiceDataBatch } as never)
|
||||||
|
const decoder = (service as unknown as {
|
||||||
|
decoderRegistry: { decode: ReturnType<typeof vi.fn> }
|
||||||
|
}).decoderRegistry
|
||||||
|
vi.spyOn(decoder, 'decode').mockResolvedValue({
|
||||||
|
pcm: Buffer.alloc(16_000 * 2),
|
||||||
|
sampleRate: 16_000,
|
||||||
|
channels: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
const [result] = await service.resolveVoices([
|
||||||
|
{ sessionId: 'session', localId: 10, createTime: 100, svrId: '1000' }
|
||||||
|
])
|
||||||
|
|
||||||
|
expect(result.success).toBe(true)
|
||||||
|
const wav = Buffer.from(result.data!, 'base64')
|
||||||
|
expect(wav.readUInt32LE(24)).toBe(16_000)
|
||||||
|
expect(wav.readUInt16LE(22)).toBe(1)
|
||||||
|
expect((wav.length - 44) / (wav.readUInt32LE(24) * wav.readUInt16LE(22) * 2)).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
it('retries failed batch entries with the compatible single-item lookup', async () => {
|
it('retries failed batch entries with the compatible single-item lookup', async () => {
|
||||||
const getVoiceDataBatch = vi.fn().mockResolvedValue([
|
const getVoiceDataBatch = vi.fn().mockResolvedValue([
|
||||||
{ success: false, error: '获取语音数据失败' },
|
{ success: false, error: '获取语音数据失败' },
|
||||||
|
|||||||
Reference in New Issue
Block a user