From 2b950ad6cf0dc26214ad3ba9b842f918f20ce1c0 Mon Sep 17 00:00:00 2001 From: Pratham <pratham200209@gmail.com> Date: Sun, 24 Nov 2024 18:50:37 +0530 Subject: [PATCH 01/15] Implemented FormData parsing in curl_parser and added tests for it. --- packages/curl_parser/lib/models/curl.dart | 102 ++++++++++++++---- packages/curl_parser/pubspec.yaml | 3 + .../curl_parser/test/curl_parser_test.dart | 102 +++++++++++++++++- 3 files changed, 184 insertions(+), 23 deletions(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index 0420d241..668027c5 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -1,6 +1,8 @@ +import 'package:apidash_core/consts.dart'; +import 'package:apidash_core/models/form_data_model.dart'; import 'package:args/args.dart'; +import 'package:curl_parser/utils/string.dart'; import 'package:equatable/equatable.dart'; -import '../../utils/string.dart'; /// A representation of a cURL command in Dart. /// @@ -10,7 +12,7 @@ class Curl extends Equatable { /// Specifies the HTTP request method (e.g., GET, POST, PUT, DELETE). final String method; - /// Specifies the HTTP request URL + /// Specifies the HTTP request URL. final Uri uri; /// Adds custom HTTP headers to the request. @@ -34,6 +36,10 @@ class Curl extends Equatable { /// Sends data as a multipart/form-data request. final bool form; + /// Form data list. + /// Currently, it is represented as a list of key-value pairs ([key, value]). + final List<FormDataModel>? formData; + /// Allows insecure SSL connections. final bool insecure; @@ -42,7 +48,7 @@ class Curl extends Equatable { /// Constructs a new Curl object with the specified parameters. /// - /// The uri parameter is required, while the remaining parameters are optional. + /// The `uri` parameter is required, while the remaining parameters are optional. Curl({ required this.uri, this.method = 'GET', @@ -52,12 +58,18 @@ class Curl extends Equatable { this.user, this.referer, this.userAgent, + this.formData, this.form = false, this.insecure = false, this.location = false, - }); + }) { + assert( + ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'].contains(method)); + assert(['http', 'https'].contains(uri.scheme)); + assert(form ? formData != null : formData == null); + } - /// Parse [curlString] as a [Curl] class instance. + /// Parses [curlString] into a [Curl] class instance. /// /// Like [parse] except that this function returns `null` where a /// similar call to [parse] would throw a throwable. @@ -70,8 +82,9 @@ class Curl extends Equatable { static Curl? tryParse(String curlString) { try { return Curl.parse(curlString); - } catch (_) {} - return null; + } catch (_) { + return null; + } } /// Parse [curlString] as a [Curl] class instance. @@ -88,6 +101,8 @@ class Curl extends Equatable { final parser = ArgParser(allowTrailingOptions: true); + // TODO: Add more options + // https://gist.github.com/eneko/dc2d8edd9a4b25c5b0725dd123f98b10 // Define the expected options parser.addOption('url'); parser.addOption('request', abbr: 'X'); @@ -98,7 +113,7 @@ class Curl extends Equatable { parser.addOption('referer', abbr: 'e'); parser.addOption('user-agent', abbr: 'A'); parser.addFlag('head', abbr: 'I'); - parser.addFlag('form', abbr: 'F'); + parser.addMultiOption('form', abbr: 'F'); parser.addFlag('insecure', abbr: 'k'); parser.addFlag('location', abbr: 'L'); @@ -111,7 +126,15 @@ class Curl extends Equatable { final result = parser.parse(splittedCurlString); - final method = (result['request'] as String?)?.toUpperCase(); + // A potential alternative to the above code + // final curlString = curlString.replaceAll("\\\n", " "); + // final tokens = shlex.split(curlString); + // final result = parser.parse(tokens); + // if (!result.arguments.contains('curl')) { + // throw Exception('Invalid cURL command'); + // } + + String? method = (result['request'] as String?)?.toUpperCase(); // Extract the request headers Map<String, String>? headers; @@ -129,26 +152,57 @@ class Curl extends Equatable { } } - String? url = clean(result['url']); + // Parse form data + List<FormDataModel>? formData; + if (result['form'] is List<String> && + (result['form'] as List<String>).isNotEmpty) { + formData = <FormDataModel>[]; + for (final formEntry in result['form']) { + final pairs = formEntry.split('='); + if (pairs.length != 2) { + throw Exception('Form data is not in key=value format'); + } + + // Handling the file or text type + FormDataModel formDataModel = pairs[1].startsWith('@') + ? FormDataModel( + name: pairs[0], + value: pairs[1].substring(1), + type: FormDataType.file, + ) + : FormDataModel( + name: pairs[0], + value: pairs[1], + type: FormDataType.text, + ); + + formData.add(formDataModel); + } + headers ??= <String, String>{}; + headers['Content-Type'] = 'multipart/form-data'; + } + + // Handle URL and query parameters + String? url = clean(result['url']) ?? + (result.rest.isNotEmpty ? clean(result.rest.first) : null); + if (url == null) { + throw Exception('URL is null'); + } + final uri = Uri.parse(url); + + method = result['head'] == true ? 'HEAD' : (method ?? 'GET'); final String? data = result['data']; final String? cookie = result['cookie']; final String? user = result['user']; final String? referer = result['referer']; final String? userAgent = result['user-agent']; - final bool form = result['form'] ?? false; - final bool head = result['head'] ?? false; + final bool form = formData != null && formData.isNotEmpty; final bool insecure = result['insecure'] ?? false; final bool location = result['location'] ?? false; // Extract the request URL - url ??= result.rest.isNotEmpty ? clean(result.rest.first) : null; - if (url == null) { - throw Exception('url is null'); - } - final uri = Uri.parse(url); - return Curl( - method: head ? "HEAD" : (method ?? 'GET'), + method: method, uri: uri, headers: headers, data: data, @@ -157,12 +211,13 @@ class Curl extends Equatable { referer: referer, userAgent: userAgent, form: form, + formData: formData, insecure: insecure, location: location, ); } - // Formatted cURL command + /// Converts the Curl object to a formatted cURL command string. String toCurlString() { var cmd = 'curl '; @@ -176,7 +231,6 @@ class Curl extends Equatable { // Add the URL cmd += '"${Uri.encodeFull(uri.toString())}" '; - // Add the headers headers?.forEach((key, value) { cmd += '\\\n -H "$key: $value" '; @@ -204,7 +258,10 @@ class Curl extends Equatable { } // Add the form flag if (form) { - cmd += " \\\n -F "; + for (final formEntry in formData!) { + cmd += '\\\n -F '; + cmd += '"${formEntry.name}=${formEntry.value}" '; + } } // Add the insecure flag if (insecure) { @@ -229,6 +286,7 @@ class Curl extends Equatable { referer, userAgent, form, + formData, insecure, location, ]; diff --git a/packages/curl_parser/pubspec.yaml b/packages/curl_parser/pubspec.yaml index 2e356acf..be638e07 100644 --- a/packages/curl_parser/pubspec.yaml +++ b/packages/curl_parser/pubspec.yaml @@ -1,6 +1,7 @@ name: curl_parser description: Parse cURL command to Dart object and convert Dart object to cURL command. version: 0.1.0 +publish_to: none homepage: https://github.com/foss42/apidash/tree/main/packages/curl_parser repository: https://github.com/foss42/apidash/tree/main/packages/curl_parser issue_tracker: https://github.com/foss42/apidash/issues @@ -20,6 +21,8 @@ dependencies: args: ^2.5.0 equatable: ^2.0.5 shlex: ^2.0.2 + apidash_core: + path: ../apidash_core dev_dependencies: lints: ^2.1.0 diff --git a/packages/curl_parser/test/curl_parser_test.dart b/packages/curl_parser/test/curl_parser_test.dart index 1c1e641d..ad85c523 100644 --- a/packages/curl_parser/test/curl_parser_test.dart +++ b/packages/curl_parser/test/curl_parser_test.dart @@ -1,6 +1,8 @@ import 'dart:io'; -import 'package:curl_parser/models/curl.dart'; +import 'package:apidash_core/consts.dart'; +import 'package:apidash_core/models/form_data_model.dart'; +import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; const defaultTimeout = Timeout(Duration(seconds: 3)); @@ -27,6 +29,104 @@ void main() { ); }, timeout: defaultTimeout); + test('parse POST request with form-data', () { + const curl = r'''curl -X POST https://api.apidash.dev/upload \\ + -F "file=@/path/to/image.jpg" \\ + -F "username=john" + '''; + + expect( + Curl.parse(curl), + Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/upload'), + headers: { + "Content-Type": "multipart/form-data", + }, + form: true, + formData: [ + FormDataModel( + name: "file", + value: "/path/to/image.jpg", + type: FormDataType.file), + FormDataModel( + name: "username", value: "john", type: FormDataType.text) + ], + ), + ); + }); + + test('parse POST request with form-data including a file and arrays', () { + const curl = r'''curl -X POST https://api.apidash.dev/upload \\ + -F "file=@/path/to/image.jpg" \\ + -F "username=john" \\ + -F "tags=tag1" \\ + -F "tags=tag2" + '''; + + expect( + Curl.parse(curl), + Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/upload'), + headers: { + "Content-Type": "multipart/form-data", + }, + form: true, + formData: [ + FormDataModel( + name: "file", + value: "/path/to/image.jpg", + type: FormDataType.file), + FormDataModel( + name: "username", value: "john", type: FormDataType.text), + FormDataModel(name: "tags", value: "tag1", type: FormDataType.text), + FormDataModel(name: "tags", value: "tag2", type: FormDataType.text), + ], + ), + ); + }); + + test('should throw exception when form data is not in key=value format', () { + const curl = r'''curl -X POST https://api.apidash.dev/upload \\ + -F "invalid_format" \\ + -F "username=john" + '''; + expect( + () => Curl.parse(curl), + throwsException, + ); + }); + + test('should not throw when form data entries are valid key-value pairs', () { + expect( + () => Curl( + uri: Uri.parse('https://api.apidash.dev/upload'), + method: 'POST', + form: true, + formData: [ + FormDataModel( + name: "username", value: "john", type: FormDataType.text), + FormDataModel( + name: "password", value: "password", type: FormDataType.text), + ], + ), + returnsNormally, + ); + }); + + test('should not throw when form data is null', () { + expect( + () => Curl( + uri: Uri.parse('https://api.apidash.dev/upload'), + method: 'POST', + form: false, + formData: null, + ), + returnsNormally, + ); + }); + test('Check quotes support for URL string', () async { expect( Curl.parse('curl -X GET "https://api.apidash.dev/"'), From c7b822223ba01440d5cfe2c8e8d070664569db37 Mon Sep 17 00:00:00 2001 From: Pratham <pratham200209@gmail.com> Date: Tue, 26 Nov 2024 01:13:18 +0530 Subject: [PATCH 02/15] Split the test file into 3 files --- .../curl_parser/test/curl_model_test.dart | 35 +++ .../curl_parser/test/curl_parser_test.dart | 158 ++----------- .../curl_parser/test/dart_to_curl_test.dart | 218 ++++++++++++++++++ 3 files changed, 272 insertions(+), 139 deletions(-) create mode 100644 packages/curl_parser/test/curl_model_test.dart create mode 100644 packages/curl_parser/test/dart_to_curl_test.dart diff --git a/packages/curl_parser/test/curl_model_test.dart b/packages/curl_parser/test/curl_model_test.dart new file mode 100644 index 00000000..6ccbb5ca --- /dev/null +++ b/packages/curl_parser/test/curl_model_test.dart @@ -0,0 +1,35 @@ +import 'package:apidash_core/consts.dart'; +import 'package:apidash_core/models/form_data_model.dart'; +import 'package:curl_parser/curl_parser.dart'; +import 'package:test/test.dart'; + +void main() { + test('should not throw when form data entries are valid key-value pairs', () { + expect( + () => Curl( + uri: Uri.parse('https://api.apidash.dev/upload'), + method: 'POST', + form: true, + formData: [ + FormDataModel( + name: "username", value: "john", type: FormDataType.text), + FormDataModel( + name: "password", value: "password", type: FormDataType.text), + ], + ), + returnsNormally, + ); + }); + + test('should not throw when form data is null', () { + expect( + () => Curl( + uri: Uri.parse('https://api.apidash.dev/upload'), + method: 'POST', + form: false, + formData: null, + ), + returnsNormally, + ); + }); +} diff --git a/packages/curl_parser/test/curl_parser_test.dart b/packages/curl_parser/test/curl_parser_test.dart index ad85c523..4fa1abcd 100644 --- a/packages/curl_parser/test/curl_parser_test.dart +++ b/packages/curl_parser/test/curl_parser_test.dart @@ -1,5 +1,4 @@ import 'dart:io'; - import 'package:apidash_core/consts.dart'; import 'package:apidash_core/models/form_data_model.dart'; import 'package:curl_parser/curl_parser.dart'; @@ -12,26 +11,13 @@ void main() { test('parse an easy cURL', () async { expect( Curl.parse('curl -X GET https://api.apidash.dev/'), - Curl( - method: 'GET', - uri: exampleDotComUri, - ), - ); - }, timeout: defaultTimeout); - - test('compose an easy cURL', () async { - expect( - Curl.parse('curl -X GET https://api.apidash.dev/'), - Curl( - method: 'GET', - uri: exampleDotComUri, - ), + Curl(method: 'GET', uri: exampleDotComUri), ); }, timeout: defaultTimeout); test('parse POST request with form-data', () { - const curl = r'''curl -X POST https://api.apidash.dev/upload \\ - -F "file=@/path/to/image.jpg" \\ + const curl = r'''curl -X POST https://api.apidash.dev/upload \ + -F "file=@/path/to/image.jpg" \ -F "username=john" '''; @@ -40,9 +26,7 @@ void main() { Curl( method: 'POST', uri: Uri.parse('https://api.apidash.dev/upload'), - headers: { - "Content-Type": "multipart/form-data", - }, + headers: {"Content-Type": "multipart/form-data"}, form: true, formData: [ FormDataModel( @@ -57,10 +41,10 @@ void main() { }); test('parse POST request with form-data including a file and arrays', () { - const curl = r'''curl -X POST https://api.apidash.dev/upload \\ - -F "file=@/path/to/image.jpg" \\ - -F "username=john" \\ - -F "tags=tag1" \\ + const curl = r'''curl -X POST https://api.apidash.dev/upload \ + -F "file=@/path/to/image.jpg" \ + -F "username=john" \ + -F "tags=tag1" \ -F "tags=tag2" '''; @@ -69,9 +53,7 @@ void main() { Curl( method: 'POST', uri: Uri.parse('https://api.apidash.dev/upload'), - headers: { - "Content-Type": "multipart/form-data", - }, + headers: {"Content-Type": "multipart/form-data"}, form: true, formData: [ FormDataModel( @@ -88,52 +70,17 @@ void main() { }); test('should throw exception when form data is not in key=value format', () { - const curl = r'''curl -X POST https://api.apidash.dev/upload \\ - -F "invalid_format" \\ + const curl = r'''curl -X POST https://api.apidash.dev/upload \ + -F "invalid_format" \ -F "username=john" '''; - expect( - () => Curl.parse(curl), - throwsException, - ); - }); - - test('should not throw when form data entries are valid key-value pairs', () { - expect( - () => Curl( - uri: Uri.parse('https://api.apidash.dev/upload'), - method: 'POST', - form: true, - formData: [ - FormDataModel( - name: "username", value: "john", type: FormDataType.text), - FormDataModel( - name: "password", value: "password", type: FormDataType.text), - ], - ), - returnsNormally, - ); - }); - - test('should not throw when form data is null', () { - expect( - () => Curl( - uri: Uri.parse('https://api.apidash.dev/upload'), - method: 'POST', - form: false, - formData: null, - ), - returnsNormally, - ); + expect(() => Curl.parse(curl), throwsException); }); test('Check quotes support for URL string', () async { expect( Curl.parse('curl -X GET "https://api.apidash.dev/"'), - Curl( - method: 'GET', - uri: exampleDotComUri, - ), + Curl(method: 'GET', uri: exampleDotComUri), ); }, timeout: defaultTimeout); @@ -185,17 +132,11 @@ void main() { }, timeout: defaultTimeout); test('throw exception when parses wrong input', () async { - expect( - () => Curl.parse('1f'), - throwsException, - ); + expect(() => Curl.parse('1f'), throwsException); }, timeout: defaultTimeout); test('tryParse return null when parses wrong input', () async { - expect( - Curl.tryParse('1f'), - null, - ); + expect(Curl.tryParse('1f'), null); }, timeout: defaultTimeout); test('tryParse success', () async { @@ -214,56 +155,7 @@ void main() { ); }, timeout: defaultTimeout); - test('GET 1', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - ), - ); - }, timeout: defaultTimeout); - - test('GET 2', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/country/data?code=US'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev/country/data?code=US'), - ), - ); - }, timeout: defaultTimeout); - - test('GET 3', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/country/data?code=IND'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev/country/data?code=IND'), - ), - ); - }, timeout: defaultTimeout); - - test('GET 4', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'""", - ), - Curl( - method: 'GET', - uri: Uri.parse( - 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'), - ), - ); - }, timeout: defaultTimeout); - - test('GET 5', () async { + test('GET with GitHub API', () async { expect( Curl.parse( r"""curl --url 'https://api.github.com/repos/foss42/apidash' \ @@ -277,7 +169,7 @@ void main() { ); }, timeout: defaultTimeout); - test('GET 6', () async { + test('GET with GitHub API and raw parameter', () async { expect( Curl.parse( r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ @@ -291,19 +183,7 @@ void main() { ); }, timeout: defaultTimeout); - test('HEAD 2', () async { - expect( - Curl.parse( - r"""curl --head --url 'http://api.apidash.dev'""", - ), - Curl( - method: 'HEAD', - uri: Uri.parse('http://api.apidash.dev'), - ), - ); - }, timeout: defaultTimeout); - - test('POST 1', () async { + test('POST with text/plain content', () async { expect( Curl.parse( r"""curl --request POST \ @@ -324,7 +204,7 @@ void main() { ); }, timeout: defaultTimeout); - test('POST 2', () async { + test('POST with application/json content', () async { expect( Curl.parse( r"""curl --request POST \ diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart new file mode 100644 index 00000000..cde85ad0 --- /dev/null +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -0,0 +1,218 @@ +import 'package:apidash_core/consts.dart'; +import 'package:apidash_core/models/form_data_model.dart'; +import 'package:curl_parser/curl_parser.dart'; +import 'package:test/test.dart'; + +void main() { + group('Basic HTTP Methods', () { + test('GET request', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev"', + ); + }); + + test('POST request', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + ); + expect( + curl.toCurlString(), + 'curl -X POST "https://api.apidash.dev/test"', + ); + }); + + test('HEAD request', () { + final curl = Curl( + method: 'HEAD', + uri: Uri.parse('https://api.apidash.dev'), + ); + expect( + curl.toCurlString(), + 'curl -I "https://api.apidash.dev"', + ); + }); + }); + + group('Headers and Data', () { + test('request with headers', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer token123' + }, + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -H "Content-Type: application/json" \\\n' + ' -H "Authorization: Bearer token123"', + ); + }); + + test('POST request with data', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + headers: {'Content-Type': 'application/json'}, + data: '{"key": "value"}', + ); + expect( + curl.toCurlString(), + 'curl -X POST "https://api.apidash.dev/test" \\\n' + ' -H "Content-Type: application/json" \\\n' + ' -d \'{"key": "value"}\'', + ); + }); + }); + + group('Form Data', () { + test('request with form data', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/upload'), + headers: {'Content-Type': 'multipart/form-data'}, + form: true, + formData: [ + FormDataModel( + name: "file", + value: "/path/to/file.txt", + type: FormDataType.file, + ), + FormDataModel( + name: "name", + value: "test", + type: FormDataType.text, + ), + ], + ); + expect( + curl.toCurlString(), + 'curl -X POST "https://api.apidash.dev/upload" \\\n' + ' -H "Content-Type: multipart/form-data" \\\n' + ' -F "file=/path/to/file.txt" \\\n' + ' -F "name=test"', + ); + }); + }); + + group('Special Parameters', () { + test('request with cookie', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + cookie: 'session=abc123', + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -b \'session=abc123\'', + ); + }); + + test('request with user credentials', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + user: 'username:password', + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -u \'username:password\'', + ); + }); + + test('request with referer', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + referer: 'https://example.com', + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -e \'https://example.com\'', + ); + }); + + test('request with user agent', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + userAgent: 'MyApp/1.0', + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -A \'MyApp/1.0\'', + ); + }); + + test('request with insecure flag', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + insecure: true, + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -k', + ); + }); + + test('request with location flag', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + location: true, + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev" \\\n' + ' -L', + ); + }); + }); + + group('Complex Requests', () { + test('request with all parameters', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer token123' + }, + data: '{"key": "value"}', + cookie: 'session=abc123', + user: 'username:password', + referer: 'https://example.com', + userAgent: 'MyApp/1.0', + insecure: true, + location: true, + ); + expect( + curl.toCurlString(), + 'curl -X POST "https://api.apidash.dev/test" \\\n' + ' -H "Content-Type: application/json" \\\n' + ' -H "Authorization: Bearer token123" \\\n' + ' -d \'{"key": "value"}\' \\\n' + ' -b \'session=abc123\' \\\n' + ' -u \'username:password\' \\\n' + ' -e \'https://example.com\' \\\n' + ' -A \'MyApp/1.0\' \\\n' + ' -k \\\n' + ' -L', + ); + }); + }); +} From 49e2b3d11ed2645482dcf7b0e5a81925088eafbc Mon Sep 17 00:00:00 2001 From: Pratham <pratham200209@gmail.com> Date: Tue, 26 Nov 2024 01:15:49 +0530 Subject: [PATCH 03/15] Adding back the GET tests --- .../curl_parser/test/curl_parser_test.dart | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/packages/curl_parser/test/curl_parser_test.dart b/packages/curl_parser/test/curl_parser_test.dart index 4fa1abcd..0a3b383e 100644 --- a/packages/curl_parser/test/curl_parser_test.dart +++ b/packages/curl_parser/test/curl_parser_test.dart @@ -155,6 +155,55 @@ void main() { ); }, timeout: defaultTimeout); + test('GET 1', () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev'""", + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + ), + ); + }, timeout: defaultTimeout); + + test('GET 2', () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev/country/data?code=US'""", + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev/country/data?code=US'), + ), + ); + }, timeout: defaultTimeout); + + test('GET 3', () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev/country/data?code=IND'""", + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev/country/data?code=IND'), + ), + ); + }, timeout: defaultTimeout); + + test('GET 4', () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'""", + ), + Curl( + method: 'GET', + uri: Uri.parse( + 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'), + ), + ); + }, timeout: defaultTimeout); + test('GET with GitHub API', () async { expect( Curl.parse( From 166c9286f91c73a8302c024356eb6e43ef4f8f86 Mon Sep 17 00:00:00 2001 From: Pratham <pratham200209@gmail.com> Date: Tue, 26 Nov 2024 12:25:16 +0530 Subject: [PATCH 04/15] Fixed a bug in toCurlString() and fixed the dart_to_curl_test with valid curls. --- packages/curl_parser/lib/models/curl.dart | 6 ++- .../curl_parser/test/dart_to_curl_test.dart | 42 +++++-------------- 2 files changed, 15 insertions(+), 33 deletions(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index 668027c5..e933cff7 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -260,7 +260,11 @@ class Curl extends Equatable { if (form) { for (final formEntry in formData!) { cmd += '\\\n -F '; - cmd += '"${formEntry.name}=${formEntry.value}" '; + if (formEntry.type == FormDataType.file) { + cmd += '"${formEntry.name}=@${formEntry.value}" '; + } else { + cmd += '"${formEntry.name}=${formEntry.value}" '; + } } } // Add the insecure flag diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart index cde85ad0..6a344ea6 100644 --- a/packages/curl_parser/test/dart_to_curl_test.dart +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -51,9 +51,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -H "Content-Type: application/json" \\\n' - ' -H "Authorization: Bearer token123"', + 'curl "https://api.apidash.dev" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer token123"', ); }); @@ -66,9 +64,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl -X POST "https://api.apidash.dev/test" \\\n' - ' -H "Content-Type: application/json" \\\n' - ' -d \'{"key": "value"}\'', + """curl -X POST "https://api.apidash.dev/test" \\\n -H "Content-Type: application/json" \\\n -d '{"key": "value"}'""", ); }); }); @@ -95,10 +91,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl -X POST "https://api.apidash.dev/upload" \\\n' - ' -H "Content-Type: multipart/form-data" \\\n' - ' -F "file=/path/to/file.txt" \\\n' - ' -F "name=test"', + 'curl -X POST "https://api.apidash.dev/upload" \\\n -H "Content-Type: multipart/form-data" \\\n -F "file=@/path/to/file.txt" \\\n -F "name=test"', ); }); }); @@ -112,8 +105,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -b \'session=abc123\'', + """curl "https://api.apidash.dev" \\\n -b 'session=abc123'""", ); }); @@ -125,8 +117,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -u \'username:password\'', + """curl "https://api.apidash.dev" \\\n -u 'username:password'""", ); }); @@ -138,8 +129,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -e \'https://example.com\'', + """curl "https://api.apidash.dev" \\\n -e 'https://example.com'""", ); }); @@ -151,8 +141,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -A \'MyApp/1.0\'', + """curl "https://api.apidash.dev" \\\n -A 'MyApp/1.0'""", ); }); @@ -164,8 +153,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -k', + """curl "https://api.apidash.dev" \\\n -k""", ); }); @@ -177,8 +165,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n' - ' -L', + """curl "https://api.apidash.dev" \\\n -L""", ); }); }); @@ -202,16 +189,7 @@ void main() { ); expect( curl.toCurlString(), - 'curl -X POST "https://api.apidash.dev/test" \\\n' - ' -H "Content-Type: application/json" \\\n' - ' -H "Authorization: Bearer token123" \\\n' - ' -d \'{"key": "value"}\' \\\n' - ' -b \'session=abc123\' \\\n' - ' -u \'username:password\' \\\n' - ' -e \'https://example.com\' \\\n' - ' -A \'MyApp/1.0\' \\\n' - ' -k \\\n' - ' -L', + """curl -X POST "https://api.apidash.dev/test" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer token123" \\\n -d '{"key": "value"}' \\\n -b 'session=abc123' \\\n -u 'username:password' \\\n -e 'https://example.com' \\\n -A 'MyApp/1.0' \\\n -k \\\n -L""", ); }); }); From bbe552d4370d6c687149136c0c6c814989d3c328 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 08:48:47 +0530 Subject: [PATCH 05/15] Update curl.dart --- packages/curl_parser/lib/models/curl.dart | 27 ++++++++--------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index e933cff7..4052e367 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -1,8 +1,7 @@ -import 'package:apidash_core/consts.dart'; -import 'package:apidash_core/models/form_data_model.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:args/args.dart'; -import 'package:curl_parser/utils/string.dart'; import 'package:equatable/equatable.dart'; +import '../utils/string.dart'; /// A representation of a cURL command in Dart. /// @@ -37,7 +36,6 @@ class Curl extends Equatable { final bool form; /// Form data list. - /// Currently, it is represented as a list of key-value pairs ([key, value]). final List<FormDataModel>? formData; /// Allows insecure SSL connections. @@ -126,16 +124,6 @@ class Curl extends Equatable { final result = parser.parse(splittedCurlString); - // A potential alternative to the above code - // final curlString = curlString.replaceAll("\\\n", " "); - // final tokens = shlex.split(curlString); - // final result = parser.parse(tokens); - // if (!result.arguments.contains('curl')) { - // throw Exception('Invalid cURL command'); - // } - - String? method = (result['request'] as String?)?.toUpperCase(); - // Extract the request headers Map<String, String>? headers; if (result['header'] != null) { @@ -160,11 +148,12 @@ class Curl extends Equatable { for (final formEntry in result['form']) { final pairs = formEntry.split('='); if (pairs.length != 2) { - throw Exception('Form data is not in key=value format'); + throw Exception( + 'Form data entry $formEntry is not in key=value format'); } // Handling the file or text type - FormDataModel formDataModel = pairs[1].startsWith('@') + var formDataModel = pairs[1].startsWith('@') ? FormDataModel( name: pairs[0], value: pairs[1].substring(1), @@ -179,7 +168,7 @@ class Curl extends Equatable { formData.add(formDataModel); } headers ??= <String, String>{}; - headers['Content-Type'] = 'multipart/form-data'; + headers[kHeaderContentType] = ContentType.formdata.header; } // Handle URL and query parameters @@ -190,7 +179,9 @@ class Curl extends Equatable { } final uri = Uri.parse(url); - method = result['head'] == true ? 'HEAD' : (method ?? 'GET'); + final method = result['head'] + ? 'HEAD' + : ((result['request'] as String?)?.toUpperCase() ?? 'GET'); final String? data = result['data']; final String? cookie = result['cookie']; final String? user = result['user']; From da1d0efc761400836eec0863b20bf93df0f38040 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 08:55:35 +0530 Subject: [PATCH 06/15] minor refactor --- packages/curl_parser/lib/models/curl.dart | 7 +------ packages/curl_parser/lib/utils/string.dart | 4 ++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index 4052e367..ecff5dd9 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -93,10 +93,6 @@ class Curl extends Equatable { /// print(Curl.parse('1f')); // [Exception] is thrown /// ``` static Curl parse(String curlString) { - String? clean(String? url) { - return url?.replaceAll('"', '').replaceAll("'", ''); - } - final parser = ArgParser(allowTrailingOptions: true); // TODO: Add more options @@ -172,8 +168,7 @@ class Curl extends Equatable { } // Handle URL and query parameters - String? url = clean(result['url']) ?? - (result.rest.isNotEmpty ? clean(result.rest.first) : null); + final url = clean(result['url']) ?? clean(result.rest.firstOrNull); if (url == null) { throw Exception('URL is null'); } diff --git a/packages/curl_parser/lib/utils/string.dart b/packages/curl_parser/lib/utils/string.dart index 075b0080..046282cf 100644 --- a/packages/curl_parser/lib/utils/string.dart +++ b/packages/curl_parser/lib/utils/string.dart @@ -3,3 +3,7 @@ import 'package:shlex/shlex.dart' as shlex; List<String> splitAsCommandLineArgs(String command) { return shlex.split(command); } + +String? clean(String? url) { + return url?.replaceAll('"', '').replaceAll("'", ''); +} From 47ab117bfb1c9cd0f942932003f84af82ae65303 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 09:02:45 +0530 Subject: [PATCH 07/15] Update curl.dart --- packages/curl_parser/lib/models/curl.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index ecff5dd9..a85cf904 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -245,7 +245,7 @@ class Curl extends Equatable { // Add the form flag if (form) { for (final formEntry in formData!) { - cmd += '\\\n -F '; + cmd += "\\\n -F "; if (formEntry.type == FormDataType.file) { cmd += '"${formEntry.name}=@${formEntry.value}" '; } else { From 69c7d83e4c39dbb9ed096433ac21cc7530295493 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 09:04:44 +0530 Subject: [PATCH 08/15] bump version --- packages/curl_parser/CHANGELOG.md | 4 ++++ packages/curl_parser/pubspec.yaml | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/curl_parser/CHANGELOG.md b/packages/curl_parser/CHANGELOG.md index 7f67f734..67747c87 100644 --- a/packages/curl_parser/CHANGELOG.md +++ b/packages/curl_parser/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.1 + +- Add formdata support and new test cases. + ## 0.1.0 - Added new test cases. diff --git a/packages/curl_parser/pubspec.yaml b/packages/curl_parser/pubspec.yaml index be638e07..85e37f8f 100644 --- a/packages/curl_parser/pubspec.yaml +++ b/packages/curl_parser/pubspec.yaml @@ -1,7 +1,6 @@ name: curl_parser description: Parse cURL command to Dart object and convert Dart object to cURL command. -version: 0.1.0 -publish_to: none +version: 0.1.1 homepage: https://github.com/foss42/apidash/tree/main/packages/curl_parser repository: https://github.com/foss42/apidash/tree/main/packages/curl_parser issue_tracker: https://github.com/foss42/apidash/issues From 0a5a0ce8225d50eb74dc10f92a8708dd75feff01 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 13:19:35 +0530 Subject: [PATCH 09/15] Update curl_model_test.dart --- packages/curl_parser/test/curl_model_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/curl_parser/test/curl_model_test.dart b/packages/curl_parser/test/curl_model_test.dart index 6ccbb5ca..af6f6b75 100644 --- a/packages/curl_parser/test/curl_model_test.dart +++ b/packages/curl_parser/test/curl_model_test.dart @@ -4,7 +4,7 @@ import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; void main() { - test('should not throw when form data entries are valid key-value pairs', () { + test('should not throw when form data entries are provided', () { expect( () => Curl( uri: Uri.parse('https://api.apidash.dev/upload'), From 093ef6f5948fdc8391055c45916c43e5891ec50d Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 13:20:44 +0530 Subject: [PATCH 10/15] Update curl_model_test.dart --- packages/curl_parser/test/curl_model_test.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/curl_parser/test/curl_model_test.dart b/packages/curl_parser/test/curl_model_test.dart index af6f6b75..2521b35c 100644 --- a/packages/curl_parser/test/curl_model_test.dart +++ b/packages/curl_parser/test/curl_model_test.dart @@ -1,5 +1,4 @@ -import 'package:apidash_core/consts.dart'; -import 'package:apidash_core/models/form_data_model.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; From 835b1df03d32d0eb1dc4f286f18864a534af10b3 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 13:21:37 +0530 Subject: [PATCH 11/15] update imports --- packages/curl_parser/test/curl_parser_test.dart | 3 +-- packages/curl_parser/test/dart_to_curl_test.dart | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/curl_parser/test/curl_parser_test.dart b/packages/curl_parser/test/curl_parser_test.dart index 0a3b383e..454b743d 100644 --- a/packages/curl_parser/test/curl_parser_test.dart +++ b/packages/curl_parser/test/curl_parser_test.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:apidash_core/consts.dart'; -import 'package:apidash_core/models/form_data_model.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart index 6a344ea6..33e91556 100644 --- a/packages/curl_parser/test/dart_to_curl_test.dart +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -1,5 +1,4 @@ -import 'package:apidash_core/consts.dart'; -import 'package:apidash_core/models/form_data_model.dart'; +import 'package:apidash_core/apidash_core.dart'; import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; From bbcca7ee400fe54fc564f581e5e8aa8eefef7a91 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 14:24:02 +0530 Subject: [PATCH 12/15] Update curl_parser_test.dart --- .../curl_parser/test/curl_parser_test.dart | 476 ++++++++++-------- 1 file changed, 272 insertions(+), 204 deletions(-) diff --git a/packages/curl_parser/test/curl_parser_test.dart b/packages/curl_parser/test/curl_parser_test.dart index 454b743d..97037355 100644 --- a/packages/curl_parser/test/curl_parser_test.dart +++ b/packages/curl_parser/test/curl_parser_test.dart @@ -3,72 +3,71 @@ import 'package:apidash_core/apidash_core.dart'; import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; -const defaultTimeout = Timeout(Duration(seconds: 3)); -final exampleDotComUri = Uri.parse('https://api.apidash.dev/'); +final apiUri = Uri.parse('https://api.apidash.dev'); void main() { - test('parse an easy cURL', () async { - expect( - Curl.parse('curl -X GET https://api.apidash.dev/'), - Curl(method: 'GET', uri: exampleDotComUri), - ); - }, timeout: defaultTimeout); + test( + 'parse an easy cURL', + () async { + expect( + Curl.parse('curl -X GET https://api.apidash.dev'), + Curl( + method: 'GET', + uri: apiUri, + ), + ); + }, + ); - test('parse POST request with form-data', () { - const curl = r'''curl -X POST https://api.apidash.dev/upload \ - -F "file=@/path/to/image.jpg" \ - -F "username=john" + test('parse POST request with multipart/form-data', () { + const curl = r'''curl -X POST 'https://api.apidash.dev/io/img' \ + -H 'Content-Type: multipart/form-data' \ + -F "imfile=@/path/to/image.jpg" \ + -F "token=john" '''; expect( Curl.parse(curl), Curl( method: 'POST', - uri: Uri.parse('https://api.apidash.dev/upload'), + uri: Uri.parse('https://api.apidash.dev/io/img'), headers: {"Content-Type": "multipart/form-data"}, form: true, formData: [ FormDataModel( - name: "file", - value: "/path/to/image.jpg", - type: FormDataType.file), + name: "imfile", + value: "/path/to/image.jpg", + type: FormDataType.file, + ), FormDataModel( - name: "username", value: "john", type: FormDataType.text) + name: "token", + value: "john", + type: FormDataType.text, + ) ], ), ); }); - test('parse POST request with form-data including a file and arrays', () { - const curl = r'''curl -X POST https://api.apidash.dev/upload \ - -F "file=@/path/to/image.jpg" \ - -F "username=john" \ - -F "tags=tag1" \ - -F "tags=tag2" + test('parse POST request with x-www-form-urlencoded', () { + const curl = r'''curl -X 'POST' \ + 'https://api.apidash.dev/io/form' \ + -H 'Content-Type: application/x-www-form-urlencoded' \ + -d 'text=apidash&sep=%7C×=3' '''; expect( Curl.parse(curl), Curl( method: 'POST', - uri: Uri.parse('https://api.apidash.dev/upload'), - headers: {"Content-Type": "multipart/form-data"}, - form: true, - formData: [ - FormDataModel( - name: "file", - value: "/path/to/image.jpg", - type: FormDataType.file), - FormDataModel( - name: "username", value: "john", type: FormDataType.text), - FormDataModel(name: "tags", value: "tag1", type: FormDataType.text), - FormDataModel(name: "tags", value: "tag2", type: FormDataType.text), - ], + uri: Uri.parse('https://api.apidash.dev/io/form'), + headers: {"Content-Type": "application/x-www-form-urlencoded"}, + data: 'text=apidash&sep=%7C×=3', ), ); }); - test('should throw exception when form data is not in key=value format', () { + test('should throw exception when multipart/form-data is not valid', () { const curl = r'''curl -X POST https://api.apidash.dev/upload \ -F "invalid_format" \ -F "username=john" @@ -76,186 +75,254 @@ void main() { expect(() => Curl.parse(curl), throwsException); }); - test('Check quotes support for URL string', () async { - expect( - Curl.parse('curl -X GET "https://api.apidash.dev/"'), - Curl(method: 'GET', uri: exampleDotComUri), - ); - }, timeout: defaultTimeout); + test( + 'Check quotes support for URL string', + () async { + expect( + Curl.parse('curl -X GET "https://api.apidash.dev"'), + Curl(method: 'GET', uri: apiUri), + ); + }, + ); - test('parses two headers', () async { - expect( - Curl.parse( - 'curl -X GET https://api.apidash.dev/ -H "${HttpHeaders.contentTypeHeader}: ${ContentType.text}" -H "${HttpHeaders.authorizationHeader}: Bearer %token%"', - ), - Curl( - method: 'GET', - uri: exampleDotComUri, - headers: { - HttpHeaders.contentTypeHeader: ContentType.text.toString(), - HttpHeaders.authorizationHeader: 'Bearer %token%', - }, - ), - ); - }, timeout: defaultTimeout); + test( + 'parses two headers', + () async { + expect( + Curl.parse( + 'curl -X GET https://api.apidash.dev -H "${HttpHeaders.contentTypeHeader}: ${ContentType.text}" -H "${HttpHeaders.authorizationHeader}: Bearer %token%"', + ), + Curl( + method: 'GET', + uri: apiUri, + headers: { + HttpHeaders.contentTypeHeader: ContentType.text.toString(), + HttpHeaders.authorizationHeader: 'Bearer %token%', + }, + ), + ); + }, + ); - test('parses a lot of headers', () async { - expect( - Curl.parse( - r'curl -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" -H "Upgrade-Insecure-Requests: 1" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" -H "Accept-Encoding: gzip, deflate, br" -H "Accept-Language: en,en-GB;q=0.9,en-US;q=0.8,ru;q=0.7" -H "Cache-Control: max-age=0" -H "Dnt: 1" -H "Sec-Ch-Ua: \"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"macOS\"" -H "Sec-Fetch-Dest: document" -H "Sec-Fetch-Mode: navigate" -H "Sec-Fetch-Site: same-origin" -H "Sec-Fetch-User: ?1" https://apidash.dev', - ), - Curl( - method: 'GET', - uri: Uri.parse('https://apidash.dev'), - headers: { - 'User-Agent': - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', - 'Upgrade-Insecure-Requests': '1', - 'Accept': - 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', - 'Accept-Encoding': 'gzip, deflate, br', - 'Accept-Language': 'en,en-GB;q=0.9,en-US;q=0.8,ru;q=0.7', - 'Cache-Control': 'max-age=0', - 'Dnt': '1', - 'Sec-Ch-Ua': - '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', - 'Sec-Ch-Ua-Mobile': '?0', - 'Sec-Ch-Ua-Platform': '"macOS"', - 'Sec-Fetch-Dest': 'document', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'same-origin', - 'Sec-Fetch-User': '?1' - }, - ), - ); - }, timeout: defaultTimeout); + test( + 'parses a lot of headers', + () async { + expect( + Curl.parse( + r'''curl -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36" \ + -H "Upgrade-Insecure-Requests: 1" \ + -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7" \ + -H "Accept-Encoding: gzip, deflate, br" \ + -H "Accept-Language: en,en-GB;q=0.9,en-US;q=0.8,ru;q=0.7" \ + -H "Cache-Control: max-age=0" \ + -H "Dnt: 1" \ + -H "Sec-Ch-Ua: \"Google Chrome\";v=\"117\", \"Not;A=Brand\";v=\"8\", \"Chromium\";v=\"117\"" \ + -H "Sec-Ch-Ua-Mobile: ?0" \ + -H "Sec-Ch-Ua-Platform: \"macOS\"" \ + -H "Sec-Fetch-Dest: document" \ + -H "Sec-Fetch-Mode: navigate" \ + -H "Sec-Fetch-Site: same-origin" \ + -H "Sec-Fetch-User: ?1" https://apidash.dev''', + ), + Curl( + method: 'GET', + uri: Uri.parse('https://apidash.dev'), + headers: { + 'User-Agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', + 'Upgrade-Insecure-Requests': '1', + 'Accept': + 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', + 'Accept-Encoding': 'gzip, deflate, br', + 'Accept-Language': 'en,en-GB;q=0.9,en-US;q=0.8,ru;q=0.7', + 'Cache-Control': 'max-age=0', + 'Dnt': '1', + 'Sec-Ch-Ua': + '"Google Chrome";v="117", "Not;A=Brand";v="8", "Chromium";v="117"', + 'Sec-Ch-Ua-Mobile': '?0', + 'Sec-Ch-Ua-Platform': '"macOS"', + 'Sec-Fetch-Dest': 'document', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-Site': 'same-origin', + 'Sec-Fetch-User': '?1' + }, + ), + ); + }, + ); - test('throw exception when parses wrong input', () async { - expect(() => Curl.parse('1f'), throwsException); - }, timeout: defaultTimeout); + test( + 'throw exception when parses wrong input', + () async { + expect(() => Curl.parse('1f'), throwsException); + }, + ); - test('tryParse return null when parses wrong input', () async { - expect(Curl.tryParse('1f'), null); - }, timeout: defaultTimeout); + test( + 'tryParse return null when parses wrong input', + () async { + expect(Curl.tryParse('1f'), null); + }, + ); - test('tryParse success', () async { - expect( - Curl.tryParse( - 'curl -X GET https://api.apidash.dev/ -H "${HttpHeaders.contentTypeHeader}: ${ContentType.text}" -H "${HttpHeaders.authorizationHeader}: Bearer %token%"', - ), - Curl( - method: 'GET', - uri: exampleDotComUri, - headers: { - HttpHeaders.contentTypeHeader: ContentType.text.toString(), - HttpHeaders.authorizationHeader: 'Bearer %token%', - }, - ), - ); - }, timeout: defaultTimeout); + test( + 'tryParse success', + () async { + expect( + Curl.tryParse( + 'curl -X GET https://api.apidash.dev -H "test: Agent"', + ), + Curl( + method: 'GET', + uri: apiUri, + headers: { + 'test': 'Agent', + }, + ), + ); + }, + ); - test('GET 1', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - ), - ); - }, timeout: defaultTimeout); + test( + 'HEAD 1', + () async { + expect( + Curl.parse( + r"""curl -I 'https://api.apidash.dev'""", + ), + Curl( + method: 'HEAD', + uri: apiUri, + ), + ); + }, + ); - test('GET 2', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/country/data?code=US'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev/country/data?code=US'), - ), - ); - }, timeout: defaultTimeout); + test( + 'HEAD 2', + () async { + expect( + Curl.parse( + r"""curl --head 'https://api.apidash.dev'""", + ), + Curl( + method: 'HEAD', + uri: apiUri, + ), + ); + }, + ); - test('GET 3', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/country/data?code=IND'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev/country/data?code=IND'), - ), - ); - }, timeout: defaultTimeout); + test( + 'GET 1', + () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev'""", + ), + Curl( + method: 'GET', + uri: apiUri, + ), + ); + }, + ); - test('GET 4', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'""", - ), - Curl( - method: 'GET', - uri: Uri.parse( - 'https://api.apidash.dev/humanize/social?num=8700000&digits=3&system=SS&add_space=true&trailing_zeros=true'), - ), - ); - }, timeout: defaultTimeout); + test( + 'GET 2', + () async { + expect( + Curl.parse( + r"""curl --url 'https://api.apidash.dev/country/data?code=US'""", + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev/country/data?code=US'), + ), + ); + }, + ); - test('GET with GitHub API', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.github.com/repos/foss42/apidash' \ + test( + 'GET 3', + () async { + expect( + Curl.parse( + r"""curl 'https://api.apidash.dev/country/data?code=IND'""", + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev/country/data?code=IND'), + ), + ); + }, + ); + + test( + 'GET with GitHub API', + () async { + expect( + Curl.parse( + r"""curl --url 'https://api.github.com/repos/foss42/apidash' \ --header 'User-Agent: Test Agent'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.github.com/repos/foss42/apidash'), - headers: {"User-Agent": "Test Agent"}, - ), - ); - }, timeout: defaultTimeout); + ), + Curl( + method: 'GET', + uri: Uri.parse('https://api.github.com/repos/foss42/apidash'), + headers: {"User-Agent": "Test Agent"}, + ), + ); + }, + ); - test('GET with GitHub API and raw parameter', () async { - expect( - Curl.parse( - r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ + test( + 'GET with GitHub API and raw parameter', + () async { + expect( + Curl.parse( + r"""curl --url 'https://api.github.com/repos/foss42/apidash?raw=true' \ --header 'User-Agent: Test Agent'""", - ), - Curl( - method: 'GET', - uri: Uri.parse('https://api.github.com/repos/foss42/apidash?raw=true'), - headers: {"User-Agent": "Test Agent"}, - ), - ); - }, timeout: defaultTimeout); + ), + Curl( + method: 'GET', + uri: + Uri.parse('https://api.github.com/repos/foss42/apidash?raw=true'), + headers: {"User-Agent": "Test Agent"}, + ), + ); + }, + ); - test('POST with text/plain content', () async { - expect( - Curl.parse( - r"""curl --request POST \ + test( + 'POST with text/plain content', + () async { + expect( + Curl.parse( + r"""curl --request POST \ --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: text/plain' \ --data '{ "text": "I LOVE Flutter" }'""", - ), - Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/case/lower'), - headers: {"Content-Type": "text/plain"}, - data: r"""{ + ), + Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/case/lower'), + headers: {"Content-Type": "text/plain"}, + data: r"""{ "text": "I LOVE Flutter" }""", - ), - ); - }, timeout: defaultTimeout); + ), + ); + }, + ); - test('POST with application/json content', () async { - expect( - Curl.parse( - r"""curl --request POST \ + test( + 'POST with application/json content', + () async { + expect( + Curl.parse( + r"""curl --request POST \ --url 'https://api.apidash.dev/case/lower' \ --header 'Content-Type: application/json' \ --data '{ @@ -266,12 +333,12 @@ void main() { "no": 1.2, "arr": ["null", "true", "false", null] }'""", - ), - Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/case/lower'), - headers: {"Content-Type": "application/json"}, - data: r"""{ + ), + Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/case/lower'), + headers: {"Content-Type": "application/json"}, + data: r"""{ "text": "I LOVE Flutter", "flag": null, "male": true, @@ -279,7 +346,8 @@ void main() { "no": 1.2, "arr": ["null", "true", "false", null] }""", - ), - ); - }, timeout: defaultTimeout); + ), + ); + }, + ); } From bd7b1e5e3a141a7bbcf0c932249d3682b31aa5f2 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 16:08:09 +0530 Subject: [PATCH 13/15] fixes --- packages/curl_parser/lib/models/curl.dart | 4 +- .../curl_parser/test/dart_to_curl_test.dart | 38 ++++++++++++++----- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/curl_parser/lib/models/curl.dart b/packages/curl_parser/lib/models/curl.dart index a85cf904..a0316401 100644 --- a/packages/curl_parser/lib/models/curl.dart +++ b/packages/curl_parser/lib/models/curl.dart @@ -255,11 +255,11 @@ class Curl extends Equatable { } // Add the insecure flag if (insecure) { - cmd += " \\\n -k "; + cmd += "-k "; } // Add the location flag if (location) { - cmd += " \\\n -L "; + cmd += "-L "; } return cmd.trim(); diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart index 33e91556..e9a3e54a 100644 --- a/packages/curl_parser/test/dart_to_curl_test.dart +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -50,7 +50,9 @@ void main() { ); expect( curl.toCurlString(), - 'curl "https://api.apidash.dev" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer token123"', + r'''curl "https://api.apidash.dev" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer token123"''', ); }); @@ -63,7 +65,9 @@ void main() { ); expect( curl.toCurlString(), - """curl -X POST "https://api.apidash.dev/test" \\\n -H "Content-Type: application/json" \\\n -d '{"key": "value"}'""", + r"""curl -X POST "https://api.apidash.dev/test" \ + -H "Content-Type: application/json" \ + -d '{"key": "value"}'""", ); }); }); @@ -90,7 +94,10 @@ void main() { ); expect( curl.toCurlString(), - 'curl -X POST "https://api.apidash.dev/upload" \\\n -H "Content-Type: multipart/form-data" \\\n -F "file=@/path/to/file.txt" \\\n -F "name=test"', + r'''curl -X POST "https://api.apidash.dev/upload" \ + -H "Content-Type: multipart/form-data" \ + -F "file=@/path/to/file.txt" \ + -F "name=test"''', ); }); }); @@ -104,7 +111,8 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -b 'session=abc123'""", + r"""curl "https://api.apidash.dev" \ + -b 'session=abc123'""", ); }); @@ -116,7 +124,8 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -u 'username:password'""", + r"""curl "https://api.apidash.dev" \ + -u 'username:password'""", ); }); @@ -128,7 +137,8 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -e 'https://example.com'""", + r"""curl "https://api.apidash.dev" \ + -e 'https://example.com'""", ); }); @@ -140,7 +150,8 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -A 'MyApp/1.0'""", + r"""curl "https://api.apidash.dev" \ + -A 'MyApp/1.0'""", ); }); @@ -152,7 +163,7 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -k""", + r"""curl "https://api.apidash.dev" -k""", ); }); @@ -164,7 +175,7 @@ void main() { ); expect( curl.toCurlString(), - """curl "https://api.apidash.dev" \\\n -L""", + r"""curl "https://api.apidash.dev" -L""", ); }); }); @@ -188,7 +199,14 @@ void main() { ); expect( curl.toCurlString(), - """curl -X POST "https://api.apidash.dev/test" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer token123" \\\n -d '{"key": "value"}' \\\n -b 'session=abc123' \\\n -u 'username:password' \\\n -e 'https://example.com' \\\n -A 'MyApp/1.0' \\\n -k \\\n -L""", + r"""curl -X POST "https://api.apidash.dev/test" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer token123" \ + -d '{"key": "value"}' \ + -b 'session=abc123' \ + -u 'username:password' \ + -e 'https://example.com' \ + -A 'MyApp/1.0' -k -L""", ); }); }); From b227ae2e9caa074be5015214d617a1ebc3d12339 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 16:37:56 +0530 Subject: [PATCH 14/15] Update dart_to_curl_test.dart --- .../curl_parser/test/dart_to_curl_test.dart | 407 ++++++++++-------- 1 file changed, 223 insertions(+), 184 deletions(-) diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart index e9a3e54a..f7a614a4 100644 --- a/packages/curl_parser/test/dart_to_curl_test.dart +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -3,203 +3,241 @@ import 'package:curl_parser/curl_parser.dart'; import 'package:test/test.dart'; void main() { - group('Basic HTTP Methods', () { - test('GET request', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - ); - expect( - curl.toCurlString(), - 'curl "https://api.apidash.dev"', - ); - }); - - test('POST request', () { - final curl = Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/test'), - ); - expect( - curl.toCurlString(), - 'curl -X POST "https://api.apidash.dev/test"', - ); - }); - - test('HEAD request', () { - final curl = Curl( - method: 'HEAD', - uri: Uri.parse('https://api.apidash.dev'), - ); - expect( - curl.toCurlString(), - 'curl -I "https://api.apidash.dev"', - ); - }); - }); - - group('Headers and Data', () { - test('request with headers', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer token123' + group( + 'Basic HTTP Methods', + () { + test( + 'GET request', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + ); + expect( + curl.toCurlString(), + 'curl "https://api.apidash.dev"', + ); }, ); - expect( - curl.toCurlString(), - r'''curl "https://api.apidash.dev" \ + + test( + 'POST request', + () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + ); + expect( + curl.toCurlString(), + 'curl -X POST "https://api.apidash.dev/test"', + ); + }, + ); + + test('HEAD request', () { + final curl = Curl( + method: 'HEAD', + uri: Uri.parse('https://api.apidash.dev'), + ); + expect( + curl.toCurlString(), + 'curl -I "https://api.apidash.dev"', + ); + }); + }, + ); + + group( + 'Headers and Data', + () { + test( + 'request with headers', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer token123' + }, + ); + expect( + curl.toCurlString(), + r'''curl "https://api.apidash.dev" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer token123"''', + ); + }, ); - }); - test('POST request with data', () { - final curl = Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/test'), - headers: {'Content-Type': 'application/json'}, - data: '{"key": "value"}', - ); - expect( - curl.toCurlString(), - r"""curl -X POST "https://api.apidash.dev/test" \ + test('POST request with data', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + headers: {'Content-Type': 'application/json'}, + data: '{"key": "value"}', + ); + expect( + curl.toCurlString(), + r"""curl -X POST "https://api.apidash.dev/test" \ -H "Content-Type: application/json" \ -d '{"key": "value"}'""", - ); - }); - }); + ); + }); + }, + ); - group('Form Data', () { - test('request with form data', () { - final curl = Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/upload'), - headers: {'Content-Type': 'multipart/form-data'}, - form: true, - formData: [ - FormDataModel( - name: "file", - value: "/path/to/file.txt", - type: FormDataType.file, - ), - FormDataModel( - name: "name", - value: "test", - type: FormDataType.text, - ), - ], - ); - expect( - curl.toCurlString(), - r'''curl -X POST "https://api.apidash.dev/upload" \ + group( + 'Post with Form Data', + () { + test('request with form data', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/upload'), + headers: {'Content-Type': 'multipart/form-data'}, + form: true, + formData: [ + FormDataModel( + name: "file", + value: "/path/to/file.txt", + type: FormDataType.file, + ), + FormDataModel( + name: "name", + value: "test", + type: FormDataType.text, + ), + ], + ); + expect( + curl.toCurlString(), + r'''curl -X POST "https://api.apidash.dev/upload" \ -H "Content-Type: multipart/form-data" \ -F "file=@/path/to/file.txt" \ -F "name=test"''', - ); - }); - }); + ); + }); + }, + ); - group('Special Parameters', () { - test('request with cookie', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - cookie: 'session=abc123', - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" \ + group( + 'Special Parameters', + () { + test( + 'request with cookie', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + cookie: 'session=abc123', + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" \ -b 'session=abc123'""", - ); - }); - - test('request with user credentials', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - user: 'username:password', - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" \ - -u 'username:password'""", - ); - }); - - test('request with referer', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - referer: 'https://example.com', - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" \ - -e 'https://example.com'""", - ); - }); - - test('request with user agent', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - userAgent: 'MyApp/1.0', - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" \ - -A 'MyApp/1.0'""", - ); - }); - - test('request with insecure flag', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - insecure: true, - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" -k""", - ); - }); - - test('request with location flag', () { - final curl = Curl( - method: 'GET', - uri: Uri.parse('https://api.apidash.dev'), - location: true, - ); - expect( - curl.toCurlString(), - r"""curl "https://api.apidash.dev" -L""", - ); - }); - }); - - group('Complex Requests', () { - test('request with all parameters', () { - final curl = Curl( - method: 'POST', - uri: Uri.parse('https://api.apidash.dev/test'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer token123' + ); }, - data: '{"key": "value"}', - cookie: 'session=abc123', - user: 'username:password', - referer: 'https://example.com', - userAgent: 'MyApp/1.0', - insecure: true, - location: true, ); - expect( - curl.toCurlString(), - r"""curl -X POST "https://api.apidash.dev/test" \ + + test( + 'request with user credentials', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + user: 'username:password', + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" \ + -u 'username:password'""", + ); + }, + ); + + test( + 'request with referer', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + referer: 'https://example.com', + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" \ + -e 'https://example.com'""", + ); + }, + ); + + test( + 'request with user agent', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + userAgent: 'MyApp/1.0', + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" \ + -A 'MyApp/1.0'""", + ); + }, + ); + + test( + 'request with insecure flag', + () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + insecure: true, + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" -k""", + ); + }, + ); + + test('request with location flag', () { + final curl = Curl( + method: 'GET', + uri: Uri.parse('https://api.apidash.dev'), + location: true, + ); + expect( + curl.toCurlString(), + r"""curl "https://api.apidash.dev" -L""", + ); + }); + }, + ); + + group( + 'Complex Requests', + () { + test('request with all parameters', () { + final curl = Curl( + method: 'POST', + uri: Uri.parse('https://api.apidash.dev/test'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer token123' + }, + data: '{"key": "value"}', + cookie: 'session=abc123', + user: 'username:password', + referer: 'https://example.com', + userAgent: 'MyApp/1.0', + insecure: true, + location: true, + ); + expect( + curl.toCurlString(), + r"""curl -X POST "https://api.apidash.dev/test" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer token123" \ -d '{"key": "value"}' \ @@ -207,7 +245,8 @@ void main() { -u 'username:password' \ -e 'https://example.com' \ -A 'MyApp/1.0' -k -L""", - ); - }); - }); + ); + }); + }, + ); } From b382ea78f36935b8a71f19f42e4c5d023e0b2e41 Mon Sep 17 00:00:00 2001 From: Ashita Prasad <ashitaprasad92@gmail.com> Date: Sat, 30 Nov 2024 16:46:09 +0530 Subject: [PATCH 15/15] Update dart_to_curl_test.dart --- .../curl_parser/test/dart_to_curl_test.dart | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/curl_parser/test/dart_to_curl_test.dart b/packages/curl_parser/test/dart_to_curl_test.dart index f7a614a4..1f874a32 100644 --- a/packages/curl_parser/test/dart_to_curl_test.dart +++ b/packages/curl_parser/test/dart_to_curl_test.dart @@ -73,15 +73,15 @@ void main() { test('POST request with data', () { final curl = Curl( method: 'POST', - uri: Uri.parse('https://api.apidash.dev/test'), + uri: Uri.parse('https://api.apidash.dev/case/lower'), headers: {'Content-Type': 'application/json'}, - data: '{"key": "value"}', + data: '{"text": "Grass Is Green"}', ); expect( curl.toCurlString(), - r"""curl -X POST "https://api.apidash.dev/test" \ + r"""curl -X POST "https://api.apidash.dev/case/lower" \ -H "Content-Type: application/json" \ - -d '{"key": "value"}'""", + -d '{"text": "Grass Is Green"}'""", ); }); }, @@ -93,28 +93,28 @@ void main() { test('request with form data', () { final curl = Curl( method: 'POST', - uri: Uri.parse('https://api.apidash.dev/upload'), + uri: Uri.parse('https://api.apidash.dev/io/img'), headers: {'Content-Type': 'multipart/form-data'}, form: true, formData: [ FormDataModel( - name: "file", - value: "/path/to/file.txt", + name: "imfile", + value: "/path/to/file.png", type: FormDataType.file, ), FormDataModel( - name: "name", - value: "test", + name: "token", + value: "123", type: FormDataType.text, ), ], ); expect( curl.toCurlString(), - r'''curl -X POST "https://api.apidash.dev/upload" \ + r'''curl -X POST "https://api.apidash.dev/io/img" \ -H "Content-Type: multipart/form-data" \ - -F "file=@/path/to/file.txt" \ - -F "name=test"''', + -F "imfile=@/path/to/file.png" \ + -F "token=123"''', ); }); },