0

I have some acceptance tests that test a component. If I run each test separately, they pass just fine. However, when I run the tests together, they fail because they're retaining the values from the previous tests.

Here is my code:

filter-test.js

module('Integration - Filter', {
  beforeEach: function() {
    App = startApp();
    server = setupPretender();
    authenticateSession();
  },
  afterEach: function() {
    Ember.run(App, 'destroy');
    server.shutdown();
  }
});

test('filters can be saved and selected via the dropdown', function(assert) {
  visit('/status');
  fillIn('.filter-status', 'Not Completed');
  fillIn('.filter-id', '444');

  andThen(function() {
    assert.ok(find('.status-title').text().includes('2 of 7'), 'the new filter filters the results');
  });
});

test('only saved filters can be edited', function(assert) {
  visit('/status');
  fillIn('.filter-id', 'not an id');
  click('.update-filter');

  andThen(function() {
    assert.equal(find('.alert').text(), 'Not a Saved Filter×');
  });
});

test('filter values can be cleared', function(assert) {
  visit('/status');
  fillIn('.filter-id', '444');
  fillIn('.filter-status', 'Completed');
  click('.clear-filters');

  andThen(function() {
    // this fails because `.filter-id` is set to 'not an id':
    assert.equal(find('.filter-id').val(), '', 'filter for was reset to its initial value');
    // this also fails because `.filter-status` is set to 'Not Completed':
    assert.equal(find('.filter-status').val(), 'Everything', 'status dropdown was reset to its initial value');
  });
});

ps-filter/component.js

export default Ember.Component.extend({
  classNames: ['panel', 'panel-default', 'filter-panel'],
  currentFilter: null,
  initialValues: null,

  didInsertElement: function() {
    this.set('initialValues', Ember.copy(this.get('filterValues')));
  },

  actions: {
    saveFilter: function(name) {
      var filters = this._getFilterList();
      var filterValues = this.get('filterValues');

      if (!Ember.isEmpty(name)) {
        filters[name] = filterValues;

        this.sendAction('updateFilter', filters);
        this.set('currentFilter', name);
      }
    },

    updateFilter: function() {
      var filterValues = this.get('filterValues');
      var currentFilter = this.get('currentFilter')
      var filters = this.get('userFilters');

      filters[currentFilter] = filterValues;

      this.sendAction('updateFilter', filters);
    },

    clearFilters: function() {
      this.set('currentFilter', null);
      this.set('filterValues', Ember.copy(this.get('initialValues')));
    }
  }
});

status/controller.js

export default Ember.ArrayController.extend({
  filterValues: {
    filterStatus: 'Everything',
    filterId: 'id',
  },
  userFilters: Ember.computed.alias('currentUser.content.preferences.filters')
});

status/template.hbs

<div class="row">
  {{ps-filter
    filterValues=filterValues
    userFilters=userFilters
    updateFilter='updateFilter'
  }}
</div>

From what I gathered, it seems that it sets the initialValues to the filterValues left over from the previous test. However, I thought that the afterEach was supposed to reset it to its original state. Is there a reason why it doesn't reset it to the values in the controller?

Note that the component works normally when I run it in development.

Ember versions listed in the Ember Inspector:

Ember      : 1.11.3
Ember Data : 1.0.0-beta.18

I'm running Ember CLI 0.2.7.

Edit

I don't think this is the issue at all, but here is my pretender setup:

tests/helpers/setup-pretender.js

export default function setupPretender(attrs) {
  var users = [
    {
      id: 1,
      name: 'ttest',
      preferences: null
    }
  ];

  var activities = [
    {
      id: 36874,
      activity_identifier: '18291',
      status: 'Complete'
    }, {
      id: 36873,
      activity_identifier: '82012',
      status: 'In Progress'
    }, {
      id: 35847,
      activity_identifier: '189190',
      status: 'In Progress'
    }, {
      id: 35858,
      activity_identifier: '189076',
      status: 'Not Started'
    }, {
      id: 382901,
      activity_identifier: '182730',
      status: 'Not Started'
    }, {
      id: 400293,
      activity_identifier: '88392',
      status: 'Complete'
    }, {
      id: 400402,
      activity_identifier: '88547',
      status: 'Complete'
    }
  ];

  return new Pretender(function() {
    this.get('api/v1/users/:id', function(request) {
      var user = users.find(function(user) {
        if (user.id === parseInt(request.params.id, 10)) {
          return user;
        }
      });

      return [200, {"Content-Type": "application/json"}, JSON.stringify({user: user})];
    });

    this.get('api/v1/activities', function(request) {
      return [200, {"Content-Type": "application/json"}, JSON.stringify({
        activities: activities
      })];
    });

    this.put('api/v1/users/:id', function(request) {
      var response = Ember.$.parseJSON(request.requestBody);
      response.user.id = parseInt(request.params.id, 10);

      var oldUser = users.find(function(user) {
        if (user.id === parseInt(request.params.id, 10)) {
          return user;
        }
      });
      var oldUserIndex = users.indexOf(oldUser);

      if (oldUserIndex > -1) {
        users.splice(oldUserIndex, 1);
        users.push(response.user);
      }

      return [200, {"Content-Type": "application/json"}, JSON.stringify(response)];
    });
  });
}

When I run the tests, it fails because it reset the value to the one in the previous test. For example, when I run 'filter values can be cleared', the .filter-id input has the same .filter-id value from 'only saved filter can be edited. If I change the value in 'only saved filters can be edited'back to '', the 'filter values can be cleared' test passes.

Basically, the component sets the initialValues property when it first inserts the element. It's set to a copy of the filterValues property, so it should be set to the controller's filterValues property, and shouldn't change. However, it seems that the modified filterValues property is carried over to the next test, which means that initialValues is set to that modified property when it rerenders. So, the test rerenders the templates, but retains the modified values in the controller and component.

I can make the tests pass by creating an initialValues property in the controller and passing that into the component, but that'd mean having duplicate properties in the controller (since filterValues and initialValues would have the same values).

I could modify the user record in the component, but I thought we're supposed to only modify records in the controller or router. Besides, isn't the afterEach hook supposed to reset the app?

NJP
  • 815
  • 1
  • 7
  • 20
  • just to clarify -is this a pretender problem? if so -can you show a lot more about your pretender setup/config/version ? – Toran Billups Jul 14 '15 at 01:55
  • Sure, I'll include it. I don't think that's the case, since it looks like the component is retaining the `filterValues` from the previous tests. I'm willing to explore all possible solutions, though. – NJP Jul 14 '15 at 19:12

0 Answers0