Giter Club home page Giter Club logo

meteor-publication-collector's Issues

collector.collect() doesn't throw in 1.1.0

Hi,

We've just updated Publication Collector to 1.1.0 and it's broken a few of our tests. Given that you've added support for Promises, I'd say this is probably something you'd consider "expected behaviour", but I was thinking you might want to update the changelog/history to note that it's a potentially breaking change.

Example of the problem:

// FooBarQux is a publication that has a check(argument, String) call for type-checking arguments
describe('FooBarQux subscription', () => {
    it('Takes a String argument', () => {
      const collector = new PublicationCollector();
      expect(() => collector.collect('OrganisationDetail'))
      .to.throw(/Match error/);

      expect(() => collector.collect('FooBarQux', {
        foo: 'bar',
      }))
      .to.throw(/Match error/);
    });
  });

This test has regressed because collector.collect() no longer re-throws errors that are thrown by the publication; instead it returns a promise and rejects it.

This is obviously expected behaviour and we've updated our test suite accordingly, but I can only assume that anybody else testing for publication errors has been doing something similar, so I'd argue that this is potentially a breaking change?

Does not collect results on `ready()`

When a collection is published using the low-level publication API, calling this.ready() does not seem to have any effect. My tests are reporting: Error: timeout of 2000ms exceeded.. I can't replicate this error when running the app and subscribing to the same publication. I noticed this package's tests are testing publications that all use return, so it may be worth checking this use case.

Thanks for the package, though. It makes testing so much easier in the majority of use cases.

publication returns [] but collection is undefined

Hi,

I have a publication that returns a cursor. If the collection exists but the cursor has no documents, I would expect publication-collector have an empty array for that collection. Instead it is undefined.

Error: Cannot read property 'length' of undefined

If I add one document its fine.

Is this behavior expected?

Here's my publication:

Meteor.publish("pairsAsParticipant", function (participantId) {
  authorizeOwner.call(this, participantId);
  return Pairs.find( { $and:   [ {"inviteeId":{$ne:null}},  { $or: [ { inviterId: participantId }, { inviteeId: participantId } ] } ]  } );
});

and my test:

  describe('No Pairs', () => {
    beforeEach(function (){
      resetDatabase()
      // make 5 pairs
      const fiveRandomPairs = [...Array(5)].map( () => {
        return Factory.create('pair', { inviterId: Random.id(), inviteeId: Random.id()  })
      })
    })

    it('should find zero pairs if currentUser is not a participant', function() {
      const collector = new PublicationCollector({userId: currentUserId})
      collector.collect('pairsAsParticipant', currentUserId,  (collections) => {
        expect(collections.pairs).to.have.lengthOf(0)
      })
    })
  })

Error on stop with meteor-publish-performant-counts

Hello and thank you for this package!

I get an error on line 37:

this.observeHandles.forEach(handle => handle.stop());
โ€ฃ
Error: Cannot read property 'stop' of undefined
    at packages/johanbrook:publication-collector/publication-collector.js:37:47
    at Array.forEach (native)
    at PublicationCollector.<anonymous> (packages/johanbrook:publication-collector/publication-collector.js:37:29)
    at PublicationCollector.ready (packages/johanbrook:publication-collector/publication-collector.js:99:10)
    at PublicationCollector.collect (packages/johanbrook:publication-collector/publication-collector.js:53:10)
    at Test.<anonymous> (imports/projects/api/projects.tests.js:26:19)
    at run (packages/practicalmeteor:mocha-core/server.js:34:29)

The issue is caused by publishing a counter obtained using the meteor-publish-performant-counts package. This is my publication code:

Meteor.publish('PubName', function() {
    const cursor = collection.find({})
    const counter = new Counter('PubNameListCount', cursor)
    return [
      cursor, counter
    ];
})

I am not sure if this is because that package is not confirming to the subscription API, or because the publication-collector is relying on features that are not present in all publications. I did a little bit of investigation and I feel like it is the latter, but I am not that intimately familiar with the Meteor pub / sub mechanism yet so I could be missing something! Would there be interest in accepting a PR if it is warranted?

Can't use on publication of users

I have a publication that publishes a selection of users and fields depending on the user, but it doesn't work. I get the output below when i try to run it.

TypeError: Cannot read property 'call' of undefined
at PublicationCollector.collect (packages/johanbrook:publication-collector/publication-collector.js:67:28)

My publication looks like this:

Meteor.publish('users', function () {
  const user = Meteor.users.findOne(this.userId);
  if (!user) {
    return this.ready();
  }

  if (Roles.userIsInRole(user._id, ['admin'])) {
    return Meteor.users.find({}, {
      fields: {
        createdAt: 1,
        emails: 1,
        roles: 1,
      },
    });
  }
  return this.ready();
});

