Git Product home page Git Product logo

mockbase's People

Contributors

dependabot[bot] avatar gustavohenke avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

wsedlacek

mockbase's Issues

`onSnapshot()` destructures subscribes resulting in different behavior then Firebase

Code in question:

onSnapshot(options: any, onNext?: any, onError?: any, onCompletion?: any): () => void {
let actualListeners: Observer<firebase.firestore.DocumentSnapshot<T>>;
if (typeof options === "object") {
if (typeof onNext === "object") {
actualListeners = onNext;
} else if (typeof onNext === "function") {
actualListeners = {
next: onNext,
error: onError,
};
} else {
actualListeners = options;
}
} else {
actualListeners = {
next: options,
error: onNext,
};
}
const { next, error } = actualListeners;
this.emitter.on(SNAPSHOT_NEXT_EVENT, next);
error && this.emitter.on(SNAPSHOT_ERROR_EVENT, error);
// Don't emit SNAPSHOT_NEXT_EVENT otherwise every listener will get it
this.get().then((snapshot) => next(snapshot));
return () => {
this.emitter.off(SNAPSHOT_NEXT_EVENT, next);
error && this.emitter.off(SNAPSHOT_ERROR_EVENT, error);
};
}

Example on how it is used from firebase in AngularFire

  return new Observable(subscriber => {
    let unsubscribe;
    if (scheduler != null) {
      scheduler.schedule(() => {
        unsubscribe = ref.onSnapshot(subscriber);
      });
    } else {
      unsubscribe = ref.onSnapshot(subscriber);
    }

    return () => {
      if (unsubscribe != null) {
        unsubscribe();
      }
    };
  });

By destructuring the subscriber it results in this error.

Unhandled Promise rejection: Cannot read property 'isStopped' of undefined ; Zone: ProxyZone ; Task: Promise.then ; Value: TypeError: Cannot read property 'isStopped' of undefined

Because next() references this internally in the RxJS subscriber it needs to be called with dot notation of the subscriber.

docChanges() does not include `removed` items

First I would like to thank you Gustavo for all the hard work you have put into mocking Firebase.
I have been attempting to build out proper unit test when using Angular Fire and your mock of Firebase has been instrumental in building out proper mocks.

I am running into an issue with your mock of Firestore though. That is that it is only sending me the added docs but not removed or modified.

This is the section of code that I am getting stuck and and not getting past the short circuit.

if (this === this.query.lastSnapshot || !this.query.lastSnapshot) {
// Short circuit: this is the first snapshot, so all items were added.
return this.docs.map((doc, newIndex) => ({
type: "added",
oldIndex: -1,
newIndex,
doc,
}));
}

This is where the lastSnapshot seems like it should be set to prevent that short circuit

public async emitChange() {
if (!this.emitter.hasListeners(QUERY_SNAPSHOT_NEXT_EVENT)) {
return;
}
// TODO: this emits even if there wasn't an actual change with the current filters
const snapshot = await this.get();
this.lastSnapshot = snapshot;
this.emitter.emit(QUERY_SNAPSHOT_NEXT_EVENT, [snapshot]);
}
setNoInitialSnapshot(): this {
this.noInitialSnapshot = true;
return this;
}

Code I am using

      const subject = new Subject();
      this.app
        .firestore()
        .collection(path)
        .onSnapshot({
          next: (collection) => {
            subject.next(
              collection.docChanges().map(({ type, doc }) => ({ type, payload: { doc } }))
            );
          },
          error: (err) => subject.error(err),
          complete: () => subject.complete(),
        });

      subject.subscribe(console.log);

I have played around with it for a bit but can't seem to figure out the exact cause. My guess is either (a) lastSnapshot isn't being set OR (b) the current snapshot and lastSnapshot are always in sync, or at least at the time when docChanges() runs from within a onSnapshot()

Again thank you so much for your work. Let me know if you need any more information or have any work arounds.

Feature Request: Mock additionalUserInfo

mockbase/auth/auth.ts

Lines 112 to 117 in aa58af5

return Promise.resolve<firebase.auth.UserCredential>({
user,
additionalUserInfo: null,
credential: null,
operationType: "signIn",
});

In some libraries it is assumed that UserCredential will include additionalUserInfo. While the typing of UserCredential is clear that additionalUserInfo can be null or undefined many libraries assume that if the sign in came from a supported platform (like Google) then the additionalUserInfo will be included.

For example:
https://github.com/dappsnation/akita-ng-fire/blob/b698cfcdd5e9e21f59aa8e5a4126d41d529a760f/projects/akita-ng-fire/src/lib/auth/auth.service.ts#L255-L295

Additionally libraries, including this one, may have branching behavior based on what is included in additionalUserInfo so being able to express this when setting up the mock would allow for testing that additional behavior.

Handle Observers in `onAuthStateChanged`

In this section

mockbase/auth/auth.ts

Lines 67 to 78 in 61b9467

onAuthStateChanged(
nextOrObserver: AuthStateChangeListener,
error?: (a: firebase.auth.Error) => void,
completed?: firebase.Unsubscribe
): firebase.Unsubscribe {
this.authStateEvents.add(nextOrObserver);
nextOrObserver(this.currentUser);
return () => {
this.authStateEvents.delete(nextOrObserver);
};
}

When used with

  public readonly authState = new Observable<User | null>(
    this.auth.onAuthStateChanged.bind(this.auth)
  );

as done in
https://github.com/angular/angularfire/blob/2de8501d10add9e575885db9f44b8098e5857929/src/auth/auth.ts#L66

throws the following error.

TypeError: nextOrObserver is not a function

It should be noted that nextOrObserver is a SwitchMapSubscriber when this error occurs.

Reference:
https://github.com/ReactiveX/rxjs/blob/b8c2a52bf78e855dfe48e3620b7ee2fee05ec120/src/internal/operators/switchMap.ts#L109

Simply checking typeof should allow us to determine if nextOrObserver is next or observer
observer seem to be expecting you to call nest() on them with the user.

Here is the firebase implementation of this function for additional reference
https://github.com/firebase/firebase-js-sdk/blob/35bc0a2eea98d9796023f15cd5783700d45ccc4d/packages/auth/src/auth.js#L1442-L1472

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.