mainmatter / ember-simple-auth

A library for implementing authentication/authorization in Ember.js applications.
https://ember-simple-auth.com
MIT License
1.92k stars 605 forks source link

Ember 1.9.1 #407

Closed chrisvdp closed 9 years ago

chrisvdp commented 9 years ago

I tried running the test suite against Ember 1.9.1 and Handlebars 2.0.0 and experienced a number of errors. The errors occur without the Handlebars upgrade as well

Running node v0.10.35 npm v2.2.0 OS X v10.10.1

$ grunt test
Running "jshint:library" (jshint) task
>> 39 files lint free.

Running "jshint:tests" (jshint) task
>> 27 files lint free.

Running "lintspaces:all" (lintspaces) task
>> 140 files lint free.

Running "clean:0" (clean) task

Running "clean:1" (clean) task
Cleaning tmp...OK

Running "transpile:amd" (transpile) task

Running "concat:amd" (concat) task
File "tmp/ember-simple-auth-cookie-store.amd.js" created.
File "tmp/ember-simple-auth-devise.amd.js" created.
File "tmp/ember-simple-auth-oauth2.amd.js" created.
File "tmp/ember-simple-auth-testing.amd.js" created.
File "tmp/ember-simple-auth-torii.amd.js" created.
File "tmp/ember-simple-auth.amd.js" created.

Running "concat:browser" (concat) task
File "tmp/ember-simple-auth-cookie-store.js" created.
File "tmp/ember-simple-auth-devise.js" created.
File "tmp/ember-simple-auth-oauth2.js" created.
File "tmp/ember-simple-auth-testing.js" created.
File "tmp/ember-simple-auth-torii.js" created.
File "tmp/ember-simple-auth.js" created.

Running "string-replace:version" (string-replace) task
File tmp/ember-simple-auth-cookie-store.amd.js created.
File tmp/ember-simple-auth-cookie-store.js created.
File tmp/ember-simple-auth-devise.amd.js created.
File tmp/ember-simple-auth-devise.js created.
File tmp/ember-simple-auth-oauth2.amd.js created.
File tmp/ember-simple-auth-oauth2.js created.
File tmp/ember-simple-auth-testing.amd.js created.
File tmp/ember-simple-auth-testing.js created.
File tmp/ember-simple-auth-torii.amd.js created.
File tmp/ember-simple-auth-torii.js created.
File tmp/ember-simple-auth.amd.js created.
File tmp/ember-simple-auth.js created.

Running "transpile:tests" (transpile) task

Running "concat:tests" (concat) task
File "tmp/ember-simple-auth-cookie-store-tests.amd.js" created.
File "tmp/ember-simple-auth-devise-tests.amd.js" created.
File "tmp/ember-simple-auth-oauth2-tests.amd.js" created.
File "tmp/ember-simple-auth-testing-tests.amd.js" created.
File "tmp/ember-simple-auth-torii-tests.amd.js" created.
File "tmp/ember-simple-auth-tests.amd.js" created.

Running "connect:dev" (connect) task
Started connect web server on http://0.0.0.0:8000

