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

Feature/support mocking server timestamp #287

Merged

Conversation

ming-chu
Copy link
Contributor

This PR is going to provide the interface for mocking the server timestamp.
Btw, I am pretty sure that there are lots of better solutions than mine.

Any advice or comments are welcome.

Thank you for maintaining such an amazing plugin. I appreciated it! ❤️

@atn832

FakeFirebaseFirestore({
Stream<Map<String, dynamic>?>? authObject,
String? securityRules,
this.fakeServerTimeProvider,
Copy link
Owner

Choose a reason for hiding this comment

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

Instead of passing your own FakeServerTimeProvider, we probably want to use the clock package like the ticket reporter suggested. Clock allows us to later use FakeAsync to pass time artificially as explained at https://pub.dev/packages/clock.

Would you mind reworking the PR by removing FakeServerTimeProvider, adding clock as a dependency, then modifying the constructor like so:

  final Clock _clock;

  FakeFirebaseFirestore({
    Stream<Map<String, dynamic>?>? authObject,
    String? securityRules,
    Clock? clock,
  }) : securityRules = ..., _clock = clock ?? Clock()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, no problem. I will do that😃 @atn832


@override
void updateDocument(Map<String, dynamic> document, String key) {
document[key] = Timestamp.now();
document[key] = now;
Copy link
Owner

Choose a reason for hiding this comment

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

With the Clock always set up, you can rewrite this as

document[key] = clock.now()

https://pub.dev/documentation/clock/latest/clock/Clock/now.html


Timestamp get now => _fakeServerTimeProvider?.now ?? Timestamp.now();

void setTimeProvider(FakeServerTimeProvider? fakeServerTimeProvider) {
Copy link
Owner

@atn832 atn832 Jan 4, 2024

Choose a reason for hiding this comment

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

How about using a setter?

set clock(Clock clock) {
  this._clock = clock;
}

Copy link
Contributor Author

@ming-chu ming-chu Jan 4, 2024

Choose a reason for hiding this comment

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

let me think, I was thinking about how the FieldValueServerTimestamp can get the clock from FakeFirebaseFirestore

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did the same way as the previous commit, haha. Any other ideas are welcome.

let me think, I was thinking about how the FieldValueServerTimestamp can get the clock from FakeFirebaseFirestore

expect(bobCreated, fixedTimestamp);
});

test('FieldValue.serverTimestamp() sets the time with relative time',
Copy link
Owner

Choose a reason for hiding this comment

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

If we use Clock, the first test is probably sufficient and you can remove the second test. If you want to implement a second test, perhaps you could use fake_async and demonstrate the passing of time like they do in https://pub.dev/packages/clock.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that will be like:

final fakeClock = Clock(() => DateTime.now().subtract(Duration(hours: 3)));

So, maybe I don't prefer to have this test just for demonstration and probably mess the tests up.
What do you think?🤔

Copy link
Owner

Choose a reason for hiding this comment

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

You can safely delete this

Comment on lines 1755 to 1767
class CustomServerTimeProvider implements FakeServerTimeProvider {
final int hoursAgo;

CustomServerTimeProvider({required this.hoursAgo});

@override
Timestamp get now {
// always return the time that n hours ago from now
return Timestamp.fromDate(
DateTime.now().subtract(Duration(hours: hoursAgo)),
);
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

You can safely delete this.

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.

Thanks for the PR! Would you mind replacing FakeServerTimeProvider with Clock from https://pub.dev/packages/clock?

@ming-chu
Copy link
Contributor Author

ming-chu commented Jan 4, 2024

@atn832 Thank you for the review and I resolved them according to your suggestions.
Please feel free to check and comment.

Thank you very much!!

@ming-chu ming-chu requested a review from atn832 January 4, 2024 03:40
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.

Thanks for the quick update @ming-chu !

@atn832 atn832 merged commit cb5e5d9 into atn832:master Jan 4, 2024
4 checks passed
@ming-chu ming-chu deleted the feature/support-mocking-server-timestamp branch January 4, 2024 04:51
@atn832
Copy link
Owner

atn832 commented Jan 4, 2024

I made tiny tweaks at 1036aa2. Basically in this project's classes, we first put private variables, then constructors, then methods and getter/setters.

@ming-chu
Copy link
Contributor Author

ming-chu commented Jan 4, 2024

I made tiny tweaks at 1036aa2. Basically in this project's classes, we first put private variables, then constructors, then methods and getter/setters.

No problem, I will keep it in mind and follow it next time.
Thank you very much!

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.

None yet

2 participants