I have emptied and populated both the user and role collection and trying just to get the test working like this:

  it('should publish users', function(done) {
    const collector = new PublicationCollector({ userId: 'D9E6CRGLX4Me3p6x9' });
    collector.collect('users', (collections) => {

      done();
    });
  });

ES6 Error

this.userId is undefined when using arrow function as argument of the publication.

// pub.js
Meteor.publish('posts', function({ _id }) {
  const user = this.userId; // working correctly
  return Posts.find({ _id, user });
});
// pub.js
Meteor.publish('posts', ({ _id }) => {
  const user = this.userId; // userId is undefined
  return Posts.find({ _id, user });
});
// test.js
const collector = new PublicationCollector({ userId });
collector.collect('posts', (collections) => {
  assert.equal(collections.posts.length, 5);
  done();
});

Breaking with peerlibrary:reactive-publish's "autorun"

I have run into a problem with peerlibrary:reactive-publish where "publish._isDeactivated" is not a function.

TypeError: publish._isDeactivated is not a function
       at Computation.<anonymous> (packages/peerlibrary_reactive-publish.js:354:24)
       at runWithEnvironment (packages/meteor.js:1176:24)
       at packages/meteor.js:1189:14
       at packages/peerlibrary_server-autorun.js:474:23
       at packages/peerlibrary_server-autorun.js:452:18
       at Function.FiberUtils.synchronize (packages/peerlibrary_fiber-utils.js:188:12)
       at Computation.Tracker.Computation.Computation._runInside (packages/peerlibrary_server-autorun.js:441:23)
       at packages/peerlibrary_server-autorun.js:466:22
       at Function.FiberUtils.synchronize (packages/peerlibrary_fiber-utils.js:188:12)
       at Computation.Tracker.Computation.Computation._compute (packages/peerlibrary_server-autorun.js:463:23)
       at new Computation (packages/peerlibrary_server-autorun.js:335:12)
       at Object.Tracker.autorun (packages/peerlibrary_server-autorun.js:253:7)
       at PublicationCollector.publish.autorun (packages/peerlibrary_reactive-publish.js:340:24)
       at imports/api/users/server/publications.js:52:22
       at PublicationCollector.<anonymous> (imports/api/users/server/publications.js:29:22)
       at PublicationCollector.<anonymous> (packages/peerlibrary_subscription-data.js:234:30)
       at PublicationCollector.<anonymous> (packages/peerlibrary_reactive-publish.js:371:30)
       at PublicationCollector.collect (packages/johanbrook:publication-collector/publication-collector.js:44:20)
       at Test.<anonymous> (imports/api/users/server/publicatons.test.js:35:19)

I wonder if this is along the same lines as the last issue that related to peerlibrary:reactive-publish?

Needs license

Could you please add a license so that others can use this package? Publishing software without a license means that anyone attempting to use it would be in violation of copyright. If you could please add an MIT or another distribution-friendly license, that would be appreciated!

Thanks in advance!

Use universal_publish_handlers when no publication-name is given

I want to test (server side) a package, that auto-publishes data to the user. The publication scheme it uses therefore is

Metepr.publish(null, function(){...})

which adds the publication to the universal_publish_handlers instead of publish_handlers, as taken from the code.

When calling the collector.collect(null, ...); then of course I get an error, because it uses publish_handlers[name] and not universal_publish_handlers when no name is provided.

Does it make sense to add this feature? I could try to provide a PR with an implementation and some tests, if desired.

Not working with `peerlibrary:reactive-publish`

I can't use publication-collector while using peerlibrary:reactive-publish at the same time.

server/example.test.js

import { PublicationCollector } from 'meteor/johanbrook:publication-collector'
import '/imports/api/server/publications.js'

describe('example', () => {
	it('should return empty array', function(done) {
		const collector = new PublicationCollector()

		collector.collect('publication', (collections) => {
			expect(collections.publication).to.be.deep.equal([])
			done()
		})
	})
})

server/publications.js

Meteor.publish('publication', function() {
	this.autorun(function() {
		return Collection.find({ any: 'thing' })
	})
})

I have to remove this.autorun() to get the test working. Otherwise I'll get this error:

Error: publish._isDeactivated is not a function
at Computation.<anonymous> (packages/peerlibrary_reactive-publish.js:349:24)
at runWithEnvironment (packages/meteor.js:1176:24)
at packages/meteor.js:1189:14
at packages/peerlibrary_server-autorun.js:469:23
at packages/peerlibrary_server-autorun.js:447:18
at Function.FiberUtils.synchronize (packages/peerlibrary_fiber-utils.js:183:12)
at Computation.Tracker.Computation.Computation._runInside (packages/peerlibrary_server-autorun.js:436:23)
at packages/peerlibrary_server-autorun.js:461:22
at Function.FiberUtils.synchronize (packages/peerlibrary_fiber-utils.js:183:12)
at Computation.Tracker.Computation.Computation._compute (packages/peerlibrary_server-autorun.js:458:23)

