jeudi 22 juin 2017

ember.js: Acceptance testing with an ajax request

I'm writing an acceptance test where a user fills in a form and an ajax request is made to a third party resource. I'm mocking the request with Ember CLI Mirage.

I'm writing a basic working example that I'll refactor after my tests pass. I know I need to abstract out my request into a service or utility but I don't like refactoring my code without a working test around it.

My code seems to work however, when I return a result that changes some content in the template, I can't get the test to pass.

It might be important to note: The third party API I am mocking out is not restful.

Here's the mirage config:

export default function() {
  this.post('/LogonAction', () => {
    return {foo: 'bar'};
  });
}

I haven't set the canonical URL of the web service yet. It should be an external service.

And my component:

import Ember from 'ember';

export default Ember.Component.extend({
  result: null,
  errors: null,
  usernameTextChanged: function() { this.reset(); }.observes('username'),
  passwordTextChanged: function() { this.reset(); }.observes('password'),
  reset() {
    this.set('errors', null);
    this.set('result', null);
  },
  actions: {
    sync() {
      this.reset();

      // TODO abstract out validation and add more use cases
      if(this.get('username') === undefined || this.get('password') === undefined) {
        this.set('errors', 'Please fill out the form');
      }
      else {
        // TODO abstract out into a utility and move config values into config
        let params = { userId: this.get('username'), passwd: this.get('password') }

        this.set('test', 'foos'); //just checking...

        Ember.$.post('/LogonAction', params).then((r) => {
          // This renders to console.
          console.log('promise happened 1', r, this.get('result')); 
          // Fails here. I don't know why.
          this.set('result', true);
          // This does not execute
          console.log('promise happened 2', this.get('result'));
        });
      }
    }
  }
});

You'll see that I output to console twice so I can debug it. I am not sure this is the right way to debug while I am writing tests.

This is my template:

<form id="logon" >
  
  
  <button>Click me</button>

  [[]] <!-- this is just debugging -->

  
    <div id="result">Sync complete</div>
  
  
    <div id="result"></div>
  
</form>

And finally, my test:

test('logging in', assert => {
  server.createList('LogonAction', 0);
  visit('/');

  console.log(0);

  fillIn('input.username', 'foo');
  fillIn('input.password', 'bar');
  click('button');

  console.log(1);

  andThen(() => {
    console.log(find('#logon').html());
    assert.equal(find('#result').text(), 'Sync complete')
  });
});

The console logging (I think) tells me that the promise is resolved before I assert that the page shows the result to the user. But I can't get this to pass! As soon as I set the value of result, it fails silently.

Any help, much appreciated.




Aucun commentaire:

Enregistrer un commentaire