diff --git a/lib/consts.dart b/lib/consts.dart index e3d2dc6bb..3f1281317 100644 --- a/lib/consts.dart +++ b/lib/consts.dart @@ -245,6 +245,8 @@ final kColorHttpMethodDelete = Colors.red.shade800; enum RequestItemMenuOption { edit, delete, duplicate } +enum ProtocolType { http } + enum HTTPVerb { get, head, post, put, patch, delete } enum FormDataType { text, file } @@ -258,6 +260,7 @@ const kMethodsWithBody = [ HTTPVerb.delete, ]; +const kDefaultProtocolType = ProtocolType.http; const kDefaultHttpMethod = HTTPVerb.get; const kDefaultContentType = ContentType.json; diff --git a/lib/models/request_model.dart b/lib/models/request_model.dart index 0ea6d7358..8e1afe7d5 100644 --- a/lib/models/request_model.dart +++ b/lib/models/request_model.dart @@ -15,6 +15,7 @@ import 'models.dart'; class RequestModel { const RequestModel({ required this.id, + this.protocol = kDefaultProtocolType, this.method = HTTPVerb.get, this.url = "", this.name = "", @@ -34,6 +35,7 @@ class RequestModel { }); final String id; + final ProtocolType protocol; final HTTPVerb method; final String url; final String name; @@ -98,6 +100,7 @@ class RequestModel { }) { return RequestModel( id: id, + protocol: protocol, method: method, url: url, name: name ?? "${this.name} (copy)", @@ -117,6 +120,7 @@ class RequestModel { RequestModel copyWith({ String? id, + ProtocolType? protocol, HTTPVerb? method, String? url, String? name, @@ -141,6 +145,7 @@ class RequestModel { var formDataList = requestFormDataList ?? this.requestFormDataList; return RequestModel( id: id ?? this.id, + protocol: protocol ?? this.protocol, method: method ?? this.method, url: url ?? this.url, name: name ?? this.name, @@ -162,11 +167,17 @@ class RequestModel { } factory RequestModel.fromJson(Map data) { + ProtocolType protocol; HTTPVerb method; ContentType requestBodyContentType; ResponseModel? responseModel; final id = data["id"] as String; + try { + protocol = ProtocolType.values.byName(data["protocol"] as String); + } catch (e) { + protocol = kDefaultProtocolType; + } try { method = HTTPVerb.values.byName(data["method"] as String); } catch (e) { @@ -200,6 +211,7 @@ class RequestModel { return RequestModel( id: id, + protocol: protocol, method: method, url: url, name: name ?? "", @@ -227,6 +239,7 @@ class RequestModel { Map toJson({bool includeResponse = true}) { return { "id": id, + "protocol": protocol.name, "method": method.name, "url": url, "name": name, @@ -248,6 +261,7 @@ class RequestModel { String toString() { return [ "Request Id: $id", + "Request Protocol: ${protocol.name}", "Request Method: ${method.name}", "Request URL: $url", "Request Name: $name", @@ -271,6 +285,7 @@ class RequestModel { return other is RequestModel && other.runtimeType == runtimeType && other.id == id && + other.protocol == protocol && other.method == method && other.url == url && other.name == name && @@ -293,6 +308,7 @@ class RequestModel { return Object.hash( runtimeType, id, + protocol, method, url, name, diff --git a/lib/providers/collection_providers.dart b/lib/providers/collection_providers.dart index db6b7cf33..fa6dd47a1 100644 --- a/lib/providers/collection_providers.dart +++ b/lib/providers/collection_providers.dart @@ -129,6 +129,7 @@ class CollectionStateNotifier void update( String id, { + ProtocolType? protocol, HTTPVerb? method, String? url, String? name, @@ -146,6 +147,7 @@ class CollectionStateNotifier ResponseModel? responseModel, }) { final newModel = state![id]!.copyWith( + protocol: protocol, method: method, url: url, name: name, diff --git a/lib/screens/home_page/editor_pane/editor_request.dart b/lib/screens/home_page/editor_pane/editor_request.dart index 90a603493..b23b4e8fe 100644 --- a/lib/screens/home_page/editor_pane/editor_request.dart +++ b/lib/screens/home_page/editor_pane/editor_request.dart @@ -40,6 +40,8 @@ class RequestEditorTopBar extends ConsumerWidget { ), child: Row( children: [ + const DropdownButtonProtocol(), + kHSpacer20, Expanded( child: Text( name ?? "", diff --git a/lib/screens/home_page/editor_pane/url_card.dart b/lib/screens/home_page/editor_pane/url_card.dart index 012d067c0..63ef2c99e 100644 --- a/lib/screens/home_page/editor_pane/url_card.dart +++ b/lib/screens/home_page/editor_pane/url_card.dart @@ -41,6 +41,28 @@ class EditorPaneRequestURLCard extends StatelessWidget { } } +class DropdownButtonProtocol extends ConsumerWidget { + const DropdownButtonProtocol({ + super.key, + }); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final protocol = ref + .watch(selectedRequestModelProvider.select((value) => value?.protocol)); + return DropdownButtonProtocolType( + protocolType: protocol, + onChanged: (ProtocolType? value) { + final selectedId = ref.read(selectedRequestModelProvider)!.id; + ref + .read(collectionStateNotifierProvider.notifier) + .update(selectedId, protocol: protocol); + print('protocol: $value'); + }, + ); + } +} + class DropdownButtonHTTPMethod extends ConsumerWidget { const DropdownButtonHTTPMethod({ super.key, diff --git a/lib/widgets/dropdowns.dart b/lib/widgets/dropdowns.dart index 69008a6b7..2336e2d7d 100644 --- a/lib/widgets/dropdowns.dart +++ b/lib/widgets/dropdowns.dart @@ -47,6 +47,56 @@ class DropdownButtonHttpMethod extends StatelessWidget { } } +class DropdownButtonProtocolType extends StatelessWidget { + const DropdownButtonProtocolType({ + super.key, + this.protocolType, + this.onChanged, + }); + + final ProtocolType? protocolType; + final void Function(ProtocolType? value)? onChanged; + + @override + Widget build(BuildContext context) { + final surfaceColor = Theme.of(context).colorScheme.surface; + return DropdownButton( + isDense: true, + focusColor: surfaceColor, + value: protocolType, + icon: const Icon( + Icons.unfold_more_rounded, + size: 16, + ), + elevation: 4, + underline: Container( + height: 0, + ), + borderRadius: kBorderRadius12, + onChanged: onChanged, + items: ProtocolType.values + .map>((ProtocolType value) { + return DropdownMenuItem( + value: value, + child: Padding( + padding: const EdgeInsets.only(left: 16), + child: Text( + value.name.toUpperCase(), + style: kCodeStyle.copyWith( + fontWeight: FontWeight.bold, + color: Theme.of(context).brightness == Brightness.dark + ? getDarkModeColor(Colors.white) + : Colors.black, + fontSize: 14, + ), + ), + ), + ); + }).toList(), + ); + } +} + class DropdownButtonContentType extends StatelessWidget { const DropdownButtonContentType({ super.key, diff --git a/test/models/request_model_test.dart b/test/models/request_model_test.dart index b7dbb413d..6742d3c4b 100644 --- a/test/models/request_model_test.dart +++ b/test/models/request_model_test.dart @@ -98,6 +98,7 @@ void main() { Map requestModelAsJson = { "id": '1', + "protocol": 'http', "method": 'post', "url": 'api.apidash.dev/case/lower', "name": 'foss42 api', @@ -137,6 +138,7 @@ void main() { final requestModeDupString = [ "Request Id: 1", + "Request Protocol: http", "Request Method: post", "Request URL: api.apidash.dev/case/lower", "Request Name: foss42 api", diff --git a/test/widgets/dropdowns_test.dart b/test/widgets/dropdowns_test.dart index 7d304ce8e..9e3ef2bcc 100644 --- a/test/widgets/dropdowns_test.dart +++ b/test/widgets/dropdowns_test.dart @@ -171,4 +171,48 @@ void main() { expect(changedValue, CodegenLanguage.dartDio); }); + testWidgets('Testing Dropdown for ProtocolType', (tester) async { + ProtocolType? changedValue; + await tester.pumpWidget( + MaterialApp( + title: 'Dropdown ProtocolType testing', + theme: ThemeData.light(), + home: Scaffold( + body: Center( + child: Column( + children: [ + DropdownButtonProtocolType( + protocolType: ProtocolType.values.first, + onChanged: (value) { + changedValue = value; + }, + ), + ], + ), + ), + ), + ), + ); + + expect(find.byIcon(Icons.unfold_more_rounded), findsOneWidget); + expect(find.byType(DropdownButton), findsOneWidget); + expect( + (tester.widget(find.byType(DropdownButton)) + as DropdownButton) + .value, + equals(ProtocolType.values.first)); + + if (ProtocolType.values.length > 1) { + await tester.tap(find.text(ProtocolType.values.first.name.toUpperCase())); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + + await tester + .tap(find.text(ProtocolType.values[1].name.toUpperCase()).last); + await tester.pump(); + await tester.pump(const Duration(seconds: 1)); + + expect(changedValue, ProtocolType.values[1]); + } + }); }