From b0db4db61fd607c24521ce15e20b55dfb5895f9d Mon Sep 17 00:00:00 2001 From: nharris Date: Mon, 12 Dec 2022 11:49:32 -0700 Subject: [PATCH] - Rename some elements - Finish README documentation - Improve imports - Include unit tests in Dart published file (per Dart's rec: https://stackoverflow.com/a/69767697/13343799) --- README.md | 176 ++++++++++++++++-- lib/dartvcr.dart | 15 +- ...ed_settings.dart => advanced_options.dart} | 4 +- ...asyvcr_client.dart => dartvcr_client.dart} | 38 ++-- lib/src/defaults.dart | 2 +- lib/src/vcr.dart | 14 +- test/fake_data_service.dart | 8 +- test/test_utils.dart | 10 +- test/tests.dart | 127 ++++++------- 9 files changed, 267 insertions(+), 127 deletions(-) rename lib/src/{advanced_settings.dart => advanced_options.dart} (94%) rename lib/src/{easyvcr_client.dart => dartvcr_client.dart} (81%) diff --git a/README.md b/README.md index 1aaf7a8..623cc1e 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,170 @@ - +DartVCR is a library for recording and replaying HTTP interactions in your test suite. Port of [EasyVCR](https://github.com/EasyPost/easyvcr-csharp) for Dart. -A Dart package for recording and replaying HTTP interactions. Useful for testing, mocking, and more. +This can be useful for speeding up your test suite, or for running your tests on a CI server which doesn't have +connectivity to the HTTP endpoints you need to interact with. -Port of EasyVCR. +## How to use DartVCR + +#### Step 1. + +Run your test suite locally against a real HTTP endpoint in recording mode + +```dart +import 'package:dartvcr/dartvcr.dart'; + +// Create a cassette to handle HTTP interactions +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +// create an DartVCRClient using the cassette +DartVCRClient client = DartVCRClient(cassette, Mode.record); + +// Use this DartVCRClient in any class making HTTP calls +// Note: DartVCRClient extends BaseClient from the 'http/http' package, so it can be used anywhere a BaseClient is expected +var response = await client.post(Uri.parse('https://api.example.com/v1/users')); +``` + +Real HTTP calls will be made and recorded to the cassette file. + +#### Step 2. + +Switch to replay mode: + +```dart +import 'package:dartvcr/dartvcr.dart'; + +// Create a cassette to handle HTTP interactions +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +// create an DartVCRClient using the cassette +DartVCRClient client = DartVCRClient(cassette, Mode.replay); +``` + +Now when tests are run, no real HTTP calls will be made. Instead, the HTTP responses will be replayed from the cassette +file. + +### Available modes + +- `Mode.auto`: Play back a request if it has been recorded before, or record a new one if not. (default mode for `VCR`) +- `Mode.record`: Record a request, including overwriting any existing matching recording. +- `Mode.replay`: Replay a request. Throws an exception if no matching recording is found. +- `Mode.bypass`: Do not record or replay any requests (client will behave like a normal BaseClient). ## Features -To come. +`DartVCR` comes with a number of features, many of which can be customized via the `AdvancedOptions` class. + +### Censoring + +Censor sensitive data in the request and response bodies and headers, such as API keys and auth tokens. + +NOTE: This feature currently only works on JSON response bodies. + +**Default**: *Disabled* + +```dart +import 'package:dartvcr/dartvcr.dart'; + +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +var censors = Censors().censorHeaderElementsByKeys(["authorization"]); // Hide the Authorization header +censors.censorBodyElements([CensorElement("table", caseSensitive: true)]); // Hide the table element (case sensitive) in the request and response body + +var advancedOptions = AdvancedOptions(censors: censors); + +var client = DartVCRClient(cassette, Mode.record, advancedOptions: advancedOptions); +``` + +### Delay + +Simulate a delay when replaying a recorded request, either using a specified delay or the original request duration. + +NOTE: Delays may suffer from a small margin of error. Do not rely on the delay being exact down to the millisecond. + +**Default**: *No delay* + +```dart +import 'package:dartvcr/dartvcr.dart'; + +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +// Simulate a delay of the original request duration when replaying (overrides ManualDelay) +// Simulate a delay of 1000 milliseconds when replaying +var advancedOptions = AdvancedOptions(simulateDelay: true, manualDelay: 1000); + +var client = DartVCRClient(cassette, Mode.replay, advancedOptions: advancedOptions); +``` + +### Expiration + +Set expiration dates for recorded requests, and decide what to do with expired recordings. + +**Default**: *No expiration* + +```dart +import 'package:dartvcr/dartvcr.dart'; + +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +// Any matching request is considered expired if it was recorded more than 30 days ago +// Throw exception if the recording is expired +var advancedOptions = AdvancedOptions(validTimeFrame: TimeFrame(days: 30), whenExpired: ExpirationAction.throwException); + +var client = DartVCRClient(cassette, Mode.replay, advancedOptions: advancedOptions); +``` + +### Matching + +Customize how a recorded request is determined to be a match to the current request. + +**Default**: *Method and full URL must match* + +```dart +import 'package:dartvcr/dartvcr.dart'; + +var cassette = Cassette("path/to/cassettes", "my_cassette"); + +// Match recorded requests by body and a specific header +var matchRules = MatchRules().byBody().byHeader("x-my-header"); +var advancedOptions = AdvancedOptions(matchRules: matchRules); + +var client = DartVCRClient(cassette, Mode.replay, advancedOptions: advancedOptions); +``` + +## VCR + +In addition to individual recordable HttpClient instances, `DartVCR` also offers a built-in VCR, which can be used to +easily switch between multiple cassettes and/or modes. Any advanced settings applied to the VCR will be applied on every +request made using the VCR's HttpClient. + +```dart +import 'package:dartvcr/dartvcr.dart'; + +// hide the api_key query parameter +var advancedOptions = AdvancedOptions(censors: Censors().censorQueryElementsByKeys(["api_key"])); + +// create a VCR with the advanced options applied +var vcr = VCR(advancedOptions: advancedOptions); + +// create a cassette and add it to the VCR +var cassette = Cassette("path/to/cassettes", "my_cassette"); +vcr.insert(cassette); + +// set the VCR to record mode +vcr.record(); + +// get a client configured to use the VCR +var client = vcr.client; -## Getting started +// make a request -To come. +// remove the cassette from the VCR +vcr.eject(); +``` -## Usage +#### Credit -To come. +- [EasyVCR by EasyPost](https://github.com/easypost/easyvcr-csharp), which this library is based on. diff --git a/lib/dartvcr.dart b/lib/dartvcr.dart index 836ea5d..a375f3c 100644 --- a/lib/dartvcr.dart +++ b/lib/dartvcr.dart @@ -1,6 +1,15 @@ -/// Support for doing something awesome. -/// -/// More dartdocs go here. library dartvcr; // TODO: Export any libraries intended for clients of this package. +export 'src/advanced_options.dart'; +export 'src/cassette.dart'; +export 'src/censor_element.dart'; +export 'src/censors.dart'; +export 'src/dartvcr_client.dart'; +export 'src/expiration_actions.dart'; +export 'src/match_rules.dart'; +export 'src/mode.dart'; +export 'src/time_frame.dart'; +export 'src/utilities.dart'; +export 'src/vcr.dart'; +export 'src/vcr_exception.dart'; diff --git a/lib/src/advanced_settings.dart b/lib/src/advanced_options.dart similarity index 94% rename from lib/src/advanced_settings.dart rename to lib/src/advanced_options.dart index e489404..bff3c0c 100644 --- a/lib/src/advanced_settings.dart +++ b/lib/src/advanced_options.dart @@ -4,7 +4,7 @@ import 'package:dartvcr/src/time_frame.dart'; import 'censors.dart'; import 'expiration_actions.dart'; -class AdvancedSettings { +class AdvancedOptions { final Censors censors; final MatchRules matchRules; @@ -17,7 +17,7 @@ class AdvancedSettings { final ExpirationAction whenExpired; - AdvancedSettings( + AdvancedOptions( {Censors? censors, MatchRules? matchRules, int? manualDelay, diff --git a/lib/src/easyvcr_client.dart b/lib/src/dartvcr_client.dart similarity index 81% rename from lib/src/easyvcr_client.dart rename to lib/src/dartvcr_client.dart index f866419..04ab4ce 100644 --- a/lib/src/easyvcr_client.dart +++ b/lib/src/dartvcr_client.dart @@ -1,4 +1,4 @@ -import 'package:dartvcr/src/advanced_settings.dart'; +import 'package:dartvcr/src/advanced_options.dart'; import 'package:dartvcr/src/defaults.dart'; import 'package:dartvcr/src/expiration_actions.dart'; import 'package:dartvcr/src/request_elements/http_interaction.dart'; @@ -10,19 +10,19 @@ import 'package:http/http.dart' as http; import 'cassette.dart'; import 'mode.dart'; -class EasyVCRClient extends http.BaseClient { +class DartVCRClient extends http.BaseClient { final http.Client _client; final Cassette _cassette; final Mode _mode; - final AdvancedSettings _advancedSettings; + final AdvancedOptions _advancedOptions; - EasyVCRClient(this._cassette, this._mode, - {AdvancedSettings? advancedSettings}) + DartVCRClient(this._cassette, this._mode, + {AdvancedOptions? advancedOptions}) : _client = http.Client(), - _advancedSettings = advancedSettings ?? AdvancedSettings(); + _advancedOptions = advancedOptions ?? AdvancedOptions(); @override Future send(http.BaseRequest request) async { @@ -38,9 +38,9 @@ class EasyVCRClient extends http.BaseClient { throw VCRException( "No matching interaction found for request ${request.method} ${request.url}"); } - if (_advancedSettings.validTimeFrame + if (_advancedOptions.validTimeFrame .hasLapsed(replayInteraction.recordedAt)) { - switch (_advancedSettings.whenExpired) { + switch (_advancedOptions.whenExpired) { case ExpirationAction.warn: // just throw a warning // will still simulate delay below @@ -59,17 +59,17 @@ class EasyVCRClient extends http.BaseClient { // simulate delay if configured await _simulateDelay(replayInteraction); // return matching interaction's response - return replayInteraction.toStreamedResponse(_advancedSettings.censors); + return replayInteraction.toStreamedResponse(_advancedOptions.censors); case Mode.auto: // try to get recorded request, fallback to live request + record HttpInteraction? replayInteraction = _findMatchingInteraction(request); if (replayInteraction != null) { // found a matching interaction - if (_advancedSettings.validTimeFrame + if (_advancedOptions.validTimeFrame .hasLapsed(replayInteraction.recordedAt)) { // interaction has expired - switch (_advancedSettings.whenExpired) { + switch (_advancedOptions.whenExpired) { case ExpirationAction.warn: // just throw a warning // will still simulate delay below @@ -88,7 +88,7 @@ class EasyVCRClient extends http.BaseClient { await _simulateDelay(replayInteraction); // return matching interaction's response return replayInteraction - .toStreamedResponse(_advancedSettings.censors); + .toStreamedResponse(_advancedOptions.censors); } // no matching interaction found, make real request, record response @@ -104,10 +104,10 @@ class EasyVCRClient extends http.BaseClient { List interactions = _cassette.read(); Request receivedRequest = - Request.fromHttpRequest(request, _advancedSettings.censors); + Request.fromHttpRequest(request, _advancedOptions.censors); try { - return interactions.firstWhere((interaction) => _advancedSettings + return interactions.firstWhere((interaction) => _advancedOptions .matchRules .requestsMatch(receivedRequest, interaction.request)); } catch (e) { @@ -122,9 +122,9 @@ class EasyVCRClient extends http.BaseClient { http.StreamedResponse streamedResponse = await _client.send(request); stopwatch.stop(); http.Response response = - await Response.fromStream(streamedResponse, _advancedSettings.censors); + await Response.fromStream(streamedResponse, _advancedOptions.censors); HttpInteraction interaction = - HttpInteraction.fromHttpResponse(response, _advancedSettings.censors); + HttpInteraction.fromHttpResponse(response, _advancedOptions.censors); interaction.duration = stopwatch .elapsedMilliseconds; // add duration to interaction before saving interaction.response.headers.addAll( @@ -132,17 +132,17 @@ class EasyVCRClient extends http.BaseClient { _cassette.update(interaction); // need to rebuild a new streamedResponse since this one has already been read - return Response.toStream(response, _advancedSettings.censors); + return Response.toStream(response, _advancedOptions.censors); } Future _simulateDelay(HttpInteraction interaction) async { int delay = 0; - if (_advancedSettings.simulateDelay == true) { + if (_advancedOptions.simulateDelay == true) { // original delay takes precedence delay = interaction.duration; } else { // otherwise use manual delay - delay = _advancedSettings.manualDelay; + delay = _advancedOptions.manualDelay; } await Future.delayed(Duration(milliseconds: delay)); } diff --git a/lib/src/defaults.dart b/lib/src/defaults.dart index c937d19..7243cb5 100644 --- a/lib/src/defaults.dart +++ b/lib/src/defaults.dart @@ -1,4 +1,4 @@ -const String viaRecordingHeaderKey = "X-Via-EasyVCR-Recording"; +const String viaRecordingHeaderKey = "X-Via-DartVCR-Recording"; Map get replayHeaders => { viaRecordingHeaderKey: "true", diff --git a/lib/src/vcr.dart b/lib/src/vcr.dart index a8a24c5..29926d4 100644 --- a/lib/src/vcr.dart +++ b/lib/src/vcr.dart @@ -1,5 +1,5 @@ -import 'package:dartvcr/src/advanced_settings.dart'; -import 'package:dartvcr/src/easyvcr_client.dart'; +import 'package:dartvcr/src/advanced_options.dart'; +import 'package:dartvcr/src/dartvcr_client.dart'; import 'cassette.dart'; import 'mode.dart'; @@ -9,17 +9,17 @@ class VCR { Mode mode; - AdvancedSettings? advancedSettings; + AdvancedOptions? advancedOptions; - VCR({this.advancedSettings}) + VCR({this.advancedOptions}) : mode = Mode.bypass; String? get cassetteName => _currentCassette?.name; - EasyVCRClient get client => _currentCassette == null + DartVCRClient get client => _currentCassette == null ? throw Exception('No cassette is loaded') - : EasyVCRClient(_currentCassette!, mode, - advancedSettings: advancedSettings ?? AdvancedSettings()); + : DartVCRClient(_currentCassette!, mode, + advancedOptions: advancedOptions ?? AdvancedOptions()); void eject() { _currentCassette = null; diff --git a/test/fake_data_service.dart b/test/fake_data_service.dart index cd59b1b..2071d53 100644 --- a/test/fake_data_service.dart +++ b/test/fake_data_service.dart @@ -1,4 +1,4 @@ -import 'package:dartvcr/src/easyvcr_client.dart'; +import 'package:dartvcr/src/dartvcr_client.dart'; import 'package:dartvcr/src/vcr.dart'; import 'package:dartvcr/src/vcr_exception.dart'; import 'package:http/http.dart' as http; @@ -6,18 +6,18 @@ import 'package:http/http.dart' as http; import 'ip_address_data.dart'; class FakeDataService { - EasyVCRClient? _client; + DartVCRClient? _client; final String format; VCR? _vcr; - FakeDataService(this.format, {EasyVCRClient? client, VCR? vcr}) { + FakeDataService(this.format, {DartVCRClient? client, VCR? vcr}) { _client = client; _vcr = vcr; } - EasyVCRClient get client { + DartVCRClient get client { if (_client != null) { return _client!; } diff --git a/test/test_utils.dart b/test/test_utils.dart index 8c2d662..b3f11c8 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -1,8 +1,8 @@ import 'dart:io'; -import 'package:dartvcr/src/advanced_settings.dart'; +import 'package:dartvcr/src/advanced_options.dart'; import 'package:dartvcr/src/cassette.dart'; -import 'package:dartvcr/src/easyvcr_client.dart'; +import 'package:dartvcr/src/dartvcr_client.dart'; import 'package:dartvcr/src/match_rules.dart'; import 'package:dartvcr/src/mode.dart'; import 'package:dartvcr/src/vcr.dart'; @@ -12,13 +12,13 @@ class TestUtils { return Cassette(_getDirectoryInCurrentDirectory('cassettes'), cassetteName); } - static EasyVCRClient getSimpleClient(String cassetteName, Mode mode) { + static DartVCRClient getSimpleClient(String cassetteName, Mode mode) { Cassette cassette = getCassette(cassetteName); - return EasyVCRClient(cassette, mode); + return DartVCRClient(cassette, mode); } static VCR getSimpleVCR(Mode mode) { - VCR vcr = VCR(advancedSettings: AdvancedSettings( + VCR vcr = VCR(advancedOptions: AdvancedOptions( matchRules: MatchRules.defaultStrictMatchRules )); diff --git a/test/tests.dart b/test/tests.dart index 0012947..0fe2fc8 100644 --- a/test/tests.dart +++ b/test/tests.dart @@ -1,17 +1,6 @@ import 'dart:math'; -import 'package:dartvcr/src/advanced_settings.dart'; -import 'package:dartvcr/src/cassette.dart'; -import 'package:dartvcr/src/censor_element.dart'; -import 'package:dartvcr/src/censors.dart'; -import 'package:dartvcr/src/easyvcr_client.dart'; -import 'package:dartvcr/src/expiration_actions.dart'; -import 'package:dartvcr/src/match_rules.dart'; -import 'package:dartvcr/src/mode.dart'; -import 'package:dartvcr/src/time_frame.dart'; -import 'package:dartvcr/src/utilities.dart'; -import 'package:dartvcr/src/vcr.dart'; -import 'package:dartvcr/src/vcr_exception.dart'; +import 'package:dartvcr/dartvcr.dart'; import 'package:test/test.dart'; import 'package:http/http.dart' as http; @@ -22,9 +11,9 @@ import 'test_utils.dart'; Future getIPAddressDataRequest( Cassette cassette, Mode mode) async { - EasyVCRClient client = EasyVCRClient(cassette, mode, - advancedSettings: - AdvancedSettings(matchRules: MatchRules.defaultStrictMatchRules)); + DartVCRClient client = DartVCRClient(cassette, mode, + advancedOptions: + AdvancedOptions(matchRules: MatchRules.defaultStrictMatchRules)); FakeDataService service = FakeDataService("json", client: client); @@ -33,9 +22,9 @@ Future getIPAddressDataRequest( Future getIPAddressDataRawRequest( Cassette cassette, Mode mode) async { - EasyVCRClient client = EasyVCRClient(cassette, mode, - advancedSettings: - AdvancedSettings(matchRules: MatchRules.defaultStrictMatchRules)); + DartVCRClient client = DartVCRClient(cassette, mode, + advancedOptions: + AdvancedOptions(matchRules: MatchRules.defaultStrictMatchRules)); FakeDataService service = FakeDataService("json", client: client); @@ -91,19 +80,19 @@ void main() { // set up advanced settings String censorString = "censored-by-test"; - AdvancedSettings advancedSettings = AdvancedSettings( + AdvancedOptions advancedOptions = AdvancedOptions( censors: Censors(censorString: censorString) .censorHeaderElementsByKeys(["date"])); // record cassette with advanced settings first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record, - advancedSettings: advancedSettings); + DartVCRClient client = DartVCRClient(cassette, Mode.record, + advancedOptions: advancedOptions); FakeDataService service = FakeDataService("json", client: client); await service.getIPAddressDataRawResponse(); // now replay cassette - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: advancedSettings); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: advancedOptions); service = FakeDataService("json", client: client); http.StreamedResponse response = await service.getIPAddressDataRawResponse(); @@ -124,8 +113,8 @@ void main() { String postBody = "test post body"; // record cassette first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record, - advancedSettings: AdvancedSettings( + DartVCRClient client = DartVCRClient(cassette, Mode.record, + advancedOptions: AdvancedOptions( matchRules: MatchRules .defaultMatchRules) // doesn't really matter for initial record ); @@ -133,9 +122,9 @@ void main() { assert(responseCameFromRecording(response) == false); // replay cassette - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: - AdvancedSettings(matchRules: MatchRules.defaultMatchRules)); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: + AdvancedOptions(matchRules: MatchRules.defaultMatchRules)); response = await client.post(url, body: postBody); // check that the request body was matched and that a recording was used @@ -147,12 +136,12 @@ void main() { cassette.erase(); // Erase cassette before recording // record cassette first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); FakeDataService service = FakeDataService("json", client: client); await service.getIPAddressDataRawResponse(); // baseline - how much time does it take to replay the cassette? - client = EasyVCRClient(cassette, Mode.replay); + client = DartVCRClient(cassette, Mode.replay); service = FakeDataService("json", client: client); Stopwatch stopwatch = Stopwatch()..start(); await service.getIPAddressDataRawResponse(); @@ -164,8 +153,8 @@ void main() { // set up advanced settings int delay = normalReplayTime + 3000; // add 3 seconds to the normal replay time, for good measure - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: AdvancedSettings(manualDelay: delay)); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: AdvancedOptions(manualDelay: delay)); service = FakeDataService("json", client: client); // time replay request @@ -184,7 +173,7 @@ void main() { Cassette cassette = TestUtils.getCassette("test_erase"); // record something to the cassette - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); FakeDataService service = FakeDataService("json", client: client); await service.getIPAddressDataRawResponse(); @@ -203,7 +192,7 @@ void main() { cassette.erase(); // Erase cassette before recording // cassette is empty, so replaying should throw an exception - EasyVCRClient client = EasyVCRClient(cassette, Mode.replay); + DartVCRClient client = DartVCRClient(cassette, Mode.replay); FakeDataService service = FakeDataService("json", client: client); expect(service.getIPAddressDataRawResponse(), throwsException); }); @@ -213,7 +202,7 @@ void main() { cassette.erase(); // Erase cassette before recording // cassette is empty, so recording should work - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); FakeDataService service = FakeDataService("json", client: client); await service.getIPAddressDataRawResponse(); @@ -228,16 +217,16 @@ void main() { Uri url = Uri.parse("https://google.com"); // record cassette first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); await client.post(url); // replay cassette with default expiration rules, should find a match - client = EasyVCRClient(cassette, Mode.replay); + client = DartVCRClient(cassette, Mode.replay); http.Response response = await client.post(url); assert(responseCameFromRecording(response) == true); // replay cassette with custom expiration rules, should not find a match because recording is expired (throw exception) - AdvancedSettings advancedSettings = AdvancedSettings( + AdvancedOptions advancedOptions = AdvancedOptions( validTimeFrame: TimeFrame.never, whenExpired: ExpirationAction .throwException // throw exception when in replay mode @@ -245,18 +234,18 @@ void main() { await Future.delayed(Duration( milliseconds: 1000)); // Allow 1 second to lapse to ensure recording is now "expired" - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: advancedSettings); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: advancedOptions); expect(client.post(url), throwsException); // replay cassette with bad expiration rules, should throw an exception because settings are bad - advancedSettings = AdvancedSettings( + advancedOptions = AdvancedOptions( validTimeFrame: TimeFrame.never, whenExpired: ExpirationAction .recordAgain // invalid settings for replay mode, should throw exception ); - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: advancedSettings); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: advancedOptions); }); test('Ignore elements fail match', () async { @@ -271,12 +260,12 @@ void main() { "{\"name\": \"Different Name\",\n \"company\": \"EasyPost\"}"; // record baseline request first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); await client.post(url, body: body1); // try to replay the request with different body data - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: AdvancedSettings( + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: AdvancedOptions( matchRules: MatchRules().byBody().byMethod().byFullUrl())); // should fail since we're strictly in replay mode and there's no exact match @@ -295,7 +284,7 @@ void main() { "{\"name\": \"Different Name\",\n \"company\": \"EasyPost\"}"; // record baseline request first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); await client.post(url, body: body1); List ignoreElements = [ @@ -303,8 +292,8 @@ void main() { ]; // try to replay the request with different body data, but ignoring the differences - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: AdvancedSettings( + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: AdvancedOptions( matchRules: MatchRules() .byBody(ignoreElements: ignoreElements) .byMethod() @@ -322,20 +311,20 @@ void main() { Uri url = Uri.parse("https://google.com"); // record cassette first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); await client.post(url); // replay cassette with default match rules, should find a match - client = EasyVCRClient(cassette, Mode.replay); + client = DartVCRClient(cassette, Mode.replay); // add custom header to request, shouldn't matter when matching by default rules // shouldn't throw an exception await client.post(url, headers: {"X-Custom-Header": "custom-value"}); // replay cassette with custom match rules, should not find a match because request is different (throw exception) - AdvancedSettings advancedSettings = - AdvancedSettings(matchRules: MatchRules().byEverything()); - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: advancedSettings); + AdvancedOptions advancedOptions = + AdvancedOptions(matchRules: MatchRules().byEverything()); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: advancedOptions); // add custom header to request, causing a match failure when matching by everything expect(client.post(url, headers: {"X-Custom-Header": "custom-value"}), throwsException); @@ -354,11 +343,11 @@ void main() { Censors censors = Censors(censorString: censorString); censors.censorBodyElementsByKeys( ["nested_dict_1_1_1", "nested_dict_2_2", "nested_array", "null_key"]); - AdvancedSettings advancedSettings = AdvancedSettings(censors: censors); + AdvancedOptions advancedOptions = AdvancedOptions(censors: censors); // record cassette - EasyVCRClient client = EasyVCRClient(cassette, Mode.record, - advancedSettings: advancedSettings); + DartVCRClient client = DartVCRClient(cassette, Mode.record, + advancedOptions: advancedOptions); await client.post(url, body: body); // NOTE: Have to manually check the cassette @@ -373,18 +362,18 @@ void main() { "{\n \"address\": {\n \"name\": \"Jack Sparrow\",\n \"company\": \"EasyPost\",\n \"street1\": \"388 Townsend St\",\n \"street2\": \"Apt 20\",\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"zip\": \"94107\",\n \"country\": \"US\",\n \"phone\": \"5555555555\"\n }\n}"; // record cassette first - EasyVCRClient client = EasyVCRClient(cassette, Mode.record); + DartVCRClient client = DartVCRClient(cassette, Mode.record); http.Response response = await client.post(url, body: body); // check that the request body was not matched (should be a live call) assert(responseCameFromRecording(response) == false); // replay cassette with default match rules, should find a match - client = EasyVCRClient(cassette, Mode.replay); + client = DartVCRClient(cassette, Mode.replay); // replay cassette - client = EasyVCRClient(cassette, Mode.replay, - advancedSettings: - AdvancedSettings(matchRules: MatchRules.defaultStrictMatchRules)); + client = DartVCRClient(cassette, Mode.replay, + advancedOptions: + AdvancedOptions(matchRules: MatchRules.defaultStrictMatchRules)); response = await client.post(url, body: body); // check that the request body was matched @@ -399,13 +388,13 @@ void main() { test('Advanced settings', () async { String censorString = "censored-by-test"; - AdvancedSettings advancedSettings = AdvancedSettings( + AdvancedOptions advancedOptions = AdvancedOptions( censors: Censors(censorString: censorString) .censorHeaderElementsByKeys(["date"])); - VCR vcr = VCR(advancedSettings: advancedSettings); + VCR vcr = VCR(advancedOptions: advancedOptions); // test that the advanced settings are applied inside the VCR - assert(vcr.advancedSettings == advancedSettings); + assert(vcr.advancedOptions == advancedOptions); // test that the advanced settings are passed to the cassette by checking if censor is applied Cassette cassette = TestUtils.getCassette("test_vcr_advanced_settings"); @@ -414,7 +403,7 @@ void main() { // record cassette first vcr.record(); - EasyVCRClient client = vcr.client; + DartVCRClient client = vcr.client; FakeDataService service = FakeDataService("json", client: client); await service.getIPAddressDataRawResponse(); @@ -466,7 +455,7 @@ void main() { // make sure the VCR client is set correctly // no exception thrown when retrieving the client - EasyVCRClient client = vcr.client; + DartVCRClient client = vcr.client; }); test("VCR client handoff", () async { @@ -477,7 +466,7 @@ void main() { // test that we can still control the VCR even after it's been handed off to the service using it FakeDataService service = FakeDataService("json", vcr: vcr); // Client should come from VCR, which has a client because it has a cassette. - EasyVCRClient client = service.client; + DartVCRClient client = service.client; vcr.eject(); // Client should be null because the VCR's cassette has been ejected.