How do you test Collection.allow( ) functions that rely on the user ID?

If you want to see how it looks like you can check this branch out

Try this:

Also, perhaps we should write this down in some docs somewhere.

Sorry kind of confused as to what to get from your reply. However, looking at it, it seems that it may not be a good idea to even try to do what I am doing since the Apollo data system may change things. Plus it seems to rely on low level packages like DDP.

Yeah we don’t recommend using the collection hooks package in general, in part because of its reliance on the global user ID. Instead, it’s better to pass the user ID to where you need to use it. But, the code I posted is totally reliable.

Oh I get you, you’re code is for setting the user ID in the collection. Not sure, but I got that working on my other project already using the https://github.com/matb33/meteor-collection-hooks I was trying to do something slightly differently by following the guide http://guide.meteor.com/collections.html#default-value where some values were set. I just chose the current user as a sample but I guess I can try a simpler value.

However, my question is more how do you create an automated test that proves that it works.

Actually, @sashko just reminded me that what I am doing can only be done on the ‘client’ side because that’s the only place where allow() makes sense because the client call would send the userId value down to the allow check. I just switched things around so the tests is now on the client.

The good news is that I can get the “failure” scenario passing now. However, it’s not valid because the error I got was a 404.

it('can fail to add to a collection when the user is not logged in', (done) => {
  expect(Tasks.find({}).fetch()).to.be.empty
  Tasks.insert({
    text: 'hello world'
  }, (error) => {
    assert(error)
    done()
  })
})

The bad news is I can’t get the authorized user test to work.

let sandbox
beforeEach(() => {
  sandbox = sinon.sandbox.create()
  sandbox.stub(Meteor, 'userId').returns(42)
})
afterEach(() => {
  sandbox.restore()
})
it('can add to a collection', (done) => {
  expect(Tasks.find({}).fetch()).to.be.empty
  Tasks.insert({
    text: 'hello world'
  }, (error) => {
    console.log(error)
    assert(!error)
    const results = Tasks.find({}).fetch()
    expect(results).to.have.lengthOf(1)
    expect(results[0].defaultValue).to.equal(42)
    expect(results[0].createdOn).to.not.be.undefined
    done()
  })
})

The error on console looks like this

errorClass {
  error: 404, 
  reason: "Method '/tasks/insert' not found", 
  details: undefined, 
  message: "Method '/tasks/insert' not found [404]", 
  errorType: "Meteor.Error"
}

I’m looking around for other examples for testing including the one from @Sanjo and socially but they seem to have a pattern of using spyOn(SomeCollection, 'insert') rather than using the real collection. I guess it’s because the real collection is not available on client tests?