Running "mocha:test" (mocha) task
Testing: http://localhost:8000/test/index.html?
127.0.0.1 - GET /test/index.html? HTTP/1.1 200 1803 - 6 ms
127.0.0.1 - GET /test/vendor/mocha.css HTTP/1.1 200 4242 - 2 ms
127.0.0.1 - GET /test/lib/dependencies-loader.js HTTP/1.1 200 537 - 2 ms
127.0.0.1 - GET /test/lib/shims.js HTTP/1.1 200 312 - 2 ms
127.0.0.1 - GET /test/vendor/sinon-chai.js HTTP/1.1 200 5231 - 3 ms
127.0.0.1 - GET /test/vendor/chai.js HTTP/1.1 200 117322 - 4 ms
127.0.0.1 - GET /test/vendor/mocha.js HTTP/1.1 200 123164 - 4 ms
127.0.0.1 - GET /vendor/loader.js HTTP/1.1 200 1290 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth.amd.js HTTP/1.1 200 59916 - 2 ms
127.0.0.1 - GET /test/vendor/sinon.js HTTP/1.1 200 146138 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-oauth2.amd.js HTTP/1.1 200 16728 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth-cookie-store.amd.js HTTP/1.1 200 9753 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth-devise.amd.js HTTP/1.1 200 12851 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth-torii.amd.js HTTP/1.1 200 4506 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth-testing.amd.js HTTP/1.1 200 2544 - 2 ms
127.0.0.1 - GET /tmp/ember-simple-auth-tests.amd.js HTTP/1.1 200 65227 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-oauth2-tests.amd.js HTTP/1.1 200 23085 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-cookie-store-tests.amd.js HTTP/1.1 200 6358 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-devise-tests.amd.js HTTP/1.1 200 14675 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-torii-tests.amd.js HTTP/1.1 200 5694 - 4 ms
127.0.0.1 - GET /tmp/ember-simple-auth-testing-tests.amd.js HTTP/1.1 200 1414 - 3 ms
127.0.0.1 - GET /test/vendor/jquery-2.1.1.js HTTP/1.1 200 247351 - 5 ms
127.0.0.1 - GET /test/vendor/handlebars.js HTTP/1.1 200 100756 - 4 ms
127.0.0.1 - GET /test/vendor/ember-1.9.1.js HTTP/1.1 200 1629943 - 6 ms

  Authenticators.Base
    #restore
      ✓ returns a rejecting promise 
    #authenticate
      ✓ returns a rejecting promise 
    #invalidate
      ✓ returns a resolving promise 

  Configuration
    authenticationRoute
      ✓ defaults to "login" 
    routeAfterAuthentication
      ✓ defaults to "index" 
    routeIfAlreadyAuthenticated
      ✓ defaults to "index" 
    sessionPropertyName
      ✓ defaults to "session" 
    authorizer
      ✓ defaults to null 
    session
      ✓ defaults to "simple-auth-session:main" 
    store
      ✓ defaults to "simple-auth-session-store:local-storage" 
    localStorageKey
      ✓ defaults to "ember_simple_auth:session" 
    crossOriginWhitelist
      ✓ defaults to [] 
    .load
      ✓ sets applicationRootUrl to the application's root URL 
      ✓ sets authenticationRoute correctly 
      ✓ sets routeAfterAuthentication correctly 
      ✓ sets routeIfAlreadyAuthenticated correctly 
      ✓ sets sessionPropertyName correctly 
      ✓ sets authorizer correctly 
      ✓ sets session correctly 
      ✓ sets store correctly 
      ✓ sets localStorageKey correctly 
      ✓ sets crossOriginWhitelist correctly 

  the "simple-auth" initializer
    ✓ has the correct name 

  ApplicationRouteMixin
    #beforeModel
      when there is no active route
        ✓ sends the action to the transition 
      when there is an active route
        ✓ translates the session's 'sessionAuthenticationSucceeded' event into an action invocation 
        ✓ translates the session's 'sessionAuthenticationFailed' event into an action invocation 
        ✓ translates the session's 'sessionInvalidationSucceeded' event into an action invocation 
        ✓ translates the session's 'sessionInvalidationFailed' event into an action invocation 
        ✓ translates the session's 'authorizationFailed' event into an action invocation 
        ✓ does not attach the event listeners twice 
    the "authenticateSession" action
      ✓ transitions to "Configuration.authenticationRoute" 
    the "sessionAuthenticationSucceeded" action
      when an attempted transition is stored in the session
        ✓ retries that transition 
        ✓ removes it from the session 
      when no attempted transition is stored in the session
        ✓ transitions to "Configuration.routeAfterAuthentication" 
    the "invalidateSession" action
      ✓ invalidates the session 
    the "authorizationFailed" action
      when the session is authenticated
        ✓ invalidates the session 
      when the session is not authenticated
        ✓ does not try to invalidate the session 

  AuthenticatedRouteMixin
    #beforeModel
      if the session is authenticated
        ✓ does not abort the transition 
        ✓ does not invoke the "authenticateSession" action 
      if the session is not authenticated
        ✓ aborts the transition 
        ✓ invokes the "authenticateSession" action 

  AuthenticationControllerMixin
    the "authenticate" action
      ✓ authenticates the session 
      ✓ returns the promise returned by the session 

  LoginControllerMixin
    the "authenticate" action
      when both identification and password are set on the controller
        ✓ unsets the password 
        ✓ authenticates the session 
        ✓ returns the promise returned by the session 

  UnauthenticatedRouteMixin
    #beforeModel
      if the session is authenticated
        ✓ aborts the transition 
        ✓ transitions to routeIfAlreadyAuthenticated 
      if the session is not authenticated
        ✓ does not abort the transition 
        ✓ does not call route transitionTo 

  Session
    restore
      when the restored data contains an authenticator factory
        when the authenticator resolves restoration
          ✓ returns a resolving promise 
          ✓ is authenticated 
          ✓ merges its content to the data the authenticator resolves with 
          ✓ persists its content in the store 
          ✓ persists the authenticator factory in the store 
          ✓ does not trigger the "sessionAuthenticationSucceeded" event 
          when the authenticator triggers the "sessionDataUpdated" event
            ✓ merges its content to the data the event is triggered with 
          when the authenticator triggers the "invalidated" event
            ✓ is not authenticated 
            ✓ clears its content 
            ✓ clears the store 
            ✓ triggers the "sessionInvalidationSucceeded" event 
        when the authenticator rejects restoration
          ✓ returns a rejecting promise 
          ✓ is not authenticated 
          ✓ clears the store 
          ✓ does not trigger the "sessionAuthenticationFailed" event 
      when the restored data does not contain an authenticator factory
        ✓ returns a rejecting promise 
        ✓ is not authenticated 
        ✓ clears the store 
        ✓ does not trigger the "sessionAuthenticationFailed" event 
    authentication
      when the authenticator resolves authentication
        ✓ is authenticated 
        ✓ returns a resolving promise 
        ✓ merges its content to the data the authenticator resolves with 
        ✓ persists its content in the store 
        ✓ persists the authenticator factory in the store 
        ✓ triggers the "sessionAuthenticationSucceeded" event 
        ✓ does not trigger the "sessionAuthenticationFailed" event 
        when the authenticator triggers the "sessionDataUpdated" event
          ✓ merges its content to the data the event is triggered with 
        when the authenticator triggers the "invalidated" event
          ✓ is not authenticated 
          ✓ clears its content 
          ✓ clears the store 
          ✓ triggers the "sessionInvalidationSucceeded" event 
      when the authenticator rejects authentication
        ✓ is not authenticated 
        ✓ returns a rejecting promise 
        ✓ clears its content 
        ✓ clears the store 
        1) does not trigger the "sessionAuthenticationSucceeded" event
        ✓ does not trigger the "sessionAuthenticationSucceeded" event 
    invalidation
      when the authenticator resolves to invaldiation
        2) is not authenticated
        3) returns a resolving promise
        4) clears its content
        5) clears the store
        6) does not trigger the "sessionInvalidationFailed" event
        7) triggers the "sessionInvalidationSucceeded" event
      when the authenticator rejects invalidation
        ✓ stays authenticated 
        8) "before each" hook

  87 passing (1s)
  8 failing

  1) Session authentication when the authenticator rejects authentication does not trigger the "sessionAuthenticationSucceeded" event:
     Uncaught Error: Assertion Failed: error (http://localhost:8000/test/vendor/ember-1.9.1.js:3902)

  2) Session invalidation when the authenticator resolves to invaldiation is not authenticated:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:972
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  3) Session invalidation when the authenticator resolves to invaldiation returns a resolving promise:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:979
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  4) Session invalidation when the authenticator resolves to invaldiation clears its content:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:989
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  5) Session invalidation when the authenticator resolves to invaldiation clears the store:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:999
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  6) Session invalidation when the authenticator resolves to invaldiation does not trigger the "sessionInvalidationFailed" event:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:1008
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  7) Session invalidation when the authenticator resolves to invaldiation triggers the "sessionInvalidationSucceeded" event:
     Error: Assertion Failed: Session#invalidate requires the session to be authenticated
      at http://localhost:8000/test/vendor/ember-1.9.1.js:3902
      at http://localhost:8000/tmp/ember-simple-auth.amd.js:1049
      at http://localhost:8000/tmp/ember-simple-auth-tests.amd.js:1022
      at http://localhost:8000/test/vendor/mocha.js:4323
      at http://localhost:8000/test/vendor/mocha.js:4724
      at http://localhost:8000/test/vendor/mocha.js:4815
      at next (http://localhost:8000/test/vendor/mocha.js:4649)
      at http://localhost:8000/test/vendor/mocha.js:4659
      at next (http://localhost:8000/test/vendor/mocha.js:4597)
      at http://localhost:8000/test/vendor/mocha.js:4621
      at http://localhost:8000/test/vendor/mocha.js:4338
      at next (http://localhost:8000/test/vendor/mocha.js:4622)
      at http://localhost:8000/test/vendor/mocha.js:4626
      at timeslice (http://localhost:8000/test/vendor/mocha.js:5733)

  8) Session invalidation "before each" hook:
     Uncaught Error: Assertion Failed: error (http://localhost:8000/test/vendor/ember-1.9.1.js:3902)

>> 8/95 tests failed (1.36s)
Warning: Task "mocha:test" failed. Use --force to continue.

Aborted due to warnings.
chrisvdp commented 9 years ago

At least part of the problem we were experiencing is due to ember-simple-auth/packages/ember-simple-auth/lib/simple-auth/session.js:171 rejecting the promise with the error object. This seems to cause ember to try and log the error and throwing a EmberError when an assertion fails. Removing the error object from the reject call fixes 5 tests.

marcoow commented 9 years ago

But that's actually needed so the error propagates correctly ;)

chrisvdp commented 9 years ago

More of an FYI into my investigation. :P

marcoow commented 9 years ago

Sure, it's the same in this beforeEach - if the 'error' argument is removed it doesn't fail right there but of course the assertion here fails.

chrisvdp commented 9 years ago

It might need to be fixed in the authenticator libraries? I notice I get the same results if I change ember-simple-auth-oauth2/lib/simple-auth-oauth2/authenticators/oauth2.js:163-165 to

Ember.run(function() {
    reject();
});

previously

Ember.run(function() {
    reject(xhr.responseJSON || xhr.responseText);
});
marcoow commented 9 years ago

Yeah, but that cannot be removed as the error needs to propagate.

marcoow commented 9 years ago

There seem to be errors with earlier versions of Ember already - I wonder why it was working before... Help would be greatly appreciated with this ;)

The best way to run the test locally is to run grunt server and the open http://localhost:8000/test/ (which can also be run with certain versions of Ember, jQuery etc., e.g. http://localhost:8000/test/?ember=1.8.1&jQuery=2.1.3&handlebars=1.3.0 - see .travis.yml for the full matrix).

chrisvdp commented 9 years ago

As far as I can tell, it's the propagation that is the issue with Ember. It sees the rejected promise with it's reason and tries to publish it. RSVP.onerrorDefault checks if there is an error and, in testing mode, calls Logger.error(error.stack); on the object. Since this object has no stack property, it fails. I have tried overriding onerror and this fixes it when running manually, but I still get the error in test mode due to the testing path in RSVP.onerrorDefault

marcoow commented 9 years ago

I see. Can we maybe replace RSVP.onerrorDefault for the runs somehow?

elidupuis commented 9 years ago

FYI, I'm also getting this error after sessionAuthenticationFailed is fired. I'm on Ember 1.9.1 and Ember Simple Auth 0.7.2. Looks like Logger.error(error.stack); is the default in RSVP.onerrorDefault, not just in testing mode.

screen shot 2015-01-21 at 2 08 52 pm

chrisvdp commented 9 years ago

@elidupuis didn't mean to imply that it wasn't happening in both modes, but you can override the orerror handler running normally, but not in testing mode.

RSVP.onerrorDefault = function (error) {
      if (error && error.name !== 'TransitionAborted') {
        if (Ember.testing) {
          // ES6TODO: remove when possible
          if (!Test && Ember.__loader.registry[testModuleName]) {
            Test = requireModule(testModuleName)['default'];
          }

          if (Test && Test.adapter) {
            Test.adapter.exception(error);
            Logger.error(error.stack);
          } else {
            throw error;
          }
        } else if (Ember.onerror) {
          Ember.onerror(error);
        } else {
          Logger.error(error.stack);
          Ember.assert(error, false);
        }
      }
    };
chrisvdp commented 9 years ago

To override you can use Ember.onerror = Ember.K

chrisvdp commented 9 years ago

@marcoow not that I can see

elidupuis commented 9 years ago

@chrisvdp thanks for the tip. I added an Ember.onerror implementation and I'm no longer getting this error.

marcoow commented 9 years ago

fixed

joshsmith commented 9 years ago

How was this issue fixed? I'm still seeing this error.