mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
Merge branch 'foss42:main' into add-request-cancellation
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export 'string_extensions.dart';
|
||||
export 'map_extensions.dart';
|
||||
|
||||
26
packages/apidash_core/lib/extensions/map_extensions.dart
Normal file
26
packages/apidash_core/lib/extensions/map_extensions.dart
Normal file
@@ -0,0 +1,26 @@
|
||||
import 'dart:io';
|
||||
|
||||
extension MapExtension on Map {
|
||||
bool hasKeyContentType() {
|
||||
return keys.any((k) => (k is String)
|
||||
? k.toLowerCase() == HttpHeaders.contentTypeHeader
|
||||
: false);
|
||||
}
|
||||
|
||||
String? getKeyContentType() {
|
||||
if (isEmpty) {
|
||||
return null;
|
||||
}
|
||||
bool present = hasKeyContentType();
|
||||
if (present) {
|
||||
return keys.firstWhere((e) => (e is String)
|
||||
? e.toLowerCase() == HttpHeaders.contentTypeHeader
|
||||
: false);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? getValueContentType() {
|
||||
return this[getKeyContentType()];
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:seed/seed.dart';
|
||||
import '../extensions/extensions.dart';
|
||||
import '../utils/utils.dart'
|
||||
show rowsToFormDataMapList, rowsToMap, getEnabledRows;
|
||||
import '../consts.dart';
|
||||
@@ -43,8 +43,7 @@ class HttpRequestModel with _$HttpRequestModel {
|
||||
Map<String, String> get enabledHeadersMap => rowsToMap(enabledHeaders) ?? {};
|
||||
Map<String, String> get enabledParamsMap => rowsToMap(enabledParams) ?? {};
|
||||
|
||||
bool get hasContentTypeHeader => enabledHeadersMap.keys
|
||||
.any((k) => k.toLowerCase() == HttpHeaders.contentTypeHeader);
|
||||
bool get hasContentTypeHeader => enabledHeadersMap.hasKeyContentType();
|
||||
bool get hasFormDataContentType => bodyContentType == ContentType.formdata;
|
||||
bool get hasJsonContentType => bodyContentType == ContentType.json;
|
||||
bool get hasTextContentType => bodyContentType == ContentType.text;
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:collection/collection.dart' show mergeMaps;
|
||||
import 'package:http/http.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import '../extensions/extensions.dart';
|
||||
import '../utils/utils.dart';
|
||||
import '../consts.dart';
|
||||
|
||||
@@ -61,7 +62,7 @@ class HttpResponseModel with _$HttpResponseModel {
|
||||
factory HttpResponseModel.fromJson(Map<String, Object?> json) =>
|
||||
_$HttpResponseModelFromJson(json);
|
||||
|
||||
String? get contentType => getContentTypeFromHeaders(headers);
|
||||
String? get contentType => headers?.getValueContentType();
|
||||
MediaType? get mediaType => getMediaTypeFromHeaders(headers);
|
||||
|
||||
HttpResponseModel fromResponse({
|
||||
|
||||
39
packages/apidash_core/lib/utils/content_type_utils.dart
Normal file
39
packages/apidash_core/lib/utils/content_type_utils.dart
Normal file
@@ -0,0 +1,39 @@
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import '../consts.dart';
|
||||
import '../extensions/extensions.dart';
|
||||
|
||||
ContentType? getContentTypeFromHeadersMap(
|
||||
Map<String, String>? kvMap,
|
||||
) {
|
||||
if (kvMap != null && kvMap.hasKeyContentType()) {
|
||||
var val = getMediaTypeFromHeaders(kvMap);
|
||||
if (val != null) {
|
||||
if (val.subtype.contains(kSubTypeJson)) {
|
||||
return ContentType.json;
|
||||
} else if (val.type == kTypeMultipart &&
|
||||
val.subtype == kSubTypeFormData) {
|
||||
return ContentType.formdata;
|
||||
}
|
||||
return ContentType.text;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
MediaType? getMediaTypeFromHeaders(Map? headers) {
|
||||
var contentType = headers?.getValueContentType();
|
||||
MediaType? mediaType = getMediaTypeFromContentType(contentType);
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
MediaType? getMediaTypeFromContentType(String? contentType) {
|
||||
if (contentType != null) {
|
||||
try {
|
||||
MediaType mediaType = MediaType.parse(contentType);
|
||||
return mediaType;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:seed/seed.dart';
|
||||
|
||||
Map<String, String>? rowsToMap(List<NameValueModel>? kvRows,
|
||||
{bool isHeader = false}) {
|
||||
Map<String, String>? rowsToMap(
|
||||
List<NameValueModel>? kvRows, {
|
||||
bool isHeader = false,
|
||||
}) {
|
||||
if (kvRows == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -19,7 +21,9 @@ Map<String, String>? rowsToMap(List<NameValueModel>? kvRows,
|
||||
return finalMap;
|
||||
}
|
||||
|
||||
List<NameValueModel>? mapToRows(Map<String, String>? kvMap) {
|
||||
List<NameValueModel>? mapToRows(
|
||||
Map<String, String>? kvMap,
|
||||
) {
|
||||
if (kvMap == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -50,7 +54,9 @@ List<Map<String, String>>? rowsToFormDataMapList(
|
||||
return finalMap;
|
||||
}
|
||||
|
||||
List<FormDataModel>? mapListToFormDataModelRows(List<Map>? kvMap) {
|
||||
List<FormDataModel>? mapListToFormDataModelRows(
|
||||
List<Map>? kvMap,
|
||||
) {
|
||||
if (kvMap == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -72,7 +78,9 @@ FormDataType getFormDataType(String? type) {
|
||||
}
|
||||
|
||||
List<NameValueModel>? getEnabledRows(
|
||||
List<NameValueModel>? rows, List<bool>? isRowEnabledList) {
|
||||
List<NameValueModel>? rows,
|
||||
List<bool>? isRowEnabledList,
|
||||
) {
|
||||
if (rows == null || isRowEnabledList == null) {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,10 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:xml/xml.dart';
|
||||
import '../consts.dart';
|
||||
|
||||
String? getContentTypeFromHeaders(Map? headers) {
|
||||
return headers?[HttpHeaders.contentTypeHeader];
|
||||
}
|
||||
|
||||
MediaType? getMediaTypeFromHeaders(Map? headers) {
|
||||
var contentType = getContentTypeFromHeaders(headers);
|
||||
MediaType? mediaType = getMediaTypeFromContentType(contentType);
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
MediaType? getMediaTypeFromContentType(String? contentType) {
|
||||
if (contentType != null) {
|
||||
try {
|
||||
MediaType mediaType = MediaType.parse(contentType);
|
||||
return mediaType;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? formatBody(String? body, MediaType? mediaType) {
|
||||
if (mediaType != null && body != null) {
|
||||
var subtype = mediaType.subtype;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export 'content_type_utils.dart';
|
||||
export 'http_request_utils.dart';
|
||||
export 'http_response_utils.dart';
|
||||
export 'string_utils.dart';
|
||||
|
||||
129
packages/apidash_core/test/extensions/map_extensions_test.dart
Normal file
129
packages/apidash_core/test/extensions/map_extensions_test.dart
Normal file
@@ -0,0 +1,129 @@
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Testing MapExtensions', () {
|
||||
group('Testing hasKeyContentType()', () {
|
||||
test('Content-Type present should return true', () {
|
||||
Map<String, String> mapEx = {"Content-Type": "x", "Agent": "Test"};
|
||||
expect(mapEx.hasKeyContentType(), true);
|
||||
});
|
||||
|
||||
test('content-Type present should return true', () {
|
||||
Map<String, String> mapEx = {"content-Type": "x", "Agent": "Test"};
|
||||
expect(mapEx.hasKeyContentType(), true);
|
||||
});
|
||||
|
||||
test('empty should return false', () {
|
||||
Map<String, String> mapEx = {};
|
||||
expect(mapEx.hasKeyContentType(), false);
|
||||
});
|
||||
|
||||
test('No content-type present should return false', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test"};
|
||||
expect(mapEx.hasKeyContentType(), false);
|
||||
});
|
||||
|
||||
test('Different datatype should return false', () {
|
||||
Map mapEx = {1: "Test"};
|
||||
expect(mapEx.hasKeyContentType(), false);
|
||||
});
|
||||
|
||||
test('Mixed datatype but should return true', () {
|
||||
Map mapEx = {1: "Test", "content-type": "x"};
|
||||
expect(mapEx.hasKeyContentType(), true);
|
||||
});
|
||||
});
|
||||
|
||||
group('Testing getKeyContentType()', () {
|
||||
test('Content-Type present', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test", "Content-Type": "x"};
|
||||
expect(mapEx.getKeyContentType(), "Content-Type");
|
||||
});
|
||||
|
||||
test('content-Type present', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test", "content-Type": "x"};
|
||||
expect(mapEx.getKeyContentType(), "content-Type");
|
||||
});
|
||||
|
||||
test('empty should return null', () {
|
||||
Map<String, String> mapEx = {};
|
||||
expect(mapEx.getKeyContentType(), null);
|
||||
});
|
||||
|
||||
test('No content-type present should return null', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test"};
|
||||
expect(mapEx.getKeyContentType(), null);
|
||||
});
|
||||
|
||||
test('Different datatype should return null', () {
|
||||
Map mapEx = {1: "Test"};
|
||||
expect(mapEx.getKeyContentType(), null);
|
||||
});
|
||||
|
||||
test('Mixed datatype but should return content-type', () {
|
||||
Map mapEx = {1: "Test", "content-type": "x"};
|
||||
expect(mapEx.getKeyContentType(), "content-type");
|
||||
});
|
||||
|
||||
test('Multiple occurence should return first', () {
|
||||
Map mapEx = {1: "Test", "content-Type": "y", "content-type": "x"};
|
||||
expect(mapEx.getKeyContentType(), "content-Type");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
group('Testing getValueContentType()', () {
|
||||
test('Content-Type present', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test", "Content-Type": "x"};
|
||||
expect(mapEx.getValueContentType(), "x");
|
||||
});
|
||||
|
||||
test('content-Type present', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test", "content-Type": "x"};
|
||||
expect(mapEx.getValueContentType(), "x");
|
||||
});
|
||||
|
||||
test('empty should return null', () {
|
||||
Map<String, String> mapEx = {};
|
||||
expect(mapEx.getValueContentType(), null);
|
||||
});
|
||||
|
||||
test('No content-type present should return null', () {
|
||||
Map<String, String> mapEx = {"Agent": "Test"};
|
||||
expect(mapEx.getValueContentType(), null);
|
||||
});
|
||||
|
||||
test('Different datatype should return null', () {
|
||||
Map mapEx = {1: "Test"};
|
||||
expect(mapEx.getValueContentType(), null);
|
||||
});
|
||||
|
||||
test('Mixed datatype but should return x', () {
|
||||
Map mapEx = {1: "Test", "content-type": "x"};
|
||||
expect(mapEx.getValueContentType(), "x");
|
||||
});
|
||||
|
||||
test('Multiple occurence should return first', () {
|
||||
Map mapEx = {1: "Test", "content-Type": "y", "content-type": "x"};
|
||||
expect(mapEx.getValueContentType(), "y");
|
||||
});
|
||||
});
|
||||
|
||||
group("Testing ?.getValueContentType() function", () {
|
||||
test('Testing ?.getValueContentType() for header1', () {
|
||||
Map<String, String> header1 = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
String contentType1Expected = "application/json";
|
||||
expect(header1.getValueContentType(), contentType1Expected);
|
||||
});
|
||||
test('Testing ?.getValueContentType() when header keys are in header case',
|
||||
() {
|
||||
Map<String, String> header2 = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
expect(header2.getValueContentType(), "application/json");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,30 +1,8 @@
|
||||
import 'package:apidash_core/utils/http_response_utils.dart';
|
||||
import 'package:apidash_core/utils/string_utils.dart';
|
||||
import 'package:apidash_core/utils/utils.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group("Testing getContentTypeFromHeaders function", () {
|
||||
test('Testing getContentTypeFromHeaders for header1', () {
|
||||
Map<String, String> header1 = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
String contentType1Expected = "application/json";
|
||||
expect(getContentTypeFromHeaders(header1), contentType1Expected);
|
||||
});
|
||||
test('Testing getContentTypeFromHeaders for null headers', () {
|
||||
expect(getContentTypeFromHeaders(null), null);
|
||||
});
|
||||
test(
|
||||
'Testing getContentTypeFromHeaders when header keys are in header case',
|
||||
() {
|
||||
Map<String, String> header2 = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
expect(getContentTypeFromHeaders(header2), null);
|
||||
});
|
||||
});
|
||||
|
||||
group('Testing getMediaTypeFromContentType function', () {
|
||||
test('Testing getMediaTypeFromContentType for json type', () {
|
||||
String contentType1 = "application/json";
|
||||
|
||||
Reference in New Issue
Block a user