mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 18:57:05 +08:00
test: add comprehensive tests for oauth fields
This commit is contained in:
@@ -390,7 +390,9 @@ const httpRequestModelGet4Json = <String, dynamic>{
|
||||
'bearer': null,
|
||||
'basic': null,
|
||||
'jwt': null,
|
||||
'digest': null
|
||||
'digest': null,
|
||||
'oauth1': null,
|
||||
'oauth2': null
|
||||
},
|
||||
"isHeaderEnabledList": null,
|
||||
"isParamEnabledList": null,
|
||||
@@ -417,7 +419,9 @@ const httpRequestModelPost10Json = <String, dynamic>{
|
||||
'bearer': null,
|
||||
'basic': null,
|
||||
'jwt': null,
|
||||
'digest': null
|
||||
'digest': null,
|
||||
'oauth1': null,
|
||||
'oauth2': null
|
||||
},
|
||||
'isHeaderEnabledList': [false, true],
|
||||
'isParamEnabledList': null,
|
||||
|
||||
568
test/screens/common_widgets/auth/oauth1_fields_test.dart
Normal file
568
test/screens/common_widgets/auth/oauth1_fields_test.dart
Normal file
@@ -0,0 +1,568 @@
|
||||
import 'package:apidash/screens/common_widgets/auth/oauth1_fields.dart';
|
||||
import 'package:apidash/widgets/field_auth.dart';
|
||||
import 'package:apidash_core/apidash_core.dart';
|
||||
import 'package:apidash_design_system/apidash_design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:apidash/providers/settings_providers.dart';
|
||||
import 'package:apidash/providers/collection_providers.dart';
|
||||
import 'package:apidash/models/models.dart';
|
||||
|
||||
void main() {
|
||||
group('OAuth1Fields Widget Tests', () {
|
||||
late AuthModel? mockAuthData;
|
||||
late Function(AuthModel?) mockUpdateAuth;
|
||||
late List<AuthModel?> capturedAuthUpdates;
|
||||
|
||||
setUp(() {
|
||||
capturedAuthUpdates = [];
|
||||
mockUpdateAuth = (AuthModel? authModel) {
|
||||
capturedAuthUpdates.add(authModel);
|
||||
};
|
||||
});
|
||||
|
||||
// Helper function to wrap OAuth1Fields widget with proper layout constraints
|
||||
|
||||
testWidgets('renders with default values when authData is null',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = null;
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(AuthTextField), findsNWidgets(9));
|
||||
expect(find.byType(ADPopupMenu<OAuth1SignatureMethod>), findsOneWidget);
|
||||
expect(find.text('Signature Method'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('renders with existing OAuth1 auth data',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'test_consumer_key',
|
||||
consumerSecret: 'test_consumer_secret',
|
||||
accessToken: 'test_access_token',
|
||||
tokenSecret: 'test_token_secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
callbackUrl: 'http://api.apidash.dev/callback',
|
||||
verifier: 'test_verifier',
|
||||
timestamp: '1234567890',
|
||||
nonce: 'test_nonce',
|
||||
realm: 'test_realm',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(AuthTextField), findsNWidgets(9));
|
||||
expect(find.byType(ADPopupMenu<OAuth1SignatureMethod>), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when consumer key changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'old_key',
|
||||
consumerSecret: 'secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the consumer key field (first AuthTextField)
|
||||
final consumerKeyField = find.byType(AuthTextField).first;
|
||||
await tester.tap(consumerKeyField);
|
||||
await tester.enterText(consumerKeyField, 'new_consumer_key');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(lastUpdate?.oauth1?.consumerKey, 'new_consumer_key');
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when consumer secret changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'old_secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the consumer secret field (second AuthTextField)
|
||||
final consumerSecretField = find.byType(AuthTextField).at(1);
|
||||
await tester.tap(consumerSecretField);
|
||||
await tester.enterText(consumerSecretField, 'new_consumer_secret');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(lastUpdate?.oauth1?.consumerSecret, 'new_consumer_secret');
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when signature method changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find and tap the signature method dropdown
|
||||
final signatureMethodDropdown =
|
||||
find.byType(ADPopupMenu<OAuth1SignatureMethod>);
|
||||
await tester.tap(signatureMethodDropdown);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Select a different signature method
|
||||
await tester.tap(find.text('Plaintext').last);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(
|
||||
lastUpdate?.oauth1?.signatureMethod, OAuth1SignatureMethod.plaintext);
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when access token changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'secret',
|
||||
accessToken: 'old_token',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the access token field (3rd AuthTextField, after consumer key, secret, and before signature method dropdown)
|
||||
final accessTokenField = find.byType(AuthTextField).at(2);
|
||||
await tester.tap(accessTokenField);
|
||||
await tester.enterText(accessTokenField, 'new_access_token');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(lastUpdate?.oauth1?.accessToken, 'new_access_token');
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
|
||||
testWidgets('respects readOnly property', (WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
readOnly: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Verify that AuthTextField widgets are rendered
|
||||
expect(find.byType(AuthTextField), findsNWidgets(9));
|
||||
expect(find.byType(ADPopupMenu<OAuth1SignatureMethod>), findsOneWidget);
|
||||
|
||||
// The readOnly property should be passed to AuthTextField widgets
|
||||
// This is verified by the widget structure itself
|
||||
});
|
||||
|
||||
testWidgets('handles empty auth data gracefully',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: '',
|
||||
consumerSecret: '',
|
||||
accessToken: '',
|
||||
tokenSecret: '',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(AuthTextField), findsNWidgets(9));
|
||||
expect(find.byType(ADPopupMenu<OAuth1SignatureMethod>), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'creates proper AuthModel on field changes when authData is null',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = null;
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Enter consumer key
|
||||
final consumerKeyField = find.byType(AuthTextField).first;
|
||||
await tester.tap(consumerKeyField);
|
||||
await tester.enterText(consumerKeyField, 'test_consumer_key');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called with correct structure
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
expect(lastUpdate?.oauth1?.consumerKey, 'test_consumer_key');
|
||||
});
|
||||
|
||||
testWidgets('displays correct hint texts', (WidgetTester tester) async {
|
||||
mockAuthData = null;
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(AuthTextField), findsNWidgets(9));
|
||||
expect(find.text('Signature Method'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when token secret changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'secret',
|
||||
accessToken: 'token',
|
||||
tokenSecret: 'old_token_secret',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the token secret field (4th AuthTextField)
|
||||
final tokenSecretField = find.byType(AuthTextField).at(3);
|
||||
await tester.tap(tokenSecretField);
|
||||
await tester.enterText(tokenSecretField, 'new_token_secret');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(lastUpdate?.oauth1?.tokenSecret, 'new_token_secret');
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
|
||||
testWidgets('updates auth data when callback URL changes',
|
||||
(WidgetTester tester) async {
|
||||
mockAuthData = const AuthModel(
|
||||
type: APIAuthType.oauth1,
|
||||
oauth1: AuthOAuth1Model(
|
||||
consumerKey: 'key',
|
||||
consumerSecret: 'secret',
|
||||
callbackUrl: 'http://old.api.apidash.dev/callback',
|
||||
signatureMethod: OAuth1SignatureMethod.hmacSha1,
|
||||
parameterLocation: 'url',
|
||||
credentialsFilePath: '/test/path',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ProviderScope(
|
||||
overrides: [
|
||||
settingsProvider.overrideWith((ref) => ThemeStateNotifier(
|
||||
settingsModel: const SettingsModel(
|
||||
workspaceFolderPath: '/test/workspace',
|
||||
),
|
||||
)),
|
||||
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||
],
|
||||
child: MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: OAuth1Fields(
|
||||
authData: mockAuthData,
|
||||
updateAuth: mockUpdateAuth,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// Find the callback URL field (5th AuthTextField)
|
||||
final callbackUrlField = find.byType(AuthTextField).at(4);
|
||||
await tester.tap(callbackUrlField);
|
||||
await tester.enterText(
|
||||
callbackUrlField, 'http://api.apidash.dev/callback');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Verify that updateAuth was called
|
||||
expect(capturedAuthUpdates.length, greaterThan(0));
|
||||
final lastUpdate = capturedAuthUpdates.last;
|
||||
expect(
|
||||
lastUpdate?.oauth1?.callbackUrl, 'http://api.apidash.dev/callback');
|
||||
expect(lastUpdate?.type, APIAuthType.oauth1);
|
||||
});
|
||||
});
|
||||
}
|
||||
1412
test/screens/common_widgets/auth/oauth2_fields_test.dart
Normal file
1412
test/screens/common_widgets/auth/oauth2_fields_test.dart
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user