import { PassThrough, Readable } from 'stream';
import { brotliCompressSync, gzipSync } from 'zlib';
import { createDecodedEpgStream } from './epg-stream-decoder';
import { StreamingEpgParser } from './epg-streaming-parser';
const xmltvFixture =
'' +
'Test Channel';
async function collectDecodedText(stream: Readable): Promise {
const chunks: Buffer[] = [];
for await (const chunk of stream) {
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
}
return Buffer.concat(chunks).toString('utf-8');
}
function parseChannelCount(xml: string): number {
const parser = new StreamingEpgParser(
() => undefined,
() => undefined,
() => undefined
);
parser.write(xml);
return parser.finish().totalChannels;
}
describe('createDecodedEpgStream', () => {
it('decodes Brotli transfer-encoded XML before SAX parsing', async () => {
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([brotliCompressSync(xmltvFixture)]),
{ 'content-encoding': 'br' },
false
)
);
expect(decodedText.startsWith(' {
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([gzipSync(xmltvFixture)]),
{ 'content-encoding': 'gzip' },
false
)
);
expect(decodedText.startsWith(' {
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([Buffer.from(xmltvFixture)]),
{},
false
)
);
expect(decodedText.startsWith(' {
const transferEncodedPayload = brotliCompressSync(
gzipSync(xmltvFixture)
);
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([transferEncodedPayload]),
{ 'content-encoding': 'br' },
true
)
);
expect(decodedText.startsWith(' {
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([gzipSync(xmltvFixture)]),
{ 'content-encoding': 'gzip' },
true
)
);
expect(decodedText.startsWith(' {
const encodedPayload = brotliCompressSync(gzipSync(xmltvFixture));
const decodedText = await collectDecodedText(
createDecodedEpgStream(
Readable.from([encodedPayload]),
{ 'content-encoding': 'gzip, br' },
false
)
);
expect(decodedText.startsWith(' {
const source = new PassThrough();
const decodedStream = createDecodedEpgStream(
source,
{ 'content-encoding': 'gzip' },
false
);
const readPromise = collectDecodedText(decodedStream);
source.end(Buffer.from('not gzip'));
await expect(readPromise).rejects.toThrow();
expect(source.destroyed).toBe(true);
});
});