mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 02:39:19 +08:00
1735 lines
55 KiB
Dart
1735 lines
55 KiB
Dart
import 'dart:convert';
|
|
import 'package:apidash/services/flutter_js_service.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:apidash_core/apidash_core.dart';
|
|
import 'package:apidash/models/models.dart';
|
|
import 'package:apidash/utils/pre_post_script_utils.dart';
|
|
|
|
// Base HTTP Request Model for GET request
|
|
const HttpRequestModel baseGetRequest = HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/users',
|
|
headers: [
|
|
NameValueModel(name: 'Content-Type', value: 'application/json'),
|
|
NameValueModel(name: 'User-Agent', value: 'APIDash/1.0'),
|
|
],
|
|
params: [
|
|
NameValueModel(name: 'page', value: '1'),
|
|
NameValueModel(name: 'limit', value: '10'),
|
|
],
|
|
);
|
|
|
|
// HTTP Request Model for POST request with body
|
|
const HttpRequestModel basePostRequest = HttpRequestModel(
|
|
method: HTTPVerb.post,
|
|
url: 'https://api.apidash.dev/auth/login',
|
|
headers: [
|
|
NameValueModel(name: 'Content-Type', value: 'application/json'),
|
|
NameValueModel(name: 'Accept', value: 'application/json'),
|
|
],
|
|
body: '{"username": "testuser", "password": "testpass"}',
|
|
);
|
|
|
|
// GraphQL Request Model
|
|
const HttpRequestModel baseGraphQLRequest = HttpRequestModel(
|
|
method: HTTPVerb.post,
|
|
url: 'https://api.apidash.dev/graphql',
|
|
headers: [
|
|
NameValueModel(name: 'Content-Type', value: 'application/json'),
|
|
],
|
|
query: r'query GetUser($id: ID!) { user(id: $id) { name email } }',
|
|
body: '{"variables": {"id": "123"}}',
|
|
);
|
|
|
|
// HTTP Response Model for successful login
|
|
const HttpResponseModel successLoginResponse = HttpResponseModel(
|
|
statusCode: 200,
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
'x-auth-token': 'Bearer jwt-token-abc123',
|
|
'set-cookie': 'sessionid=sess_123; Path=/; HttpOnly',
|
|
},
|
|
body:
|
|
'{"success": true, "token": "jwt-token-abc123", "user": {"id": "user_123", "name": "Test User", "email": "test@example.com"}, "expires_in": 3600}',
|
|
time: Duration(milliseconds: 150),
|
|
);
|
|
|
|
// HTTP Response Model for error case
|
|
const HttpResponseModel errorResponse = HttpResponseModel(
|
|
statusCode: 401,
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
'www-authenticate': 'Bearer',
|
|
},
|
|
body:
|
|
'{"error": "invalid_credentials", "message": "Invalid username or password"}',
|
|
time: Duration(milliseconds: 89),
|
|
);
|
|
|
|
// HTTP Response Model for API list response
|
|
const HttpResponseModel usersListResponse = HttpResponseModel(
|
|
statusCode: 200,
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
'x-total-count': '150',
|
|
'x-page': '1',
|
|
},
|
|
body:
|
|
'{"users": [{"id": "1", "name": "Alice", "status": "active"}, {"id": "2", "name": "Bob", "status": "inactive"}], "pagination": {"page": 1, "limit": 10, "total": 150}}',
|
|
time: Duration(milliseconds: 95),
|
|
);
|
|
|
|
// Environment Model with various variable types
|
|
const EnvironmentModel testEnvironment = EnvironmentModel(
|
|
id: 'test-env',
|
|
name: 'Test Environment',
|
|
values: [
|
|
EnvironmentVariableModel(
|
|
key: 'baseUrl',
|
|
value: 'https://api.apidash.dev',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'apiKey',
|
|
value: 'secret-api-key-123',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.secret,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'timeout',
|
|
value: '5000',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'debugMode',
|
|
value: 'true',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'disabledVar',
|
|
value: 'should-not-be-used',
|
|
enabled: false,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
],
|
|
);
|
|
|
|
// Request Models with different scripts
|
|
RequestModel requestWithHeaderModificationScript = RequestModel(
|
|
id: 'header-mod-request',
|
|
name: 'Header Modification Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
ad.request.headers.set('Authorization', 'Bearer ' + ad.environment.get('apiKey'));
|
|
ad.request.headers.set('X-Custom-Header', 'custom-value');
|
|
ad.request.headers.remove('User-Agent');
|
|
ad.console.log('Headers modified');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithUrlModificationScript = RequestModel(
|
|
id: 'url-mod-request',
|
|
name: 'URL Modification Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
const baseUrl = ad.environment.get('baseUrl');
|
|
ad.request.url.set(baseUrl + '/v2/users');
|
|
ad.request.params.set('version', 'v2');
|
|
ad.request.params.remove('page');
|
|
ad.console.log('URL and params modified');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithBodyModificationScript = RequestModel(
|
|
id: 'body-mod-request',
|
|
name: 'Body Modification Test',
|
|
httpRequestModel: basePostRequest,
|
|
preRequestScript: '''
|
|
const currentBody = JSON.parse(ad.request.body.get() || '{}');
|
|
currentBody.timestamp = new Date().toISOString();
|
|
currentBody.apiKey = ad.environment.get('apiKey');
|
|
ad.request.body.set(currentBody);
|
|
ad.console.log('Body modified with timestamp and API key');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithGraphQLScript = RequestModel(
|
|
id: 'graphql-request',
|
|
name: 'GraphQL Query Modification Test',
|
|
httpRequestModel: baseGraphQLRequest,
|
|
preRequestScript: r'''
|
|
const userId = ad.environment.get('userId') || '123';
|
|
ad.request.query.set('query GetUser($id: ID!) { user(id: $id) { name email roles { name } } }');
|
|
const variables = JSON.parse(ad.request.body.get() || '{}');
|
|
variables.variables.id = userId;
|
|
ad.request.body.set(variables);
|
|
ad.console.log('GraphQL query and variables updated');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithEnvironmentUpdateScript = RequestModel(
|
|
id: 'env-update-request',
|
|
name: 'Environment Update Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
ad.environment.set('requestId', 'req_' + Date.now());
|
|
ad.environment.set('retryCount', 0);
|
|
ad.environment.unset('debugMode');
|
|
ad.environment.set('newVariable', 'created-in-script');
|
|
ad.console.log('Environment variables updated');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithComplexScript = RequestModel(
|
|
id: 'complex-request',
|
|
name: 'Complex Pre-request Script Test',
|
|
httpRequestModel: basePostRequest,
|
|
preRequestScript: '''
|
|
// Modify headers
|
|
ad.request.headers.set('Authorization', 'Bearer ' + ad.environment.get('apiKey'));
|
|
ad.request.headers.set('X-Request-ID', 'req_' + Date.now());
|
|
|
|
// Modify URL
|
|
const baseUrl = ad.environment.get('baseUrl');
|
|
ad.request.url.set(baseUrl + '/auth/login');
|
|
|
|
// Modify body
|
|
const body = JSON.parse(ad.request.body.get() || '{}');
|
|
body.client_id = 'apidash-client';
|
|
body.timestamp = new Date().toISOString();
|
|
ad.request.body.set(body);
|
|
|
|
// Update environment
|
|
ad.environment.set('lastRequestTime', new Date().toISOString());
|
|
ad.environment.set('requestCount', (parseInt(ad.environment.get('requestCount') || '0') + 1).toString());
|
|
|
|
ad.console.log('Complex pre-request script executed successfully');
|
|
''',
|
|
);
|
|
|
|
// Post-response script request models
|
|
RequestModel requestWithTokenExtractionScript = RequestModel(
|
|
id: 'token-extract-request',
|
|
name: 'Token Extraction Test',
|
|
httpRequestModel: basePostRequest,
|
|
httpResponseModel: successLoginResponse,
|
|
postRequestScript: '''
|
|
if (ad.response.status === 200) {
|
|
const data = ad.response.json();
|
|
if (data && data.token) {
|
|
ad.environment.set('authToken', data.token);
|
|
ad.environment.set('userId', data.user.id);
|
|
ad.console.log('Token and user ID extracted successfully');
|
|
} else {
|
|
ad.console.error('Token not found in response');
|
|
}
|
|
} else {
|
|
ad.console.error('Login failed with status: ' + ad.response.status);
|
|
}
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithHeaderExtractionScript = RequestModel(
|
|
id: 'header-extract-request',
|
|
name: 'Header Extraction Test',
|
|
httpRequestModel: baseGetRequest,
|
|
httpResponseModel: successLoginResponse,
|
|
postRequestScript: '''
|
|
const authHeader = ad.response.getHeader('x-auth-token');
|
|
if (authHeader) {
|
|
ad.environment.set('extractedAuthToken', authHeader);
|
|
}
|
|
|
|
const sessionCookie = ad.response.getHeader('set-cookie');
|
|
if (sessionCookie) {
|
|
const sessionId = sessionCookie.match(/sessionid=([^;]+)/);
|
|
if (sessionId) {
|
|
ad.environment.set('sessionId', sessionId[1]);
|
|
}
|
|
}
|
|
|
|
ad.console.log('Headers extracted and processed');
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithStatusCheckScript = RequestModel(
|
|
id: 'status-check-request',
|
|
name: 'Status Check Test',
|
|
httpRequestModel: baseGetRequest,
|
|
httpResponseModel: errorResponse,
|
|
postRequestScript: '''
|
|
ad.environment.set('lastResponseStatus', ad.response.status.toString());
|
|
ad.environment.set('lastResponseTime', ad.response.time.toString());
|
|
|
|
if (ad.response.status >= 400) {
|
|
const errorData = ad.response.json();
|
|
if (errorData && errorData.error) {
|
|
ad.environment.set('lastError', errorData.error);
|
|
ad.environment.set('lastErrorMessage', errorData.message || 'Unknown error');
|
|
}
|
|
ad.console.error('Request failed with error: ' + (errorData ? errorData.error : 'Unknown'));
|
|
} else {
|
|
ad.environment.unset('lastError');
|
|
ad.environment.unset('lastErrorMessage');
|
|
ad.console.log('Request succeeded');
|
|
}
|
|
''',
|
|
);
|
|
|
|
RequestModel requestWithDataProcessingScript = RequestModel(
|
|
id: 'data-processing-request',
|
|
name: 'Data Processing Test',
|
|
httpRequestModel: baseGetRequest,
|
|
httpResponseModel: usersListResponse,
|
|
postRequestScript: '''
|
|
const responseData = ad.response.json();
|
|
if (responseData && responseData.users) {
|
|
const activeUsers = responseData.users.filter(user => user.status === 'active');
|
|
ad.environment.set('activeUserCount', activeUsers.length.toString());
|
|
ad.environment.set('totalUsers', responseData.pagination.total.toString());
|
|
ad.environment.set('currentPage', responseData.pagination.page.toString());
|
|
|
|
if (activeUsers.length > 0) {
|
|
ad.environment.set('firstActiveUserId', activeUsers[0].id);
|
|
}
|
|
|
|
ad.console.log('Processed ' + responseData.users.length + ' users, ' + activeUsers.length + ' active');
|
|
} else {
|
|
ad.console.error('Invalid response structure');
|
|
}
|
|
''',
|
|
);
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
setUpAll(() {
|
|
initializeJsRuntime();
|
|
});
|
|
|
|
//TODO: For Pre-request Script add individual tests for every `ad` object methods
|
|
group('Pre-request Script Handler Tests', () {
|
|
late RequestModel baseRequestModel;
|
|
late EnvironmentModel testEnvironmentModel;
|
|
late HttpRequestModel testHttpRequest;
|
|
|
|
setUp(() {
|
|
testHttpRequest = const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test',
|
|
headers: [
|
|
NameValueModel(name: 'Content-Type', value: 'application/json'),
|
|
NameValueModel(name: 'User-Agent', value: 'TestApp'),
|
|
],
|
|
params: [
|
|
NameValueModel(name: 'page', value: '1'),
|
|
NameValueModel(name: 'limit', value: '10'),
|
|
],
|
|
);
|
|
baseRequestModel = RequestModel(
|
|
id: 'test-request-1',
|
|
name: 'Test Request',
|
|
description: 'A test request for unit testing',
|
|
httpRequestModel: testHttpRequest,
|
|
preRequestScript: 'ad.console.log("Pre-request script executed");',
|
|
);
|
|
testEnvironmentModel = const EnvironmentModel(
|
|
id: 'test-env-1',
|
|
name: 'Test Environment',
|
|
values: [
|
|
EnvironmentVariableModel(
|
|
key: 'apiUrl',
|
|
value: 'https://api.apidash.dev',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'apiKey',
|
|
value: 'test-api-key',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.secret,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'disabledVar',
|
|
value: 'disabled-value',
|
|
enabled: false,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
],
|
|
);
|
|
});
|
|
|
|
test('should execute pre-request script and return updated request model',
|
|
() async {
|
|
bool updateEnvCalled = false;
|
|
EnvironmentModel? capturedEnvModel;
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
updateEnvCalled = true;
|
|
capturedEnvModel = envModel;
|
|
capturedValues = values;
|
|
}
|
|
|
|
final result = await handlePreRequestScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
expect(result.httpRequestModel, isNotNull);
|
|
expect(result.httpRequestModel!.url, equals(testHttpRequest.url));
|
|
expect(result.httpRequestModel!.method, equals(testHttpRequest.method));
|
|
|
|
expect(updateEnvCalled, isTrue);
|
|
expect(capturedEnvModel, equals(testEnvironmentModel));
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should handle null environment model gracefully', () async {
|
|
final result = await handlePreRequestScript(
|
|
baseRequestModel,
|
|
null,
|
|
null,
|
|
);
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
expect(result.httpRequestModel, isNotNull);
|
|
});
|
|
|
|
test('should handle null updateEnv callback gracefully', () async {
|
|
final result = await handlePreRequestScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
null, // No updateEnv callback
|
|
);
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test('should update environment variables when script modifies them',
|
|
() async {
|
|
bool updateEnvCalled = false;
|
|
EnvironmentModel? capturedEnvModel;
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
updateEnvCalled = true;
|
|
capturedEnvModel = envModel;
|
|
capturedValues = values;
|
|
}
|
|
|
|
final modifiedRequestModel = baseRequestModel.copyWith(
|
|
preRequestScript: 'ad.environment.set("newVar", "newValue");',
|
|
);
|
|
final result = await handlePreRequestScript(
|
|
modifiedRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
expect(result, isA<RequestModel>());
|
|
expect(updateEnvCalled, isTrue);
|
|
expect(capturedEnvModel, equals(testEnvironmentModel));
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
//TODO: Fix this test misbehaviour
|
|
test(
|
|
'should preserve existing environment variables when script adds new ones',
|
|
() async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePreRequestScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
expect(capturedValues, isNotNull);
|
|
expect(capturedValues!.length,
|
|
greaterThanOrEqualTo(2)); // At least the enabled variables
|
|
|
|
final apiUrlVar = capturedValues!.firstWhere((v) => v.key == 'apiUrl');
|
|
expect(apiUrlVar.value, equals('https://api.apidash.dev'));
|
|
expect(apiUrlVar.enabled, isTrue);
|
|
|
|
final apiKeyVar = capturedValues!.firstWhere((v) => v.key == 'apiKey');
|
|
expect(apiKeyVar.value, equals('test-api-key'));
|
|
expect(apiKeyVar.enabled, isTrue);
|
|
});
|
|
|
|
test('should handle environment variable removal correctly', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
final modifiedRequestModel = baseRequestModel.copyWith(
|
|
preRequestScript: 'ad.environment.unset("apiKey");',
|
|
);
|
|
await handlePreRequestScript(
|
|
modifiedRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert - apiKey should not be in the result if properly removed
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should convert non-string values to strings', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
final modifiedRequestModel = baseRequestModel.copyWith(
|
|
preRequestScript: '''
|
|
ad.environment.set("numberVar", 42);
|
|
ad.environment.set("boolVar", true);
|
|
ad.environment.set("nullVar", null);
|
|
''',
|
|
);
|
|
await handlePreRequestScript(
|
|
modifiedRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should handle empty script gracefully', () async {
|
|
final emptyScriptModel = baseRequestModel.copyWith(preRequestScript: '');
|
|
|
|
final result = await handlePreRequestScript(
|
|
emptyScriptModel,
|
|
testEnvironmentModel,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test('should handle null script gracefully', () async {
|
|
final nullScriptModel = baseRequestModel.copyWith(preRequestScript: null);
|
|
|
|
final result = await handlePreRequestScript(
|
|
nullScriptModel,
|
|
testEnvironmentModel,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test(
|
|
'should return the same original request model when no environment and script updates environment',
|
|
() async {
|
|
final scriptWithEnvUpdate = baseRequestModel.copyWith(
|
|
preRequestScript: 'ad.environment.set("newVar", "value");',
|
|
);
|
|
final result = await handlePreRequestScript(
|
|
scriptWithEnvUpdate,
|
|
null,
|
|
null,
|
|
);
|
|
expect(result, equals(scriptWithEnvUpdate));
|
|
});
|
|
});
|
|
|
|
group('Post-response Script Handler Tests', () {
|
|
late RequestModel baseRequestModel;
|
|
late EnvironmentModel testEnvironmentModel;
|
|
late HttpRequestModel testHttpRequest;
|
|
late HttpResponseModel testHttpResponse;
|
|
|
|
setUp(() {
|
|
testHttpRequest = const HttpRequestModel(
|
|
method: HTTPVerb.post,
|
|
url: 'https://api.apidash.dev/login',
|
|
headers: [
|
|
NameValueModel(name: 'Content-Type', value: 'application/json'),
|
|
],
|
|
body: '{"username": "ad", "password": "ad123"}',
|
|
);
|
|
|
|
testHttpResponse = const HttpResponseModel(
|
|
statusCode: 200,
|
|
headers: {
|
|
'content-type': 'application/json',
|
|
'x-correlation-id': 'abc-123-def',
|
|
},
|
|
body: '{"token": "jwt-token-123", "expires_in": 3600}',
|
|
time: Duration(milliseconds: 250),
|
|
);
|
|
|
|
baseRequestModel = RequestModel(
|
|
id: 'test-request-2',
|
|
name: 'Login Request',
|
|
description: 'A login request for testing',
|
|
httpRequestModel: testHttpRequest,
|
|
httpResponseModel: testHttpResponse,
|
|
postRequestScript: 'ad.console.log("Post-response script executed");',
|
|
);
|
|
|
|
testEnvironmentModel = const EnvironmentModel(
|
|
id: 'test-env-2',
|
|
name: 'Test Environment',
|
|
values: [
|
|
EnvironmentVariableModel(
|
|
key: 'baseUrl',
|
|
value: 'https://api.apidash.dev',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
EnvironmentVariableModel(
|
|
key: 'oldToken',
|
|
value: 'old-jwt-token',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.secret,
|
|
),
|
|
],
|
|
);
|
|
});
|
|
|
|
test('should execute post-response script and return updated request model',
|
|
() async {
|
|
// Arrange
|
|
bool updateEnvCalled = false;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
updateEnvCalled = true;
|
|
}
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
expect(result.httpResponseModel, isNotNull);
|
|
expect(result.httpResponseModel!.statusCode, equals(200));
|
|
expect(updateEnvCalled, isTrue);
|
|
});
|
|
|
|
test('should handle null environment model gracefully', () async {
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
baseRequestModel,
|
|
null, // No environment model
|
|
null,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
expect(result.httpResponseModel, isNotNull);
|
|
});
|
|
|
|
test('should extract data from response and update environment', () async {
|
|
// Arrange
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// Mock a script that extracts token from response
|
|
final tokenExtractionModel = baseRequestModel.copyWith(
|
|
postRequestScript: '''
|
|
const data = ad.response.json();
|
|
if (data && data.token) {
|
|
ad.environment.set("authToken", data.token);
|
|
ad.environment.set("tokenExpiry", Date.now() + (data.expires_in * 1000));
|
|
}
|
|
''',
|
|
);
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
tokenExtractionModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should handle response status checking scripts', () async {
|
|
// Arrange
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// Mock a script that checks response status
|
|
final statusCheckModel = baseRequestModel.copyWith(
|
|
postRequestScript: '''
|
|
if (ad.response.status === 200) {
|
|
ad.environment.set("lastRequestStatus", "success");
|
|
} else {
|
|
ad.environment.set("lastRequestStatus", "failed");
|
|
}
|
|
ad.environment.set("lastResponseTime", ad.response.time);
|
|
''',
|
|
);
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
statusCheckModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should handle header extraction from response', () async {
|
|
// Arrange
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// Mock a script that extracts headers
|
|
final headerExtractionModel = baseRequestModel.copyWith(
|
|
postRequestScript: '''
|
|
const correlationId = ad.response.getHeader("X-Correlation-ID");
|
|
if (correlationId) {
|
|
ad.environment.set("lastCorrelationId", correlationId);
|
|
}
|
|
|
|
const contentType = ad.response.getHeader("content-type");
|
|
ad.environment.set("lastContentType", contentType || "unknown");
|
|
''',
|
|
);
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
headerExtractionModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(capturedValues, isNotNull);
|
|
});
|
|
|
|
test('should preserve existing environment variables', () async {
|
|
// Arrange
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// Act
|
|
await handlePostResponseScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(capturedValues, isNotNull);
|
|
expect(capturedValues!.length, greaterThanOrEqualTo(2));
|
|
|
|
final baseUrlVar = capturedValues!.firstWhere((v) => v.key == 'baseUrl');
|
|
expect(baseUrlVar.value, equals('https://api.apidash.dev'));
|
|
expect(baseUrlVar.enabled, isTrue);
|
|
});
|
|
|
|
test('should handle environment variable updates with different data types',
|
|
() async {
|
|
// Arrange
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// There's a bug in the post-response script handler - it's missing the value assignment
|
|
// Let's test this to verify the bug
|
|
final dataTypeModel = baseRequestModel.copyWith(
|
|
postRequestScript: '''
|
|
ad.environment.set("stringVar", "hello");
|
|
ad.environment.set("numberVar", 123);
|
|
ad.environment.set("boolVar", false);
|
|
ad.environment.set("nullVar", null);
|
|
''',
|
|
);
|
|
|
|
// Act
|
|
await handlePostResponseScript(
|
|
dataTypeModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert
|
|
expect(capturedValues, isNotNull);
|
|
// Note: This test reveals a bug in handlePostResponseScript where value is not being set
|
|
});
|
|
|
|
test('should handle empty post-response script', () async {
|
|
// Arrange
|
|
final emptyScriptModel = baseRequestModel.copyWith(postRequestScript: '');
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
emptyScriptModel,
|
|
testEnvironmentModel,
|
|
null,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test('should handle null post-response script', () async {
|
|
// Arrange
|
|
final nullScriptModel =
|
|
baseRequestModel.copyWith(postRequestScript: null);
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
nullScriptModel,
|
|
testEnvironmentModel,
|
|
null,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test(
|
|
'should return updated model when no environment but script updates environment',
|
|
() async {
|
|
// Arrange
|
|
final scriptWithEnvUpdate = baseRequestModel.copyWith(
|
|
postRequestScript: 'ad.environment.set("responseVar", "value");',
|
|
);
|
|
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
scriptWithEnvUpdate,
|
|
null, // No environment
|
|
null,
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test('should handle null updateEnv callback gracefully', () async {
|
|
// Act
|
|
final result = await handlePostResponseScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
null, // No updateEnv callback
|
|
);
|
|
|
|
// Assert
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.id, equals(baseRequestModel.id));
|
|
});
|
|
|
|
test('should test the bug in post-response handler value assignment',
|
|
() async {
|
|
// This test specifically tests for the bug where value is not being assigned in post-response handler
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
// Act
|
|
await handlePostResponseScript(
|
|
baseRequestModel,
|
|
testEnvironmentModel,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
// Assert - Check for the bug where values are not properly assigned
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Find the original variables and verify they keep their values correctly
|
|
final originalVar = capturedValues!.firstWhere((v) => v.key == 'baseUrl');
|
|
expect(originalVar.value, equals('https://api.apidash.dev'));
|
|
|
|
// This assertion might fail due to the bug in the implementation
|
|
// where `value: newValue == null ? '' : newValue.toString(),` line is missing
|
|
// in the post-response handler
|
|
});
|
|
});
|
|
|
|
group('Both Pre-request and Post-response testing together', () {
|
|
test('should handle complex workflow with both pre and post scripts',
|
|
() async {
|
|
// Arrange
|
|
final complexRequest = RequestModel(
|
|
id: 'complex-request',
|
|
name: 'Complex Workflow',
|
|
preRequestScript: '''
|
|
ad.environment.set("requestStartTime", Date.now());
|
|
ad.request.headers.set("X-Request-ID", "req-" + Math.random());
|
|
''',
|
|
postRequestScript: '''
|
|
const startTime = ad.environment.get("requestStartTime");
|
|
const endTime = Date.now();
|
|
ad.environment.set("requestDuration", endTime - startTime);
|
|
|
|
if (ad.response.status === 200) {
|
|
ad.environment.set("lastSuccessfulRequest", Date.now());
|
|
}
|
|
''',
|
|
httpRequestModel: const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/data',
|
|
),
|
|
httpResponseModel: const HttpResponseModel(
|
|
statusCode: 200,
|
|
body: '{"success": true}',
|
|
),
|
|
);
|
|
|
|
final environment = const EnvironmentModel(
|
|
id: 'integration-env',
|
|
name: 'Integration Environment',
|
|
values: [],
|
|
);
|
|
|
|
void preUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
// Mock function for testing
|
|
}
|
|
|
|
void postUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
// Mock function for testing
|
|
}
|
|
|
|
final afterPre = await handlePreRequestScript(
|
|
complexRequest,
|
|
environment,
|
|
preUpdateEnv,
|
|
);
|
|
|
|
final afterPost = await handlePostResponseScript(
|
|
afterPre,
|
|
environment,
|
|
postUpdateEnv,
|
|
);
|
|
expect(afterPre, isA<RequestModel>());
|
|
expect(afterPost, isA<RequestModel>());
|
|
expect(afterPost.id, equals(complexRequest.id));
|
|
});
|
|
|
|
test('should handle environment variable dependencies between scripts',
|
|
() async {
|
|
// This test ensures that environment changes from pre-request scripts
|
|
// are available to post-response scripts
|
|
final dependentRequest = RequestModel(
|
|
id: 'dependent-request',
|
|
name: 'Dependent Request',
|
|
preRequestScript: 'ad.environment.set("requestId", "12345");',
|
|
postRequestScript: '''
|
|
const requestId = ad.environment.get("requestId");
|
|
ad.environment.set("completedRequestId", requestId);
|
|
''',
|
|
httpRequestModel: const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test',
|
|
),
|
|
httpResponseModel: const HttpResponseModel(
|
|
statusCode: 200,
|
|
body: '{"data": "test"}',
|
|
),
|
|
);
|
|
|
|
final environment = const EnvironmentModel(
|
|
id: 'dependent-env',
|
|
name: 'Dependent Environment',
|
|
values: [],
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? preValues;
|
|
List<EnvironmentVariableModel>? postValues;
|
|
|
|
void preUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
preValues = values;
|
|
}
|
|
|
|
void postUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
postValues = values;
|
|
}
|
|
|
|
final afterPre = await handlePreRequestScript(
|
|
dependentRequest,
|
|
environment,
|
|
preUpdateEnv,
|
|
);
|
|
|
|
await handlePostResponseScript(
|
|
afterPre,
|
|
environment,
|
|
postUpdateEnv,
|
|
);
|
|
expect(preValues, isNotNull);
|
|
expect(postValues, isNotNull);
|
|
});
|
|
});
|
|
|
|
group('Error Handling Tests', () {
|
|
test('should handle malformed JavaScript', () async {
|
|
final malformedRequest = RequestModel(
|
|
id: 'malformed-request',
|
|
name: 'Malformed Script Request',
|
|
preRequestScript: 'ad.environment.set("test", ; // Syntax error',
|
|
httpRequestModel: const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test',
|
|
),
|
|
);
|
|
|
|
final environment = const EnvironmentModel(
|
|
id: 'error-env',
|
|
name: 'Error Environment',
|
|
values: [],
|
|
);
|
|
final result = await handlePreRequestScript(
|
|
malformedRequest,
|
|
environment,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
});
|
|
|
|
test('should handle empty environment values list', () async {
|
|
final emptyEnvModel = const EnvironmentModel(
|
|
id: 'empty-env',
|
|
name: 'Empty Environment',
|
|
values: [],
|
|
);
|
|
|
|
final request = RequestModel(
|
|
id: 'test-empty-env',
|
|
name: 'Test Empty Environment',
|
|
preRequestScript: 'ad.environment.set("newVar", "value");',
|
|
httpRequestModel: const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test',
|
|
),
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
|
|
void updateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
final result = await handlePreRequestScript(
|
|
request,
|
|
emptyEnvModel,
|
|
updateEnv,
|
|
);
|
|
expect(result, isA<RequestModel>());
|
|
expect(capturedValues, isNotNull);
|
|
expect(capturedValues?.length, 1);
|
|
});
|
|
|
|
test('should handle accessing non-existent environment variables',
|
|
() async {
|
|
final scriptWithMissingVar = RequestModel(
|
|
id: 'missing-var-request',
|
|
name: 'Missing Variable Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
const missingVar = ad.environment.get('nonExistentVar');
|
|
ad.request.headers.set('X-Missing-Var', missingVar || 'default-value');
|
|
ad.console.log('Missing variable handled: ' + (missingVar || 'undefined'));
|
|
''',
|
|
);
|
|
|
|
final result = await handlePreRequestScript(
|
|
scriptWithMissingVar,
|
|
testEnvironment,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
final headers = result.httpRequestModel!.headers!;
|
|
final missingVarHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Missing-Var');
|
|
expect(missingVarHeader.value, equals('default-value'));
|
|
});
|
|
|
|
test('should handle JSON parsing errors in post-response script', () async {
|
|
const invalidJsonResponse = HttpResponseModel(
|
|
statusCode: 200,
|
|
headers: {'content-type': 'application/json'},
|
|
body: '{"invalid": json}', // Invalid JSON
|
|
time: Duration(milliseconds: 100),
|
|
);
|
|
|
|
final requestWithInvalidJson = RequestModel(
|
|
id: 'invalid-json-request',
|
|
name: 'Invalid JSON Test',
|
|
httpRequestModel: baseGetRequest,
|
|
httpResponseModel: invalidJsonResponse,
|
|
postRequestScript: '''
|
|
const data = ad.response.json();
|
|
if (data) {
|
|
ad.environment.set('parsedData', 'success');
|
|
} else {
|
|
ad.environment.set('parsedData', 'failed');
|
|
}
|
|
ad.console.log('JSON parsing result: ' + (data ? 'success' : 'failed'));
|
|
''',
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePostResponseScript(
|
|
requestWithInvalidJson,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
final parsedDataVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'parsedData');
|
|
expect(parsedDataVar.value, equals('failed'));
|
|
});
|
|
|
|
test('should handle null/undefined response body', () async {
|
|
const nullBodyResponse = HttpResponseModel(
|
|
statusCode: 204,
|
|
headers: {},
|
|
body: null,
|
|
time: Duration(milliseconds: 50),
|
|
);
|
|
|
|
final requestWithNullBody = RequestModel(
|
|
id: 'null-body-request',
|
|
name: 'Null Body Test',
|
|
httpRequestModel: baseGetRequest,
|
|
httpResponseModel: nullBodyResponse,
|
|
postRequestScript: '''
|
|
const body = ad.response.body;
|
|
ad.environment.set('bodyExists', body ? 'true' : 'false');
|
|
ad.environment.set('bodyLength', body ? body.length.toString() : '0');
|
|
''',
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePostResponseScript(
|
|
requestWithNullBody,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
final bodyExistsVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'bodyExists');
|
|
expect(bodyExistsVar.value, equals('false'));
|
|
});
|
|
});
|
|
|
|
group('Performance Tests', () {
|
|
test('should handle large environment efficiently', () async {
|
|
final largeEnvValues = List.generate(
|
|
1000,
|
|
(index) => EnvironmentVariableModel(
|
|
key: 'var$index',
|
|
value: 'value$index',
|
|
enabled: index % 2 == 0, // Half enabled, half disabled
|
|
type: EnvironmentVariableType.variable,
|
|
));
|
|
|
|
final largeEnvironment = EnvironmentModel(
|
|
id: 'large-env',
|
|
name: 'Large Environment',
|
|
values: largeEnvValues,
|
|
);
|
|
|
|
final request = RequestModel(
|
|
id: 'performance-test',
|
|
name: 'Performance Test',
|
|
preRequestScript: 'ad.environment.set("perfTest", "completed");',
|
|
httpRequestModel: const HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test',
|
|
),
|
|
);
|
|
|
|
final stopwatch = Stopwatch()..start();
|
|
final result = await handlePreRequestScript(
|
|
request,
|
|
largeEnvironment,
|
|
(env, values) {},
|
|
);
|
|
|
|
stopwatch.stop();
|
|
expect(result, isA<RequestModel>());
|
|
expect(stopwatch.elapsedMilliseconds,
|
|
lessThan(5000)); // Should complete within 5 seconds
|
|
});
|
|
|
|
test('should handle multiple rapid script executions', () async {
|
|
final requests = List.generate(
|
|
10,
|
|
(index) => RequestModel(
|
|
id: 'rapid-test-$index',
|
|
name: 'Rapid Test $index',
|
|
preRequestScript:
|
|
'ad.environment.set("rapidVar$index", "$index");',
|
|
httpRequestModel: HttpRequestModel(
|
|
method: HTTPVerb.get,
|
|
url: 'https://api.apidash.dev/test$index',
|
|
),
|
|
));
|
|
|
|
final environment = const EnvironmentModel(
|
|
id: 'rapid-env',
|
|
name: 'Rapid Environment',
|
|
values: [],
|
|
);
|
|
final futures = requests
|
|
.map((request) => handlePreRequestScript(request, environment, null));
|
|
|
|
final results = await Future.wait(futures);
|
|
expect(results.length, equals(10));
|
|
for (final result in results) {
|
|
expect(result, isA<RequestModel>());
|
|
}
|
|
});
|
|
});
|
|
|
|
group('Pre-request Script - Request Modification Tests', () {
|
|
test('should modify headers correctly', () async {
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
}
|
|
|
|
final result = await handlePreRequestScript(
|
|
requestWithHeaderModificationScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.httpRequestModel, isNotNull);
|
|
|
|
final headers = result.httpRequestModel!.headers!;
|
|
|
|
// Check Authorization header was added
|
|
final authHeader = headers.firstWhere((h) => h.name == 'Authorization');
|
|
expect(authHeader.value, equals('Bearer secret-api-key-123'));
|
|
|
|
// Check custom header was added
|
|
final customHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Custom-Header');
|
|
expect(customHeader.value, equals('custom-value'));
|
|
|
|
// Check User-Agent header was removed
|
|
expect(headers.any((h) => h.name == 'User-Agent'), isFalse);
|
|
});
|
|
|
|
test('should modify URL and params correctly', () async {
|
|
final result = await handlePreRequestScript(
|
|
requestWithUrlModificationScript,
|
|
testEnvironment,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.httpRequestModel, isNotNull);
|
|
|
|
// Check URL was modified
|
|
expect(result.httpRequestModel!.url,
|
|
equals('https://api.apidash.dev/v2/users'));
|
|
|
|
// Check params were modified
|
|
final params = result.httpRequestModel!.params!;
|
|
final versionParam = params.firstWhere((p) => p.name == 'version');
|
|
expect(versionParam.value, equals('v2'));
|
|
|
|
// Check page param was removed
|
|
expect(params.any((p) => p.name == 'page'), isFalse);
|
|
});
|
|
|
|
test('should modify request body correctly', () async {
|
|
final result = await handlePreRequestScript(
|
|
requestWithBodyModificationScript,
|
|
testEnvironment,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.httpRequestModel, isNotNull);
|
|
|
|
final bodyString = result.httpRequestModel!.body;
|
|
expect(bodyString, isNotNull);
|
|
|
|
final body = jsonDecode(bodyString!);
|
|
expect(body['username'], equals('testuser'));
|
|
expect(body['password'], equals('testpass'));
|
|
expect(body['apiKey'], equals('secret-api-key-123'));
|
|
expect(body['timestamp'], isNotNull);
|
|
});
|
|
|
|
test('should modify GraphQL query correctly', () async {
|
|
final environmentWithUserId = testEnvironment.copyWith(
|
|
values: [
|
|
...testEnvironment.values,
|
|
const EnvironmentVariableModel(
|
|
key: 'userId',
|
|
value: 'user_456',
|
|
enabled: true,
|
|
type: EnvironmentVariableType.variable,
|
|
),
|
|
],
|
|
);
|
|
|
|
final result = await handlePreRequestScript(
|
|
requestWithGraphQLScript,
|
|
environmentWithUserId,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.httpRequestModel, isNotNull);
|
|
|
|
// Check query was modified
|
|
expect(result.httpRequestModel!.query, contains('roles { name }'));
|
|
|
|
// Check variables were updated
|
|
final bodyString = result.httpRequestModel!.body;
|
|
expect(bodyString, isNotNull);
|
|
|
|
final body = jsonDecode(bodyString!);
|
|
expect(body['variables']['id'], equals('user_456'));
|
|
});
|
|
|
|
test('should update environment variables correctly', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePreRequestScript(
|
|
requestWithEnvironmentUpdateScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Check new variables were added
|
|
final requestIdVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'requestId');
|
|
expect(requestIdVar.value, startsWith('req_'));
|
|
|
|
final retryCountVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'retryCount');
|
|
expect(retryCountVar.value, equals('0'));
|
|
|
|
final newVar = capturedValues!.firstWhere((v) => v.key == 'newVariable');
|
|
expect(newVar.value, equals('created-in-script'));
|
|
|
|
// Check debugMode was removed
|
|
expect(capturedValues!.any((v) => v.key == 'debugMode'), isFalse);
|
|
|
|
// Check existing variables are preserved
|
|
final baseUrlVar = capturedValues!.firstWhere((v) => v.key == 'baseUrl');
|
|
expect(baseUrlVar.value, equals('https://api.apidash.dev'));
|
|
});
|
|
|
|
test('should handle complex script with multiple modifications', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
final result = await handlePreRequestScript(
|
|
requestWithComplexScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(result.httpRequestModel, isNotNull);
|
|
|
|
// Check headers
|
|
final headers = result.httpRequestModel!.headers!;
|
|
final authHeader = headers.firstWhere((h) => h.name == 'Authorization');
|
|
expect(authHeader.value, equals('Bearer secret-api-key-123'));
|
|
|
|
final requestIdHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Request-ID');
|
|
expect(requestIdHeader.value, startsWith('req_'));
|
|
|
|
// Check URL
|
|
expect(result.httpRequestModel!.url,
|
|
equals('https://api.apidash.dev/auth/login'));
|
|
|
|
// Check body
|
|
final bodyString = result.httpRequestModel!.body;
|
|
final body = jsonDecode(bodyString!);
|
|
expect(body['client_id'], equals('apidash-client'));
|
|
expect(body['timestamp'], isNotNull);
|
|
|
|
// Check environment updates
|
|
expect(capturedValues, isNotNull);
|
|
final lastRequestTimeVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'lastRequestTime');
|
|
expect(lastRequestTimeVar.value, isNotNull);
|
|
|
|
final requestCountVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'requestCount');
|
|
expect(requestCountVar.value, equals('1'));
|
|
});
|
|
});
|
|
|
|
group('Post-response Script - Data Extraction Tests', () {
|
|
test('should extract token and user data from successful login response',
|
|
() async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
final result = await handlePostResponseScript(
|
|
requestWithTokenExtractionScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Check token was extracted
|
|
final authTokenVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'authToken');
|
|
expect(authTokenVar.value, equals('jwt-token-abc123'));
|
|
|
|
// Check user ID was extracted
|
|
final userIdVar = capturedValues!.firstWhere((v) => v.key == 'userId');
|
|
expect(userIdVar.value, equals('user_123'));
|
|
});
|
|
|
|
test('should extract headers correctly', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePostResponseScript(
|
|
requestWithHeaderExtractionScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Check auth token header was extracted
|
|
final extractedTokenVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'extractedAuthToken');
|
|
expect(extractedTokenVar.value, equals('Bearer jwt-token-abc123'));
|
|
|
|
// Check session ID was extracted from cookie
|
|
final sessionIdVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'sessionId');
|
|
expect(sessionIdVar.value, equals('sess_123'));
|
|
});
|
|
|
|
test('should handle error responses correctly', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePostResponseScript(
|
|
requestWithStatusCheckScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Check status was recorded
|
|
final statusVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'lastResponseStatus');
|
|
expect(statusVar.value, equals('401'));
|
|
|
|
// Check response time was recorded
|
|
final timeVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'lastResponseTime');
|
|
expect(timeVar.value, equals('89'));
|
|
|
|
// Check error details were extracted
|
|
final errorVar = capturedValues!.firstWhere((v) => v.key == 'lastError');
|
|
expect(errorVar.value, equals('invalid_credentials'));
|
|
|
|
final errorMessageVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'lastErrorMessage');
|
|
expect(errorMessageVar.value, equals('Invalid username or password'));
|
|
});
|
|
|
|
test('should process response data correctly', () async {
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePostResponseScript(
|
|
requestWithDataProcessingScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
|
|
// Check processed data
|
|
final activeCountVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'activeUserCount');
|
|
expect(activeCountVar.value, equals('1'));
|
|
|
|
final totalUsersVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'totalUsers');
|
|
expect(totalUsersVar.value, equals('150'));
|
|
|
|
final currentPageVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'currentPage');
|
|
expect(currentPageVar.value, equals('1'));
|
|
|
|
final firstActiveUserVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'firstActiveUserId');
|
|
expect(firstActiveUserVar.value, equals('1'));
|
|
});
|
|
});
|
|
|
|
group('Data Type Conversion Tests', () {
|
|
test('should convert different data types to strings in environment',
|
|
() async {
|
|
final dataTypeScript = RequestModel(
|
|
id: 'data-type-request',
|
|
name: 'Data Type Conversion Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
ad.environment.set('stringVar', 'hello');
|
|
ad.environment.set('numberVar', 42);
|
|
ad.environment.set('booleanVar', true);
|
|
ad.environment.set('objectVar', {key: 'value'});
|
|
ad.environment.set('arrayVar', [1, 2, 3]);
|
|
ad.environment.set('nullVar', null);
|
|
ad.environment.set('undefinedVar', undefined);
|
|
''',
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? capturedValues;
|
|
void mockUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
capturedValues = values;
|
|
}
|
|
|
|
await handlePreRequestScript(
|
|
dataTypeScript,
|
|
testEnvironment,
|
|
mockUpdateEnv,
|
|
);
|
|
|
|
expect(capturedValues, isNotNull);
|
|
|
|
final stringVar = capturedValues!.firstWhere((v) => v.key == 'stringVar');
|
|
expect(stringVar.value, equals('hello'));
|
|
|
|
final numberVar = capturedValues!.firstWhere((v) => v.key == 'numberVar');
|
|
expect(numberVar.value, equals('42'));
|
|
|
|
final booleanVar =
|
|
capturedValues!.firstWhere((v) => v.key == 'booleanVar');
|
|
expect(booleanVar.value, equals('true'));
|
|
|
|
final nullVar = capturedValues!.firstWhere((v) => v.key == 'nullVar');
|
|
expect(nullVar.value, equals(''));
|
|
});
|
|
|
|
test('should handle various header value types', () async {
|
|
final headerTypeScript = RequestModel(
|
|
id: 'header-type-request',
|
|
name: 'Header Type Test',
|
|
httpRequestModel: baseGetRequest,
|
|
preRequestScript: '''
|
|
ad.request.headers.set('X-String-Header', 'string-value');
|
|
ad.request.headers.set('X-Number-Header', 123);
|
|
ad.request.headers.set('X-Boolean-Header', true);
|
|
ad.request.headers.set('X-Null-Header', null);
|
|
''',
|
|
);
|
|
|
|
final result = await handlePreRequestScript(
|
|
headerTypeScript,
|
|
testEnvironment,
|
|
null,
|
|
);
|
|
|
|
expect(result, isA<RequestModel>());
|
|
final headers = result.httpRequestModel!.headers!;
|
|
|
|
final stringHeader =
|
|
headers.firstWhere((h) => h.name == 'X-String-Header');
|
|
expect(stringHeader.value, equals('string-value'));
|
|
|
|
final numberHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Number-Header');
|
|
expect(numberHeader.value, equals('123'));
|
|
|
|
final booleanHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Boolean-Header');
|
|
expect(booleanHeader.value, equals('true'));
|
|
|
|
final nullHeader = headers.firstWhere((h) => h.name == 'X-Null-Header');
|
|
expect(nullHeader.value, equals('null'));
|
|
});
|
|
|
|
test('should handle complete workflow with pre and post scripts', () async {
|
|
// Pre-request script that sets up auth
|
|
final preRequestModel = RequestModel(
|
|
id: 'workflow-request',
|
|
name: 'Complete Workflow Test',
|
|
httpRequestModel: basePostRequest,
|
|
preRequestScript: '''
|
|
ad.request.headers.set('Authorization', 'Bearer ' + ad.environment.get('apiKey'));
|
|
ad.request.headers.set('X-Request-ID', 'req_' + Date.now());
|
|
ad.environment.set('requestStartTime', new Date().toISOString());
|
|
''',
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? preValues;
|
|
void preUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
preValues = values;
|
|
}
|
|
|
|
// Execute pre-request script
|
|
final afterPre = await handlePreRequestScript(
|
|
preRequestModel,
|
|
testEnvironment,
|
|
preUpdateEnv,
|
|
);
|
|
|
|
expect(afterPre, isA<RequestModel>());
|
|
expect(preValues, isNotNull);
|
|
|
|
// Verify pre-request modifications
|
|
final headers = afterPre.httpRequestModel!.headers!;
|
|
final authHeader = headers.firstWhere((h) => h.name == 'Authorization');
|
|
expect(authHeader.value, equals('Bearer secret-api-key-123'));
|
|
|
|
final requestIdHeader =
|
|
headers.firstWhere((h) => h.name == 'X-Request-ID');
|
|
expect(requestIdHeader.value, startsWith('req_'));
|
|
|
|
// Simulate response and add post-response script
|
|
final postRequestModel = afterPre.copyWith(
|
|
httpResponseModel: successLoginResponse,
|
|
postRequestScript: '''
|
|
const data = ad.response.json();
|
|
if (data && data.token) {
|
|
ad.environment.set('authToken', data.token);
|
|
ad.environment.set('userId', data.user.id);
|
|
}
|
|
ad.environment.set('requestEndTime', new Date().toISOString());
|
|
ad.environment.set('responseStatus', ad.response.status.toString());
|
|
''',
|
|
);
|
|
|
|
List<EnvironmentVariableModel>? postValues;
|
|
void postUpdateEnv(
|
|
EnvironmentModel envModel, List<EnvironmentVariableModel> values) {
|
|
postValues = values;
|
|
}
|
|
|
|
// Execute post-response script
|
|
final afterPost = await handlePostResponseScript(
|
|
postRequestModel,
|
|
testEnvironment,
|
|
postUpdateEnv,
|
|
);
|
|
|
|
expect(afterPost, isA<RequestModel>());
|
|
expect(postValues, isNotNull);
|
|
|
|
// Verify post-response updates
|
|
final authTokenVar = postValues!.firstWhere((v) => v.key == 'authToken');
|
|
expect(authTokenVar.value, equals('jwt-token-abc123'));
|
|
|
|
final userIdVar = postValues!.firstWhere((v) => v.key == 'userId');
|
|
expect(userIdVar.value, equals('user_123'));
|
|
|
|
final statusVar =
|
|
postValues!.firstWhere((v) => v.key == 'responseStatus');
|
|
expect(statusVar.value, equals('200'));
|
|
|
|
expect(afterPost.id, equals(preRequestModel.id));
|
|
});
|
|
});
|
|
}
|