Using:

Error: Cannot read property 'call' of undefined

Hey Johan,

I recently came across a very missleading error from this package

Error: Cannot read property 'call' of undefined
    at PublicationCollector.collect (packages/johanbrook:publication-collector/publication-collector.js:67:28)
    ....

which refers to those 2 lines:

collect(name, ...args) {
  ...
  
  const handler = Meteor.server.publish_handlers[name];
  const result = handler.call(this, ...args);

  ...
}

It turns out I "just" misspelled my publication which apperantly caused the read error.

Due to the thrown error, it took me a little while to figure out what caused the error (also because I'm not familiar with publish_handlers or meteor internals in generall). Therefor I would love to get a more specific error message suggesting that I eventually misspelled the publication.

Unfortunately, I'm busy right now and therefor not able to provide a pull request. Sorry!

Behaviour onStop

Since 1.0.4 the behaviour of collect(...) regarding this.stop() seems to be changed,
the callback will not be called if the publication is stopped before it is "ready".
Is this intended?

Thanks

Does this work with peerlibrary:reactive-publish

?
This is what we get in our terminal as the error:

Exception in queued task: TypeError: Cannot call method 'idStringify' of undefined
at PublicationCollector.publish.added (packages/peerlibrary_reactive-publish/packages/peerlibrary_reactive-publish.js:283:1)
at added (packages/mongo/collection.js:346:11)
at packages/mongo/observe_multiplex.js:183:30
at Function..each..forEach (packages/underscore/underscore.js:108:1)
at Object.task (packages/mongo/observe_multiplex.js:177:9)
at [object Object]._.extend._run (packages/meteor/fiber_helpers.js:147:1)
at packages/meteor/fiber_helpers.js:125:1

Error when trying to use stubbed collections for publication tests

Hi,

I'm trying to use the hwillson:stub-collections package for publication tests. I would like to use stubbed collections to have the tests run quicker.

The stacktrace of the error I get is:

Can't publish a cursor from a collection without a name. at [object Object].LocalCollection.Cursor._publishCursor (packages/minimongo.js:265:11) at packages/johanbrook:publication-collector/publication-collector.js:49:20 at Array.map (native) at PublicationCollector.collect (packages/johanbrook:publication-collector/publication-collector.js:44:47)

The error occurs because the hwillson:stub-collections package creates an in-memory (minimongo) collection to replace the real collection and that is achieved by creating a new Meteor collection without a name (null).

I realise this problem isn't because of your package, but I am hoping you have some insight to share?

Thanks!

Error when using findOne() in publication

When using a findOne() query like so:

Meteor.publish('event', (id) => {
    return Events.findOne({_id: id})
})

I get an error when I try to call collect() on a publication collector:

Error: Object [object Object] has no method '_publishCursor'
    at packages/johanbrook:publication-collector/publication-collector.js:33:44

I realize findOne() doesn't return a cursor, but a document. For now I can use a regular find() query in the publication as a temporary workaround. Any suggestions on how to fix this issue?

"ready" event sent twice for publications using the low-level added/changed/removed interface

Hi,

First thanks for your package, it's really useful for testing Meteor publications.

With latest version I am getting following errors while testing my publications:
Error: done() called multiple times

Here the "done" function is the Mocha callback used for asynchronous code like the one you use in your usage example.

The publications I am testing are using the low-level added/changed/removed interface which means I am also calling the "ready" method once the initial record set is complete.
The problem in that case is that you're also calling "this.ready()" at the end of "collect" method and thus the callback passed to the "collect" method is called twice since it's part of the "ready" listener you're defining before calling the publication function.

That behavior was introduced in v1.0.5 since you're now adding the "ready" listener before calling the publication function.

I could be wrong but my recommendation would be to define an empty "ready" method on PublicationCollector class (like the stop() one) and use a different name for your custom ready event.

Let me know if that's not clear enough.
Thanks for your help.

-Nicolas

Exception when publication returns an empty array.

When testing the published data for this collection, userId = null, I get Publish function can only return a Cursor or an array of Cursors

Meteor.publish('kibanaDashboards', function () {
    //make sure that the user is logged in
    if (this.userId) {
        return KibanaDashboards.find({});
    } else {
        this.stop();
        return [];
    }
});

I think the collector should expect empty arrays and null values.

eslint setup

I did npm i, is there anything else I need to do to set up eslint? My editor (atom) is giving me Error: Cannot find module 'eslint-config-lookback/meteor'

Failing to resolve promise or call callback when an publication is empty

Hi guys. I spent a couple of days on this and finally narrowed down the problem. I have this publication:

Meteor.publish("game_requests",  function() {
  const user = Meteor.user();
  if (!user || !user.loggedOn) return [];
  if (Game.isPlayingGame(user)) return GameRequestCollection.find({ _id: "0" }); //return [];

  const id = user._id;
  if (!id) return [];
  return GameRequestCollection.find(
    {
      $or: [
        { challenger_id: id },
        { receiver_id: id },
        { owner: id },
        { matchingusers: id },
        { type: "seek" }
      ]
    },
    { fields: { matchingusers: 0 } }
  );
});

When I return find({_id: "0"}), collector.collect returns correctly.
When I return [], collector.collect does not resolve or call the callback.

According to the Meteor documentation, return [] is the accepted practice when returning an empty publication, right? Am I missing something, or is this an actual issue?

Thank you,
David Logan

Package doesn't handle limit/skip correctly

In the latest version of Meteor (1.7.x) the following error is thrown when collecting data from a publication published with limit and/or skip:

Error: Must use an ordered observe with skip or limit (i.e. 'addedBefore' for observeChanges or 'addedAt' for observe, instead of 'added').

This seems to originate within the package because the same publication works correctly outside of the test.

Inconsistent results when checking length of returned collection

My collection that is being returned sometimes has only two items in the array, but more than often it has three. Here is my code

import { PublicationCollector } from 'meteor/johanbrook:publication-collector';
import { chai, assert } from 'meteor/practicalmeteor:chai';
import { Communities } from '/imports/collections/communities.jsx'
import { Random } from 'meteor/random';
import { resetDatabase } from 'meteor/xolvio:cleaner';
import { _ } from 'meteor/stevezhu:lodash';

if (Meteor.isServer) {
  describe('communities', function () {
    before( () => {
      resetDatabase()

      _.times(3, () => {
         Factory.create("community");
      });
  })

    after( () => {
      resetDatabase()
    })

    it('publishes all communities', function (done) {
      const collector = new PublicationCollector();

       collector.collect('communities', (collections) => {
         console.log("\n\nCOMMUNITIES BEFORE\n\n")
         console.log(Communities.find().fetch() )
         console.log("\n\nCOMMUNITIES AFTER\n\n")
         console.log(collections)

         chai.assert.typeOf(collections.communities, 'array');
         chai.assert.equal(collections.communities.length, 3);
         done();
        });
    });
  });
};

Usually this passing fine, but about 1/5 times it returns with an error saying expected 3 items in array, got 2.

screenshot 2016-06-29 18 40 24

Refreshing once or twice, I then get the correct results

screenshot 2016-06-29 18 41 51

Here is my console logs of the incorrect results

screenshot 2016-06-29 18 45 19

And here is the console log of the correct results

screenshot 2016-06-29 18 48 33

So it seems like sometimes, collections.communities is just returning only two, since a straight database calls shows all three are actually in there. Any Idea?

Support multiple `collector.collect`-calls within 1 test

Hi Johan,

first of all: thanks for this cool package!! ๐Ÿ‘

I have a useCase where I am creating shitloads of fixtures (they take about 10 seconds to be created) and I'd love to write ONE integrational-test, testing different subscriptions - all within ONE test.

The problem is that collecter.collect can only be run ONCE within the testcase.

It would be so cool if we could use the syntax in synchronous style, so that we can call collecter.collect multiple times, like so:

  it('should allow to call collect multiple times', function() {
    const collector = new PublicationCollector({userId: Random.id()});

    collector.collect('publicationName', 'arg1', (collections) => {
      console.log('arg1')
      assert.equal(collections.myCollection.length, 10);
    });
    collector.collect('publicationName', 'arg2', (collections) => {
      // NOT called right now
      console.log('arg2')
      assert.equal(collections.myCollection.length, 10);
    });
  });

or

  it('should allow to call collect multiple times', function(done) {
    const collector = new PublicationCollector({userId: Random.id()});

    const differentArgumentValues = [
      'argValue1',
      'argValue2',
      'argValue3',
    ]
    _.each(differentArgumentValues, (currentArgument) => {
      collector.collect('publicationName', currentArgument, (collections) => {
        console.log(`testing currentArgument "${currentArgument}"`)  // only gets called for the first value "argValue1"
        assert.equal(collections.myCollection.length, 10);
      });
    })
    done();
  });

Any chance or trick of supporting this?

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.