From 808053272797326d83926c36a19a60cb0a551806 Mon Sep 17 00:00:00 2001 From: Matteo Gesmundo <46707463+Gesma94@users.noreply.github.com> Date: Wed, 22 May 2024 00:51:06 +0200 Subject: [PATCH] Improve test coverage (#153) * test: 100% branch coverage in `parseParam.js` * test: 100% branch coverage in `Decoder.js` * test: improve branch coverage in `urlencode.js` * test: 100% test coverage in `sbmh.js` * test: 100% branch coverage in `main.js` * chore: fix linting --- test/decoder.test.js | 5 +++ test/parse-params.test.js | 10 +++++ test/streamsearch.test.js | 36 ++++++++++++++++- test/types-urlencoded.test.js | 75 +++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) diff --git a/test/decoder.test.js b/test/decoder.test.js index fa4ce69..bc8795d 100644 --- a/test/decoder.test.js +++ b/test/decoder.test.js @@ -16,6 +16,11 @@ test('Decoder', t => { expected: 'Hello world', what: 'One full encoded byte' }, + { + source: ['%20Hello World'], + expected: ' Hello World', + what: 'Start with full encoded byte' + }, { source: ['Hello%20world%21'], expected: 'Hello world!', diff --git a/test/parse-params.test.js b/test/parse-params.test.js index eea4768..3b6bc98 100644 --- a/test/parse-params.test.js +++ b/test/parse-params.test.js @@ -51,6 +51,11 @@ test('parse-params', t => { expected: ['text/plain', ['greeting', 'hello "world"']], what: 'Quotes within quoted' }, + { + source: 'text/plain; greeting="hello \\\\world\\\\"', + expected: ['text/plain', ['greeting', 'hello \\world\\']], + what: 'Escape within quoted' + }, { source: 'text/plain; encoding=""', expected: ['text/plain', ['encoding', '']], @@ -86,6 +91,11 @@ test('parse-params', t => { expected: ['text/plain', ['filename', '£ rates'], ['altfilename', 'foobarbaz']], what: 'Mixed regular and extended parameters (RFC 5987)' }, + { + source: "text/plain; filename*=iso-8859-1'en';", + expected: ['text/plain', ['filename', '']], + what: 'Mixed regular and extended parameters (RFC 5987) with separator' + }, { source: "text/plain; filename=\"foobarbaz\"; altfilename*=iso-8859-1'en'%A3%20rates", expected: ['text/plain', ['filename', 'foobarbaz'], ['altfilename', '£ rates']], diff --git a/test/streamsearch.test.js b/test/streamsearch.test.js index 968c7de..bc9f01c 100644 --- a/test/streamsearch.test.js +++ b/test/streamsearch.test.js @@ -4,7 +4,7 @@ const { test } = require('tap') const Streamsearch = require('../deps/streamsearch/sbmh') test('streamsearch', t => { - t.plan(17) + t.plan(18) t.test('should throw an error if the needle is not a String or Buffer', t => { t.plan(1) @@ -335,6 +335,40 @@ test('streamsearch', t => { s.push(chunks[3]) }) + t.test('should process four chunks with repeted starting overflowing needle', t => { + t.plan(13) + + const expected = [ + [false, Buffer.from('\n\n\0'), 0, 1], + [true, undefined, undefined, undefined], + [false, Buffer.from('\r\nhello'), 1, 7] + ] + const needle = '\n\n\r' + const s = new Streamsearch(needle) + const chunks = [ + Buffer.from('\n'), + Buffer.from('\n'), + Buffer.from('\n'), + Buffer.from('\r\nhello') + ] + let i = 0 + s.on('info', (isMatched, data, start, end) => { + t.strictSame(isMatched, expected[i][0]) + t.strictSame(data, expected[i][1]) + t.strictSame(start, expected[i][2]) + t.strictSame(end, expected[i][3]) + i++ + if (i >= 3) { + t.pass() + } + }) + + s.push(chunks[0]) + s.push(chunks[1]) + s.push(chunks[2]) + s.push(chunks[3]) + }) + t.test('should process four chunks with a potentially overflowing needle', t => { t.plan(17) diff --git a/test/types-urlencoded.test.js b/test/types-urlencoded.test.js index 73cc286..7673aef 100644 --- a/test/types-urlencoded.test.js +++ b/test/types-urlencoded.test.js @@ -27,6 +27,13 @@ const tests = [ what: 'Unassigned and assigned value', plan: 5 }, + { + source: ['foo&baz=bla'], + expected: [['foo', '', false, false]], + what: 'Unassigned and assigned value with limit', + limits: { fields: 1 }, + plan: 4 + }, { source: ['foo=bar&baz'], expected: [['foo', 'bar', false, false], @@ -80,6 +87,13 @@ const tests = [ what: 'Two assigned values, one with encoded bytes', plan: 5 }, + { + source: ['foo=bar&baz=bla', 'foo=bar'], + expected: [], + what: 'Exceeded limits', + limits: { fields: 0 }, + plan: 3 + }, { source: ['foo=bar&baz=bla'], expected: [], @@ -110,6 +124,22 @@ const tests = [ limits: { fieldNameSize: 2 }, plan: 5 }, + { + source: ['f%20=bar&baz=bla'], + expected: [['f ', 'bar', false, false], + ['ba', 'bla', true, false]], + what: 'Limits: truncated field name with encoded bytes', + limits: { fieldNameSize: 2 }, + plan: 5 + }, + { + source: ['foo=b%20&baz=bla'], + expected: [['foo', 'b ', false, false], + ['baz', 'bl', false, true]], + what: 'Limits: truncated field value with encoded bytes', + limits: { fieldSize: 2 }, + plan: 5 + }, { source: ['foo=bar&baz=bla'], expected: [['foo', 'ba', false, true], @@ -208,3 +238,48 @@ tests.forEach((v) => { busboy.end() }) }) + +test('Call parser end twice', t => { + t.plan(1) + + let finishes = 0 + const busboy = new Busboy({ + headers: { + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' + } + }) + + busboy.on('finish', function () { + t.ok(++finishes === 1, 'finish emitted') + }) + + busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) + + busboy._parser.end() + busboy._parser.end() +}) + +test('Call emit finish twice', t => { + t.plan(2) + + let fields = 0 + let finishes = 0 + + const busboy = new Busboy({ + headers: { + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' + } + }) + busboy.on('field', function () { + t.ok(++fields === 1, 'field emitted') + }) + + busboy.on('finish', function () { + t.ok(++finishes === 1, 'finish emitted') + }) + + busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) + + busboy.emit('finish') + busboy.emit('finish') +})