Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Driver test to confirm Firestore client behaviors #39

Merged
merged 18 commits into from
Mar 16, 2020
Merged

Conversation

suztomo
Copy link
Collaborator

@suztomo suztomo commented Mar 10, 2020

Fixes #17 .

The example/test_driver/cloud_firestore_behaviors driver test ensures that the behavior of
cloud_firestore_mocks follows the real Firestore client for both Cloud Firestore backend and Firestore emulator backend.

@@ -1,9 +0,0 @@
// This is a generated file; do not edit or check into version control.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file says it should not be checked into version control.

@@ -1,10 +0,0 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file says it should not be checked into version control.

@@ -15,49 +15,64 @@ def parse_KV_file(file, separator='=')
if !File.exists? file_abs_path
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flutter command said the Podfile was out-of-date and suggested regenerating; I didn't manually modify this.

@@ -44,6 +44,7 @@
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flutter updated this file; I didn't manually modify this.

tearDownAll(() => completer.complete(null));

group('Firestore behavior comparison:', () {
Map<String, Future<Firestore>> firestoreFutures = {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to make the value futures, because we need to call 'test' function without async.

If the value were without futures, it would have been initialized somewhere in setup method using future/async. When I tried that Flutter did not recognize test function calls.

Comment on lines 75 to 89
firestoreFutures.forEach((name, firestoreFuture) {
test('Unsaved documens ($name)', () async {
final firestore = await firestoreFuture;

final CollectionReference recipients = firestore.collection('messages');

final DocumentReference doc = recipients.document();
final String documentId = doc.documentID;

expect(documentId.length >= 20, true);

final result = await doc.get();
expect(doc.path, 'messages/$documentId');
expect(result.data, null);
});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the motivation for this PR. Asserting the same behavior for the following three Firestore instances:

  • cloud_firestore with Cloud Firestore backend
  • cloud_firestore with Firestore emulator backend
  • cloud_firestore_mocks

@@ -3,6 +3,47 @@
Demonstrates how to use the cloud_firestore_mocks plugin.

The example project comes from
https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/example,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This URL has changed.

@suztomo
Copy link
Collaborator Author

suztomo commented Mar 10, 2020

@atn832 The idea of the driver test worked in my environment. Thank you for the advice. When you have time, would you try to confirm it works in your Mac (I assume you have iOS simulator).

@atn832
Copy link
Owner

atn832 commented Mar 13, 2020

This looks amazing. Let me try it this weekend.

@atn832
Copy link
Owner

atn832 commented Mar 16, 2020

I gave your PR a try.

I was able to run the integration tests on an Android emulator and iOS simulator for the real firebase and the mock library (woohoo!), but not the emulator.

When running tests with the emulator, it times out on Android, and returns this error instantly on iOS:

flutter: 00:00 +5 -5: Firestore behavior comparison: Nested objects update (Firestore Emulator) [E]
flutter:   PlatformException(Error 7, FIRFirestoreErrorDomain, 
  false for 'create' @ L16)
flutter:   package:flutter/src/services/message_codecs.dart 569:7        StandardMethodCodec.decodeEnvelope
  package:flutter/src/services/platform_channel.dart 156:18     MethodChannel._invokeMethod
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1064:19                                  _CustomZone.registerBinaryCallback
  dart:async-patch/async_patch.dart 84:23                       _asyncErrorWrapperHelper
  package:test_api/src/backend/invoker.dart                     Invoker.waitForOutstandingCallbacks.<fn>
  dart:async/zone.dart 1126:13                                  _rootRun
  dart:async/zone.dart 1023:19                                  _CustomZone.run
  dart:async/zone.dart 1518:10                                  _runZoned
  dart:async/zone.dart 1465:12                                  runZoned
  package:test_api/src/backend/invoker.dart 239:5               Invoker.waitForOutstandingCallbacks

Yet the emulator seems to be running ok:

% firebase emulators:start --only firestore
i  Starting emulators: ["firestore"]
i  firestore: Logging to firestore-debug.log
✔  firestore: Emulator started at http://localhost:8080
i  firestore: For testing set FIRESTORE_EMULATOR_HOST=localhost:8080

Maybe I need to configure the emulator/simulator in some special way, so it can access my mac's port 8080?

...
~/Documents/cloud_firestore_mocks $ which firebase
/usr/local/bin/firebase
```
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also had to set up the emulator:

firebase setup:emulators:firestore

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And also run firebase init using some project of mine so that it could initialize a firebase.json file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added firebase setup:emulators:firestore, and clarified that the test does not expect firebase.json.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, we don't actually need to run setup:emulators:firestore with the latest version! I can remove this comment after the merge if you want.

```

`test_driver/cloud_firestore_behaviors` assumes the emulator listen on port
8080 (default) on localhost. This works for iOS simulator running in the same
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you require any special config for the iOS simulator? The tests for the emulator failed on my machine. I get this error:

flutter: 00:00 +5 -5: Firestore behavior comparison: Nested objects update (Firestore Emulator) [E]
flutter:   PlatformException(Error 7, FIRFirestoreErrorDomain, 
  false for 'create' @ L16)
flutter:   package:flutter/src/services/message_codecs.dart 569:7        StandardMethodCodec.decodeEnvelope
  package:flutter/src/services/platform_channel.dart 156:18     MethodChannel._invokeMethod
  ===== asynchronous gap ===========================
  dart:async/zone.dart 1064:19                                  _CustomZone.registerBinaryCallback
  dart:async-patch/async_patch.dart 84:23                       _asyncErrorWrapperHelper
  package:test_api/src/backend/invoker.dart                     Invoker.waitForOutstandingCallbacks.<fn>
  dart:async/zone.dart 1126:13                                  _rootRun
  dart:async/zone.dart 1023:19                                  _CustomZone.run
  dart:async/zone.dart 1518:10                                  _runZoned
  dart:async/zone.dart 1465:12                                  runZoned
  package:test_api/src/backend/invoker.dart 239:5               Invoker.waitForOutstandingCallbacks

Copy link
Collaborator Author

@suztomo suztomo Mar 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atn832 I didn't setup anything special for my iOS simulator or Firestore emulator (or firebase.json).

My environment

  • Simulator version: Version 11.3.1 (SimulatorApp-912.5.1 SimulatorKit-570.3 CoreSimulator-681.17.2)
  • My Mac OS Catalina: 10.15.3
  • XCode 11.3.1
  • firebase command 7.15.0 (latest)

Firestore emulator

In your emulator startup output, I don't see "Could not find config (firebase.json) so using defaults.". Aren't you using some firebase.json that defines security rules?

Mine:

~ $ firebase emulators:start --only firestore                        
⚠  Could not find config (firebase.json) so using defaults.
i  emulators: Starting emulators: firestore
⚠  firestore: Did not find a Cloud Firestore rules file specified in a firebase.json config file.
⚠  firestore: The emulator will default to allowing all reads and writes. Learn more about this option: https://firebase.google.com/docs/emulator-suite/install_and_configure#security_rules_configuration.
i  firestore: Serving ALL traffic (including WebChannel) on http://localhost:8080
⚠  firestore: Support for WebChannel on a separate port (8081) is DEPRECATED and will go away soon. Please use port above instead.
i  firestore: firestore emulator logging to firestore-debug.log
✔  firestore: firestore emulator started at http://localhost:8080
i  firestore: For testing set FIRESTORE_EMULATOR_HOST=localhost:8080
✔  emulators: All emulators started, it is now safe to connect.

Would you try running the emulator without firebase.json?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing the details of your environment. I had 7.0.0 installed. I must have had installed it long ago, and running the install script didn't actually update it. With 7.15.0, it works much better!

Version 7.0.0 required a firebase.json or it would fail (Error: Not in a Firebase app directory (could not locate firebase.json)). It also would fail if I hadn't pre-downloaded the emulator. But the new version downloads the newer emulator automatically when first run.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Beautiful!

flutter: 00:00 +0: Firestore behavior comparison: Document creation by add (Cloud Firestore)
VMServiceFlutterDriver: Connected to Flutter application.
        path: satisfied (Path is satisfied), interface: en1
flutter: 00:01 +1: Firestore behavior comparison: Document creation by add (Firestore Emulator)
        path: satisfied (Path is satisfied), interface: en1
flutter: 00:01 +2: Firestore behavior comparison: Document creation by add (cloud_firestore_mocks)
flutter: 00:01 +3: Firestore behavior comparison: Document creation by setData (Cloud Firestore)
flutter: 00:02 +4: Firestore behavior comparison: Document creation by setData (Firestore Emulator)
flutter: 00:02 +5: Firestore behavior comparison: Document creation by setData (cloud_firestore_mocks)
flutter: 00:02 +6: Firestore behavior comparison: Timestamp field (Cloud Firestore)
flutter: 00:03 +7: Firestore behavior comparison: Timestamp field (Firestore Emulator)
flutter: 00:03 +8: Firestore behavior comparison: Timestamp field (cloud_firestore_mocks)
flutter: 00:03 +9: Firestore behavior comparison: Unsaved documens (Cloud Firestore)
flutter: 00:04 +10: Firestore behavior comparison: Unsaved documens (Firestore Emulator)
flutter: 00:04 +11: Firestore behavior comparison: Unsaved documens (cloud_firestore_mocks)
flutter: 00:04 +12: Firestore behavior comparison: Nested objects creation with updateData (Cloud Firestore)
flutter: 00:05 +13: Firestore behavior comparison: Nested objects creation with updateData (Firestore Emulator)
flutter: 00:05 +14: Firestore behavior comparison: Nested objects creation with updateData (cloud_firestore_mocks)
flutter: 00:05 +15: Firestore behavior comparison: Nested objects update (Cloud Firestore)
flutter: 00:06 +16: Firestore behavior comparison: Nested objects update (Firestore Emulator)
flutter: 00:06 +17: Firestore behavior comparison: Nested objects update (cloud_firestore_mocks)
flutter: 00:06 +18: (tearDownAll)
flutter: 00:06 +19: All tests passed!
Stopping application instance.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to hear it worked.

Copy link
Owner

@atn832 atn832 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a huge accomplishment!

Feel free to tweak the documentation and merge when you're done.

I wonder if eventually, it would be possible to run the full battery of unit tests from cloud_firestore_mocks/test/* on the mock library and emulator/real firebase as part of #19.

@suztomo
Copy link
Collaborator Author

suztomo commented Mar 16, 2020

@atn832 Updated the document. Regarding PlatformException(Error 7, FIRFirestoreErrorDomain, false for 'create', I suspect your emulator picked up some security rules (that could be from firebase init). Would you try running the emulator without firebase.json?

@suztomo
Copy link
Collaborator Author

suztomo commented Mar 16, 2020

I don't have write access to the repository. Would you merge current branch?

@atn832 atn832 merged commit 5d7116b into atn832:master Mar 16, 2020
@atn832
Copy link
Owner

atn832 commented Mar 16, 2020

Merged. Also I've sent you an invite to collaborate. :)

@suztomo suztomo deleted the i17 branch March 16, 2020 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Idea: a way to run cloud_firestore_mocks_test.dart with real Firestore
2 participants