@@ -26,6 +26,7 @@ import {
2626 generateImports ,
2727 generateParameterizationCustomCode ,
2828 generateRequestSnippetsFromSchemas ,
29+ isBinaryContent ,
2930} from './codegen'
3031
3132const fakeDate = new Date ( '2000-01-01T00:00:00Z' )
@@ -183,6 +184,19 @@ describe('Code generation', () => {
183184 )
184185 ) . toBe ( expectedResult )
185186 } )
187+
188+ it ( 'should generate imports with encoding when hasBinaryContent is true' , async ( ) => {
189+ const expectedResult = await prettify ( `
190+ import { group, sleep, check } from 'k6'
191+ import http from 'k6/http'
192+ import execution from "k6/execution";
193+ import encoding from "k6/encoding";
194+ ` )
195+
196+ expect (
197+ await prettify ( generateImports ( generator , { hasBinaryContent : true } ) )
198+ ) . toBe ( expectedResult )
199+ } )
186200 } )
187201
188202 describe ( 'generateVariableDeclarations' , ( ) => {
@@ -728,4 +742,110 @@ describe('Code generation', () => {
728742 )
729743 } )
730744 } )
745+
746+ describe ( 'isBinaryContent' , ( ) => {
747+ it ( 'should return true for content with null bytes' , ( ) => {
748+ expect ( isBinaryContent ( 'hello\x00world' ) ) . toBe ( true )
749+ } )
750+
751+ it ( 'should return true for content with control characters' , ( ) => {
752+ expect ( isBinaryContent ( 'data\x01\x02\x03' ) ) . toBe ( true )
753+ } )
754+
755+ it ( 'should return false for normal text' , ( ) => {
756+ expect ( isBinaryContent ( 'hello world' ) ) . toBe ( false )
757+ } )
758+
759+ it ( 'should return false for text with tabs, newlines, and carriage returns' , ( ) => {
760+ expect ( isBinaryContent ( 'hello\tworld\nfoo\rbar' ) ) . toBe ( false )
761+ } )
762+
763+ it ( 'should return false for empty string' , ( ) => {
764+ expect ( isBinaryContent ( '' ) ) . toBe ( false )
765+ } )
766+
767+ it ( 'should return false for JSON content' , ( ) => {
768+ expect ( isBinaryContent ( '{"key": "value"}' ) ) . toBe ( false )
769+ } )
770+ } )
771+
772+ describe ( 'generateSingleRequestSnippet with binary content' , ( ) => {
773+ it ( 'should use encoding.b64decode for binary content' , ( ) => {
774+ const binaryContent = 'hello\x00\x01\x02world'
775+ const schema = {
776+ data : createProxyData ( {
777+ id : '1' ,
778+ request : createRequest ( {
779+ method : 'POST' ,
780+ url : '/api/v1/upload' ,
781+ content : binaryContent ,
782+ headers : [ [ 'content-type' , 'application/octet-stream' ] ] ,
783+ } ) ,
784+ } ) ,
785+ before : [ ] ,
786+ after : [ ] ,
787+ checks : [ ] ,
788+ }
789+
790+ const result = generateRequestSnippetsFromSchemas ( [ schema ] , thinkTime )
791+ const snippet = result [ 0 ] ?. snippet ?? ''
792+
793+ expect ( snippet ) . toContain ( "encoding.b64decode('" )
794+ expect ( snippet ) . not . toContain ( '`hello' )
795+ } )
796+
797+ it ( 'should use backtick wrapping for text content' , ( ) => {
798+ const schema = {
799+ data : createProxyData ( {
800+ id : '1' ,
801+ request : createRequest ( {
802+ method : 'POST' ,
803+ url : '/api/v1/users' ,
804+ content : '{"user": "test"}' ,
805+ headers : [ [ 'content-type' , 'application/json' ] ] ,
806+ } ) ,
807+ } ) ,
808+ before : [ ] ,
809+ after : [ ] ,
810+ checks : [ ] ,
811+ }
812+
813+ const result = generateRequestSnippetsFromSchemas ( [ schema ] , thinkTime )
814+ const snippet = result [ 0 ] ?. snippet ?? ''
815+
816+ expect ( snippet ) . toContain ( '`{"user": "test"}`' )
817+ expect ( snippet ) . not . toContain ( 'encoding.b64decode' )
818+ } )
819+
820+ it ( 'should base64 encode binary content when btoa cannot handle input' , ( ) => {
821+ const binaryContent = "\x00\u0100'data"
822+ const bytes = new TextEncoder ( ) . encode ( binaryContent )
823+ let utf8Binary = ''
824+ for ( const byte of bytes ) {
825+ utf8Binary += String . fromCharCode ( byte )
826+ }
827+ const expectedBase64Content = btoa ( utf8Binary )
828+ const schema = {
829+ data : createProxyData ( {
830+ id : '1' ,
831+ request : createRequest ( {
832+ method : 'POST' ,
833+ url : '/api/v1/upload' ,
834+ content : binaryContent ,
835+ headers : [ [ 'content-type' , 'application/octet-stream' ] ] ,
836+ } ) ,
837+ } ) ,
838+ before : [ ] ,
839+ after : [ ] ,
840+ checks : [ ] ,
841+ }
842+
843+ const result = generateRequestSnippetsFromSchemas ( [ schema ] , thinkTime )
844+ const snippet = result [ 0 ] ?. snippet ?? ''
845+
846+ expect ( snippet ) . toContain (
847+ `encoding.b64decode('${ expectedBase64Content } ')`
848+ )
849+ } )
850+ } )
731851} )
0 commit comments