Mirage responds 404 on acceptances tests - ember.js

I've been struggling with mirage for the past few days, and still haven't come up with a solution.
Even with a very simplified configuration (see below), mirage responds with a 404 error code whenever it is called within acceptance tests.
The calls do work perfectly when I serve my app and look at the browser console
(Mirage responds with a 200 status, and the data is here with the hello#world.com that I setup bellow).
Here's my mirage/config.js file
// mirage/config.js
export default function() {
this.get('/users', function() {
return {
data: [{
type: 'user',
id: 'first',
attributes: {
email: 'hello#world.com'
}
}]
};
});
}
Here's my app/routes/home.js
// app/routes/home.js
import Route from '#ember/routing/route';
export default Route.extend({
model() { return this.store.findAll('user'); }
});
Here's the failing test
import { module, test } from 'qunit';
import { visit, currentURL } from '#ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
module('Acceptance | home', function(hooks) {
setupApplicationTest(hooks);
test('visiting /home', async function(assert) {
await visit('/home');
assert.equal(currentURL(), '/home');
});
});
With this message:
Promise rejected during "visiting /home": Ember Data Request GET /users
returned a 404
Payload (Empty Content-Type)
Not found: /users# 152 ms
Source:
Error: Ember Data Request GET /users returned a 404
Payload (Empty Content-Type)
Not found: /users
at ErrorClass.EmberError
(http://localhost:7357/assets/vendor.js:24125:25)
at ErrorClass.AdapterError
(http://localhost:7357/assets/vendor.js:157167:15)
at new ErrorClass (http://localhost:7357/assets/vendor.js:157185:22)
at Class.handleResponse
(http://localhost:7357/assets/vendor.js:169227:18)
at ajaxError (http://localhost:7357/assets/vendor.js:169720:25)
at Class.hash.error
(http://localhost:7357/assets/vendor.js:169308:23)
at fire (http://localhost:7357/assets/vendor.js:3607:31)
at Object.fireWith [as rejectWith]
(http://localhost:7357/assets/vendor.js:3737:7)
at done (http://localhost:7357/assets/vendor.js:9646:14)
at XMLHttpRequest.<anonymous>
(http://localhost:7357/assets/vendor.js:9887:9)
Thank you

Are you sure Mirage is even running during your test?
If you're on a recent version of Ember, Mirage's default initializer may not be running. (This needs to be fixed.)
You might want to give the latest release notes a read, and make sure you're on version 0.4.2+.
In the new style of tests, you'll need to do something like
import { module, test } from 'qunit';
import { visit, currentURL } from '#ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
+ import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
module('Acceptance | login', function(hooks) {
setupApplicationTest(hooks);
+ setupMirage(hooks);
test('visiting /login', async function(assert) {
await visit('/login');
assert.equal(currentURL(), '/login');
});
});

Related

TypeError when using before all hook in ember mocha

I'm running into some issues with the before all hook in ember-mocha (version 0.14.0). Here's an example from the docs that's been slightly modified to include a beforeEach hook:
import { expect } from 'chai';
import { describe, it } from 'mocha';
import { setupApplicationTest } from 'ember-mocha';
import { visit, currentURL } from '#ember/test-helpers';
describe('basic acceptance test', function() {
setupApplicationTest();
beforeEach(async function() {
await visit('index');
});
it('can visit /', async function() {
await visit('/');
expect(currentURL()).to.equal('/');
});
});
The above test runs as expected with no issues. However, when I substitute before for beforeEach I encounter an error:
import { expect } from 'chai';
import { describe, it } from 'mocha';
import { setupApplicationTest } from 'ember-mocha';
import { visit, currentURL } from '#ember/test-helpers';
describe('basic acceptance test', function() {
setupApplicationTest();
before(async function() {
await visit('index');
});
it('can visit /', async function() {
await visit('/');
expect(currentURL()).to.equal('/');
});
});
TypeError: Cannot destructure property `owner` of 'undefined' or 'null'.
at visit (assets/test-support.js:24931:9)
at Context.<anonymous> (assets/tests.js:339:36)
at invoke (assets/test-support.js:22801:21)
at Context.asyncFn (assets/test-support.js:22786:11)
at callFnAsync (assets/test-support.js:14070:8)
at Hook.Runnable.run (assets/test-support.js:14022:7)
at next (assets/test-support.js:14386:10)
at assets/test-support.js:14408:5
at timeslice (assets/test-support.js:9651:27)
Please let me know if any clarification is needed. Thanks in advance for your help!
Thats expected!
before only runs once for all tests.
That means before all beforeEach hooks
However setupApplicationTest utilizes beforeEach to setup the app (and the container), and afterEach to tear it down again.
This means you get a fresh app for all tests.
However you can not really visit anything without an app.
This means for every test you get a new app instance.
This means there is no app for all tests so there is no app that could visit a route.
The same question was asked in the ember discord channel. This answer tries to take the essence of the discussion to archive it on SO.

How to setup ember-intl service in Ember integration tests?

I have just begun adding ember-intl into an application for which I had working tests. My acceptance tests are still working, but my integration tests on components whose templates are using ember-intl for string translation are failing with:
"No locale defined. Unable to resolve translation:..."
In the ember-intl docs there is a section on Integration Testing, which seems to be out of date:
import hbs from 'htmlbars-inline-precompile';
import wait from 'ember-test-helpers/wait';
import { moduleForComponent, test } from 'ember-qunit';
let service;
moduleForComponent('x-product', 'XProductComponent', {
integration: true,
setup() {
service = this.container.lookup('service:intl');
service.setLocale('en-us');
}
});
test('it renders', function(assert) {
assert.expect(1);
this.render(hbs`{{x-product price=price deadline=deadline}}`);
this.set('price', 1000);
this.set('deadline', new Date());
let output = this.$().text();
assert.ok(output);
});
test('it translates', function(assert) {
assert.expect(1);
/* waits for async behavior (loading translations on app boot) to settle */
return wait().then(() => {
assert.equal(service.t('some.key'), 'Hello world');
});
});
I've looked in the Ember docs and I can see how to stub a service for testing, but not how to just load the service in a test and then work with it.
Instead of using this.container, we now need to use this.owner in the new format tests. Here's a snippet of code showing how to use it in context:
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { find, render } from '#ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | login-form', function(hooks) {
setupRenderingTest(hooks);
let service;
hooks.beforeEach(function() {
service = this.owner.lookup('service:intl');
service.setLocale('en-us');
});
test('it renders', async function(assert) {
await render(hbs`{{login-form}}`);
assert.equal(find('[data-test-login-title]').textContent.trim(), 'Login');
});
});
A PR has been submitted to ember-intl, so hopefully the docs will reflect the latest best-practice soon.

Switching from .findall() to .query() breaks integration testing

I have a component that calls something like:
this.get('store')
.findAll('calendar-event')
.then((data) => {
// do stuff
});
However, when I replace findAll() with query() it breaks my integration testing.
this.get('store')
.query('calendar-event', { some_stuff: [596] })
.then((data) => {
// do stuff
});
The application in the web browser via ember server continues to function correctly. However: no luck with integration testing. Error I get is: TypeError: Cannot read property 'setObjects' of null
Integration test looks like:
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import moment from 'moment';
import startMirage from '../../helpers/setup-mirage-for-integration';
moduleForComponent('main-calendar', 'Integration | Component | main calendar', {
integration: true,
beforeEach() {
startMirage(this.container);
},
afterEach() {
window.server.shutdown();
}
});
test('it renders', function (assert) {
this.render(hbs`{{main-calendar}}`);
assert.equal(this.$('.col-sm.text-center').text().trim(), moment().format('MMMM YYYY'));
});
Any ideas why it would render with the server but not on the integration testing side of things.

Testing route with unauthenticatedRouteMixin fails with "Promise rejected before it exists"

THE ROUTE
import Ember from "ember";
import UnauthenticatedRouteMixin from 'ember-simple-auth/mixins/unauthenticated-route-mixin';
const {
Route,
} = Ember;​
export default Route.extend(UnauthenticatedRouteMixin, {
});
THE TEST
import { moduleFor, test } from 'ember-qunit';​
moduleFor('route:index', 'Unit | Route | index', {});
test('it exists', function(assert) {
var route = this.subject();
assert.ok(route);
});
THE ERROR
Promise rejected before it exists: Could not find module `ember-simple-auth/mixins/unauthenticated-route-mixin` imported from `appname/routes/index`
Ember: 1.13.15
Ember Simple Auth: 1.0.1
It is just the standard test generated by ember but fails everytime.
Thank you for any help

Import { module } from 'ember-qunit'

Looking over the Ember CLI docs, it says to create an integration test like so:
import Ember from "ember";
import { module, test } from 'ember-qunit';
import startApp from '../helpers/start-app';
var App;
module('An Integration test', {
beforeEach: function() {
App = startApp();
},
afterEach: function() {
Ember.run(App, App.destroy);
}
});
test("Page contents", function(assert) {
assert.expect(2);
visit('/foos').then(function() {
assert.equal(find('.foos-list').length, 1, "Page contains list of models");
assert.equal(find('.foos-list .foo-item').length, 5, "List contains expected number of models");
});
});
The problem is, this code results in:
TypeError: undefined is not a function
If I remove the test, I still get that error. If I remove the module, then I don't get the error. (But neither does qunit run the test.) This makes sense, because it looks like ember-qunit doesn't export a module.
So what am I suppose to do here?