mardi 3 janvier 2017

When testing, one instance of store.query never resolves

I am trying to write acceptance CRUD tests for my Ember app. Basically, I have a model ("Customer") that I want to create, edit, and delete in an acceptance test. When a Customer is created, I use ember-validate to do an async validation. This validation makes a call to the server using store.query. When I am running my acceptance test on its own, it works fine. However, when the test is proceeded by another test that uses the visit() helper, the test fails because that async validation never resolves, and thus a customer cannot be created. The call to store.query does successfully query the server, and it get's a response, but for some reason, the then(), catch(), and finally() hooks never get called. Has anyone run into this sort of thing before?

I've spent hours in the debugger following the call stack trying to find where the promise gets stuck, but I've not had much luck.

Here's some more details:

My test - made more generic for easier understanding

import Ember from "ember";
import { module, test } from 'qunit';
import startApp from 'my-app/tests/helpers/start-app';

module('Acceptance | customer', {
    setup() {
        this.application = startApp();

        this.createCustomer = function (unique) {
            // The process of creating a customer...
            return wait();
        };
        this.editCustomer = function (unique) {
            // The process of editing a customer
            return wait();
        };
    },
    teardown() {
        Ember.run(this.application, 'destroy');
    }
});

// This test doesn't do anything except visit the root url. If I comment out or skip this test, the next test passes. Otherwise, the next test fails.
test(` loads`, () => {
    expect(1);

    visit('/');
    andThen(() => {
        ok(true);
    });
});

test('a customer can be managed', function (assert) {
    const UNIQUE = //Some method for getting a unique string;

    expect(3);

    // Go to the home page
    visit('/');

    // Create a customer
    andThen(() => this.createCustomer(UNIQUE));

    // Assert that creation was successful
    andThen(() => {
        assert.ok('Some criteria that determines that the customer was created');
    });

    // Edit the customer
    andThen(() => this.editCustomer(UNIQUE));

    // Assert that we successfully edited the customer
    andThen(() => {
        assert.ok('Some criteria that determines that the customer was edited');
    });
});

My validator - made more generic for easier understanding

import Ember from 'ember';
import ValidationsMixin from 'some-mixin';

export default Ember.Object.extend(ValidationsMixin, {
    /**
     * The Ember data store.
     */
    store: Ember.inject.service('store'),

    /**
     * The customer.
     */
    customer: null,

    validations: {
        'customer.primaryDomain': {
            presence: true,

            format: \some-regex\,

            async() {
                let store = this.get('store');
                let domain = this.get('customer.primaryDomain');

                if (Ember.isEmpty(domain)) {
                    return Ember.RSVP.resolve(true);
                }

                // Validate that no other customers exist with the same domain
                const promise = store.query('customer', {
                    primaryDomainList: [domain]
                });

                // At this point, the promise object is created, but this .then() hook may never get called even though the ajax request was successful.
                promise.then(customers => {
                    // Some extra code that isn't relevant
                });

                return promise;
            }
        },

        'customer.companyName': {
            presence: true
        }
    }
});




Aucun commentaire:

Enregistrer un commentaire