Skip to content

Instantly share code, notes, and snippets.

@cristinawithout
Last active May 6, 2021 21:37
Show Gist options
  • Save cristinawithout/b38580216c196ef8668d1dbdb5c651f2 to your computer and use it in GitHub Desktop.
Save cristinawithout/b38580216c196ef8668d1dbdb5c651f2 to your computer and use it in GitHub Desktop.
Technical Exercise
import Component from '@ember/component';
import { get } from '@ember/object';
import { inject as service } from '@ember/service';
export default Component.extend({
store: service(),
/**
* @property airport
* @required
*/
airport: null,
/**
* The type of flight for the airport: departing or arriving.
*
* @property flightType
* @type {string}
* @required
*/
flightType: null,
flights: null,
isLoading: false,
loadingError: false,
didReceiveAttrs() {
let airportId = get(this.airport, 'id');
this.fetchFlights(airportId);
},
/**
* @method fetchFlights
* @param airportId {String}
*/
fetchFlights(airportId) {
this.set('isLoading', true);
this.set('loadingError', false);
let queryParam;
if (this.flightType === 'departing') {
queryParam = 'origin_id';
} else if (this.flightType === 'arriving') {
queryParam = 'destination_id';
}
if (queryParam) {
let query = {};
query[queryParam] = airportId;
this.store.query('flight', query)
.then( (result) => {
this.set('flights', result);
})
.catch( () => {
this.set('loadingError', true);
})
.finally( () => {
this.set('isLoading', false);
});
} else {
this.set('isLoading', false);
this.set('loadingError', true);
}
}
}).reopenClass({
positionalParams: ['airport', 'flightType']
});
import Component from '@ember/component';
export default Component.extend({
dataTest: 'airport-item',
airport: null
}).reopenClass({
positionalParams: ['airport']
});
import Component from '@ember/component';
export default Component.extend({
dataTest: 'flight-item',
flight: null
}).reopenClass({
positionalParams: ['flight']
});
import Controller from '@ember/controller';
export default Controller.extend({
appName: 'Flight Tracker'
});
/**
* This initializer reopens objects as needed in order to
* bind the data-test attribute for selecting during tests.
*/
import LinkComponent from '@ember/routing/link-component';
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
export function initialize( /*application*/ ) {
LinkComponent.reopen({
attributeBindings: ['data-test']
});
Component.reopen({
attributeBindings: ['dataTest:data-test']
});
};
export default function() {
window.server = this;
this.logging = true;
this.get('/airports');
this.get('/airports/:id');
this.get('/flights', ({ flights }, request) => {
let matches;
let originId = request.queryParams.origin_id;
let destinationId = request.queryParams.destination_id;
if (originId) {
matches = flights.where({ 'originId': originId });
} else if (destinationId) {
matches = flights.where({ 'destinationId': destinationId });
} else {
matches = flights.all();
}
return matches;
});
this.get('/flights/:id');
this.get('/passengers', ({ passengers }, request) => {
let matches;
let flightId = request.queryParams.flight_id;
if (flightId) {
matches = passengers.where({ 'flightId': flightId });
} else {
matches = passengers.all();
}
return matches;
});
this.get('/passengers/:id');
};
import { Factory } from 'ember-cli-mirage';
export default Factory.extend({
});
import { Factory } from 'ember-cli-mirage';
export default Factory.extend({});
import { Factory } from 'ember-cli-mirage';
export default Factory.extend({
});
export default [
{
id: "7df8241a-e83b-4688-a03f-33a7ffc40212",
name: "John Wayne Airport",
icao: "KSNA",
iata: "SNA",
img_url: "https://via.placeholder.com/50x50.png?text=SNA"
},
{
id: "5ecfc966-2483-49d5-ad06-02b953334edc",
name: "Los Angeles International Airport",
icao: "KLAX",
iata: "LAX",
img_url: "https://via.placeholder.com/50x50.png?text=LAX"
},
{
id: "20509d19-84f0-4e9c-9868-5d827740ba6e",
name: "Osaka International Airport",
icao: "RJOO",
iata: "ITM",
img_url: "https://via.placeholder.com/50x50.png?text=ITM"
},
{
id: "fce2618a-78eb-4835-8d8e-69ec6474b736",
name: "Zurich Airport",
icao: "LSZH",
iata: "ZRH",
img_url: "https://via.placeholder.com/50x50.png?text=ZRH"
}
];
export default [
{
id: "032d5fca-31f5-4040-9779-2a355345d132",
number: "325",
departure_time: "2021-08-28T01:26:00Z",
arrival_time: "2021-08-28T12:18:00Z",
originId: "fce2618a-78eb-4835-8d8e-69ec6474b736",
destinationId: "5ecfc966-2483-49d5-ad06-02b953334edc"
},
{
id: "591e6a88-1f3b-4f30-8b5a-e460e61f1d10",
number: "887",
departure_time: "2021-08-27T02:45:00Z",
arrival_time: "2021-08-28T22:34:00Z",
originId: "20509d19-84f0-4e9c-9868-5d827740ba6e",
destinationId: "5ecfc966-2483-49d5-ad06-02b953334edc"
},
{
id: "9e0eac64-bbe7-4bbb-b45b-b945383138bc",
number: "4875",
departure_time: "2021-08-27T07:56:00Z",
arrival_time: "2021-08-27T19:38:00Z",
originId: "20509d19-84f0-4e9c-9868-5d827740ba6e",
destinationId: "fce2618a-78eb-4835-8d8e-69ec6474b736"
},
{
id: "53ea0468-c739-44e5-ae1e-9f03425ff925",
number: "6575",
departure_time: "2021-08-27T11:45:00Z",
arrival_time: "2021-08-28T20:22:00Z",
originId: "20509d19-84f0-4e9c-9868-5d827740ba6e",
destinationId: "5ecfc966-2483-49d5-ad06-02b953334edc"
},
{
id: "4c2c91fa-2684-4876-9c50-8a38be74ef2b",
number: "2456",
departure_time: "2021-08-27T11:45:00Z",
arrival_time: "2021-08-28T22:25:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "fce2618a-78eb-4835-8d8e-69ec6474b736"
},
{
id: "e7ceee8c-ce44-4e08-a6c7-14caeefabada",
number: "6784",
departure_time: "2021-08-27T11:45:00Z",
arrival_time: "2021-08-28T22:25:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "fce2618a-78eb-4835-8d8e-69ec6474b736"
},
{
id: "70fc83a7-df1b-43db-b8e1-3acfeabca7de",
number: "8856",
departure_time: "2021-08-27T22:45:00Z",
arrival_time: "2021-08-28T12:25:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "fce2618a-78eb-4835-8d8e-69ec6474b736"
},
{
id: "babec0d2-5600-4f97-b262-f33d970d0fd8",
number: "525",
departure_time: "2021-08-28T12:45:00Z",
arrival_time: "2021-08-28T18:25:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "20509d19-84f0-4e9c-9868-5d827740ba6e"
},
{
id: "315e3e82-9dee-4bf6-9972-9aca3ede89d1",
number: "37",
departure_time: "2021-08-27T10:15:00Z",
arrival_time: "2021-08-27T16:43:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "20509d19-84f0-4e9c-9868-5d827740ba6e"
},
{
id: "4b10dc91-1fb6-4c29-89b2-9565d17f17a9",
number: "456",
departure_time: "2021-08-27T10:18:00Z",
arrival_time: "2021-08-27T17:43:00Z",
originId: "5ecfc966-2483-49d5-ad06-02b953334edc",
destinationId: "7df8241a-e83b-4688-a03f-33a7ffc40212"
}
];
export default [
{
first_name: 'Jane',
last_name: 'Johnson',
flightId: '032d5fca-31f5-4040-9779-2a355345d132'
},
{
first_name: 'Joe',
last_name: 'Smith',
flightId: '4c2c91fa-2684-4876-9c50-8a38be74ef2b'
},
{
first_name: 'Alex',
last_name: 'Jin',
flightId: '4c2c91fa-2684-4876-9c50-8a38be74ef2b'
},
{
first_name: 'Luis',
last_name: 'Morales',
flightId: '4c2c91fa-2684-4876-9c50-8a38be74ef2b'
},
{
first_name: 'Sam',
last_name: 'Boxer',
flightId: '032d5fca-31f5-4040-9779-2a355345d132'
},
{
first_name: 'Sally',
last_name: 'Sue',
flightId: '032d5fca-31f5-4040-9779-2a355345d132'
},
{
first_name: 'Ritesh',
last_name: 'Agarwal',
flightId: '032d5fca-31f5-4040-9779-2a355345d132'
},
{
first_name: 'André',
last_name: 'Augustin',
flightId: '032d5fca-31f5-4040-9779-2a355345d132'
},
{
first_name: 'Aron',
last_name: 'Man',
flightId: '9e0eac64-bbe7-4bbb-b45b-b945383138bc'
},
{
first_name: 'Jerry',
last_name: 'Shepherd',
flightId: '4c2c91fa-2684-4876-9c50-8a38be74ef2b'
},
{
first_name: 'Tai',
last_name: 'Vu',
flightId: '4c2c91fa-2684-4876-9c50-8a38be74ef2b'
},
{
first_name: 'Lam',
last_name: 'Vu',
flightId: '591e6a88-1f3b-4f30-8b5a-e460e61f1d10'
},
{
first_name: 'Alice',
last_name: 'Larsen',
flightId: '591e6a88-1f3b-4f30-8b5a-e460e61f1d10'
},
{
first_name: 'An',
last_name: 'Yang',
flightId: '591e6a88-1f3b-4f30-8b5a-e460e61f1d10'
},
{
first_name: 'Bell',
last_name: 'Winston',
flightId: '591e6a88-1f3b-4f30-8b5a-e460e61f1d10'
},
{
first_name: 'Zev',
last_name: 'Barton',
flightId: '53ea0468-c739-44e5-ae1e-9f03425ff925'
},
{
first_name: 'Chati',
last_name: 'Saelim',
flightId: '53ea0468-c739-44e5-ae1e-9f03425ff925'
},
{
first_name: 'Amelia',
last_name: 'Pond',
flightId: '53ea0468-c739-44e5-ae1e-9f03425ff925'
},
{
first_name: 'Jacob',
last_name: 'Zhang',
flightId: '53ea0468-c739-44e5-ae1e-9f03425ff925'
},
{
first_name: 'Terrance',
last_name: 'Jones',
flightId: 'e7ceee8c-ce44-4e08-a6c7-14caeefabada'
},
{
first_name: 'Leela',
last_name: 'Lemon',
flightId: 'e7ceee8c-ce44-4e08-a6c7-14caeefabada'
},
{
first_name: 'Erin',
last_name: 'González',
flightId: 'e7ceee8c-ce44-4e08-a6c7-14caeefabada'
},
{
first_name: 'Isha',
last_name: 'Patel',
flightId: 'e7ceee8c-ce44-4e08-a6c7-14caeefabada'
},
{
first_name: 'Simon',
last_name: 'Sanders',
flightId: '70fc83a7-df1b-43db-b8e1-3acfeabca7de'
},
{
first_name: 'Kavi',
last_name: 'Reddy',
flightId: '70fc83a7-df1b-43db-b8e1-3acfeabca7de'
},
{
first_name: 'Sara',
last_name: 'Zhou',
flightId: '70fc83a7-df1b-43db-b8e1-3acfeabca7de'
},
{
first_name: 'Sierra',
last_name: 'Brooke',
flightId: '70fc83a7-df1b-43db-b8e1-3acfeabca7de'
},
{
first_name: 'Xuan',
last_name: 'Pham',
flightId: '70fc83a7-df1b-43db-b8e1-3acfeabca7de'
},
{
first_name: 'Keshon',
last_name: 'Carpenter',
flightId: 'babec0d2-5600-4f97-b262-f33d970d0fd8'
},
{
first_name: 'Lisa',
last_name: 'Pérez',
flightId: 'babec0d2-5600-4f97-b262-f33d970d0fd8'
},
{
first_name: 'Janet',
last_name: 'Lewis',
flightId: '315e3e82-9dee-4bf6-9972-9aca3ede89d1'
},
{
first_name: 'Mei',
last_name: 'Wu',
flightId: '315e3e82-9dee-4bf6-9972-9aca3ede89d1'
},
{
first_name: 'Sue',
last_name: 'Stephens',
flightId: '315e3e82-9dee-4bf6-9972-9aca3ede89d1'
}
];
export default function(server) {
server.loadFixtures('airports');
server.loadFixtures('flights');
server.loadFixtures('passengers');
}
import Serializer from './application';
export default Serializer.extend({
});
import Serializer from './application';
export default Serializer.extend({
include: ['origin', 'destination']
});
import Serializer from './application';
export default Serializer.extend({
include: ['flight']
});
import DS from 'ember-data';
const { attr, hasMany, Model } = DS;
export default Model.extend({
name: attr('string'),
icao: attr('string'),
iata: attr('string'),
img_url: attr('string'),
flights: hasMany('flight', { inverse: null }),
arriving_flights: hasMany('flight', { inverse: 'destination' }),
departing_flights: hasMany('flight', { inverse: 'origin' })
});
import DS from 'ember-data';
const { attr, belongsTo, hasMany, Model } = DS;
export default Model.extend({
number: attr('string'),
departure_time: attr('date'),
arrival_time: attr('date'),
origin: belongsTo('airport'),
destination: belongsTo('airport'),
passengers: hasMany('passenger')
});
import DS from 'ember-data';
import { computed } from '@ember/object';
const { attr, belongsTo, Model } = DS;
export default Model.extend({
first_name: attr('string'),
last_name: attr('string'),
full_name: computed('first_name', 'last_name', function() {
return `${this.first_name} ${this.last_name}`;
}),
flight: belongsTo('flight')
});
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('about');
this.route('airports', function() {
this.route('airport', {path: ':airport_id'});
});
this.route('flights', function() {});
});
export default Router;
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
store: service('store'),
model(params) {
return this.store.findRecord('airport', params.airport_id);
}
});
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
store: service('store'),
model() {
return this.store.findAll('airport');
}
});
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
store: service('store'),
model() {
return this.store.findAll('flight');
}
});
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.margin-top {
margin-top: 15px;
}
.margin-bottom {
margin-bottom: .5rem;
}
.detail {
display: flex;
flex-wrap:wrap;
}
.detail-label {
display: flex;
flex-direction: row;
padding: 0.5rem;
font-weight: bold;
min-width: 15%;
}
.detail-value {
display: flex;
flex-direction: column;
padding: 0.5rem;
flex-grow: 1;
}
<h2>About</h2>
<p class="text-center">
<img src="https://via.placeholder.com/250x90.png" class="img-rounded">
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut ligula nunc, imperdiet vulputate pulvinar non, porttitor id leo. Pellentesque congue tellus et tempus faucibus. Nulla eleifend orci odio, id tempus elit ultrices quis. Sed ac venenatis lorem, ac suscipit mi. Mauris quis purus vel magna interdum ullamcorper vel eu lectus. Maecenas laoreet felis pretium tortor egestas, sed mollis nulla luctus. Praesent iaculis blandit porttitor. Integer aliquam leo enim. Nam suscipit mauris eu massa consequat, quis condimentum lectus volutpat. Nam ligula est, sollicitudin non blandit a, lacinia eget elit. Vestibulum non justo et leo aliquet ultricies in eget urna. Donec varius, orci eget dapibus feugiat, urna turpis auctor libero, nec tristique ex tortor et sem. Morbi id aliquet dui. Mauris mollis dapibus viverra.
</p>
<p>
Pellentesque nulla mi, commodo hendrerit euismod in, maximus quis elit. Morbi tristique arcu eget eros ullamcorper, at euismod nibh vehicula. Proin id semper lectus. Fusce facilisis ipsum vitae dolor tincidunt euismod.
</p>
<h2 data-test="airport-header">{{model.name}}</h2>
<div class="detail">
<div class="detail-label">ICAO</div>
<div class="detail-value" data-test="airport-icao">{{model.icao}}</div>
</div>
<div class="detail">
<div class="detail-label">IATA</div>
<div class="detail-value" data-test="airport-iata">{{model.iata}}</div>
</div>
<h3>Departing Flights</h3>
<div data-test="departing-flights">
{{airport-flights model 'departing'}}
</div>
<h3>Arriving Flights</h3>
<div data-test="arriving-flights">
{{airport-flights model 'arriving'}}
</div>
<h2>Airports</h2>
<ul class="list-group">
{{#each model as |airport|}}
<li class="list-group-item">
{{#link-to 'airports.airport' airport}}
{{airport-item airport}}
{{/link-to}}
</li>
{{/each}}
</ul>
<div>
<h1 data-test="app-name">{{this.appName}}</h1>
<ul class="nav nav-tabs">
<li>{{#link-to 'index'}}Home{{/link-to}}</li>
<li>{{#link-to 'airports' data-test="link-airports"}}Airports{{/link-to}}</li>
<li>{{#link-to 'about'}}About{{/link-to}}</li>
</ul>
</div>
<div class="margin-top">
{{outlet}}
</div>
{{#if (has-block)}}
{{yield flights}}
{{else}}
{{#if isLoading}}
Loading...
{{else}}
{{#if loadingError}}
<div class="text-danger">Error loading</div>
{{else}}
{{#if flights.length}}
<ul class="list-group">
{{#each flights as |flight|}}
<li class="list-group-item">
{{flight-item flight}}
</li>
{{/each}}
</ul>
{{else}}
<div class="text-muted">None</div>
{{/if}}
{{/if}}
{{/if}}
{{/if}}
<span data-test="airport-img"><img src="{{airport.img_url}}" width="25" height="25"></span>
<span data-test="airport-name">{{airport.name}}</span> (<span data-test="airport-iata">{{airport.iata}}</span>)
<span data-test="flight-number">{{flight.number}}</span>: <span data-test="flight-origin">{{flight.origin.iata}}</span> to <span data-test="flight-destination">{{flight.destination.iata}}</span>
<h2>Flights Listing</h2>
<ul class="list-group">
{{#each model as |flight|}}
<li class="list-group-item">
{{!-- todo: fill item list item --}}
</li>
{{/each}}
</ul>
<h2>Home</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla interdum quis neque quis tristique. Sed dictum sit amet mauris in sollicitudin. Maecenas viverra sapien id magna lacinia venenatis.</p>
<p class="text-center">
<img src="https://via.placeholder.com/350x65.png?">
</p>
<p>Nullam pharetra orci eget odio ultricies, quis tincidunt arcu pharetra. Fusce rutrum velit ut nisl tincidunt interdum. Fusce vitae ultricies eros. Mauris volutpat felis sed lacinia blandit. Aliquam erat volutpat. Donec vulputate lobortis orci. Fusce id eros vitae sem ultricies pretium in in libero. </p>
<p>Morbi placerat tortor ultrices suscipit convallis. Proin sit amet pharetra orci. Nunc dignissim elit ante, vitae egestas sem sagittis ut. Etiam aliquam felis vitae turpis hendrerit efficitur. Morbi blandit massa tempor aliquet tincidunt. Suspendisse facilisis mollis odio in lobortis.</p>
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';
module('Acceptance | airports/:airport_id', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting /airports/:airport_id', async function(assert) {
this.server.create('airport', { id: '123' });
await visit('/airports/123');
assert.equal(currentURL(), '/airports/123');
});
test('shows the airport name in h2', async function(assert) {
this.server.create('airport', { id: 'ID', name: 'Airport International' });
await visit('/airports/ID');
assert.equal(document.querySelector('h2[data-test=airport-header]').textContent, 'Airport International');
});
test('shows the airport icao', async function(assert) {
this.server.create('airport', { id: 'ID', icao: 'KABC' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=airport-icao]').textContent, 'KABC');
});
test('shows the airport iata', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=airport-iata]').textContent, 'ABC');
});
test('lists departing flights', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
this.server.create('airport', { id: '1' });
this.server.create('airport', { id : '2' });
this.server.create('flight', { id: '1', number: '123', originId: 'ID', destinationId: '1' });
this.server.create('flight', { id: '2', number: '234', originId: 'ID', destinationId: '2' });
this.server.create('flight', { id: '3', number: '456', originId: 'ID', destinationId: '2' });
await visit('/airports/ID');
assert.equal(document.querySelectorAll('[data-test=departing-flights] [data-test=flight-item]').length, 3);
});
test('departing flight format is correct', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
this.server.create('airport', { id : '1', iata: 'XYZ' });
this.server.create('flight', { id: '1', number: '123', originId: 'ID', destinationId: '1' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=departing-flights] [data-test=flight-item]').textContent, '123: ABC to XYZ');
});
test('departing flight is None if empty', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=departing-flights]').textContent.trim(), 'None');
});
test('lists arriving flights', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
this.server.create('airport', { id: '1' });
this.server.create('airport', { id : '2' });
this.server.create('flight', { id: '1', number: '123', originId: '1', destinationId: 'ID' });
this.server.create('flight', { id: '2', number: '234', originId: '2', destinationId: 'ID' });
this.server.create('flight', { id: '3', number: '456', originId: '2', destinationId: 'ID' });
await visit('/airports/ID');
assert.equal(document.querySelectorAll('[data-test=arriving-flights] [data-test=flight-item]').length, 3);
});
test('arriving flight format is correct', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
this.server.create('airport', { id : '1', iata: 'XYZ' });
this.server.create('flight', { id: '1', number: '123', originId: '1', destinationId: 'ID' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=arriving-flights] [data-test=flight-item]').textContent, '123: XYZ to ABC');
});
test('arriving flight is None if empty', async function(assert) {
this.server.create('airport', { id: 'ID', iata: 'ABC' });
await visit('/airports/ID');
assert.equal(document.querySelector('[data-test=arriving-flights]').textContent.trim(), 'None');
});
});
import { module, test } from 'qunit';
import { visit, click, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
module('Acceptance | airports', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting /airports', async function(assert) {
await visit('/airports');
assert.equal(currentURL(), '/airports');
});
test('lists airports', async function(assert) {
this.server.create('airport', { name: 'ABC International' });
this.server.create('airport', { name: 'XYZ Airport' });
await visit('/airports');
assert.equal(document.querySelectorAll('[data-test=airport-item]').length, 2);
});
test('airport item includes image', async function(assert) {
this.server.create('airport', { name: 'ABC International' });
await visit('/airports');
assert.equal(document.querySelectorAll('[data-test=airport-item] img').length, 1);
});
test('airport item has correct format', async function(assert) {
this.server.create('airport', { name: 'ABC International', iata: 'ABC', icao: 'ABCD' });
await visit('/airports');
assert.equal(document.querySelector('[data-test=airport-item]').textContent.trim(), 'ABC International (ABC)');
});
test('clicking airport navigates to airport detail', async function(assert) {
this.server.create('airport', { id: 'ABC', name: 'ABC International' });
await visit('/airports');
await click('[data-test=airport-item]');
assert.equal(currentURL(), '/airports/ABC');
});
});
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';
module('Acceptance | flights/:flight_id', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting /flights/:flight_id', async function(assert) {
await visit('/flights/123');
assert.equal(currentURL(), '/flights/123');
});
// @todo: Finish the tests
});
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';
module('Acceptance | flights', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting /flights', async function(assert) {
await visit('/flights');
assert.equal(currentURL(), '/flights');
});
test('lists flights', async function(assert) {
this.server.create('airport', { id: '1', name: 'ABC International', iata: 'ABC' });
this.server.create('airport', { id : '2', name: 'XYZ Airport', iata: 'XYZ' });
this.server.create('airport', { id : '3', name: 'EFG Airport', iata: 'EFG' });
this.server.create('flight', { id: '1', number: '123', originId: '1', destinationId: '2' });
this.server.create('flight', { id: '2', number: '234', originId: '1', destinationId: '3' });
await visit('/airports');
assert.equal(document.querySelectorAll('[data-test=flight-item]').length, 2);
});
test('flight item has correct format', async function(assert) {
this.server.create('airport', { id: '1', name: 'ABC International', iata: 'ABC' });
this.server.create('airport', { id : '2', name: 'XYZ Airport', iata: 'XYZ' });
this.server.create('flight', { id: '1', number: '123', originId: '1', destinationId: '2' });
await visit('/airports');
assert.equal(document.querySelector('[data-test=flight-item]').textContent.trim(), '123: ABC to XYZ');
});
// @todo: Finish the tests
});
import { module, test } from 'qunit';
import { visit, click, currentURL } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
module('Acceptance | index', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('visiting /', async function(assert) {
await visit('/');
assert.equal(currentURL(), '/');
});
test('has app name', async function(assert) {
await visit('/');
assert.equal(document.querySelector('[data-test=app-name').textContent, 'Flight Tracker', 'app name is correct');
});
test('navigates to /airports', async function(assert) {
await visit('/');
await click('[data-test=link-airports]');
assert.equal(currentURL(), '/airports');
});
test('navigates to /flights', async function(assert) {
await visit('/');
await click('[data-test=link-flights]');
assert.equal(currentURL(), '/flights');
});
});
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
import { setupMirage } from 'ember-cli-mirage/test-support';
module('Integration | Component | airport-flights', function(hooks) {
setupRenderingTest(hooks);
setupMirage(hooks);
test('renders flights to block', async function(assert) {
const airport = this.server.create('airport', {
id: 'TEST1',
name: 'Airport Name'
});
this.server.create('flight', { originId: 'TEST1', number: 'VAL1' });
this.server.create('flight', { originId: 'TEST1', number: 'VAL2' });
this.server.create('flight');
this.set('airportValue', airport);
await render(hbs`
{{#airport-flights airportValue 'departing' as |flights|}}
{{#each flights as |flight|}}
<div data-test="flight">{{flight.number}}</div>
{{/each}}
{{/airport-flights}}
`);
assert.equal(this.element.querySelectorAll('[data-test=flight]').length, 2, 'has correct number');
assert.equal(this.element.querySelectorAll('[data-test=flight]').item(0).textContent.trim(), 'VAL1');
assert.equal(this.element.querySelectorAll('[data-test=flight]').item(1).textContent.trim(), 'VAL2');
});
});
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | airport-item', function(hooks) {
setupRenderingTest(hooks);
test('renders airport name', async function(assert) {
const airport = { name: 'Airport Name' };
this.set('airportValue', airport);
await render(hbs`{{airport-item airportValue}}`);
assert.equal(this.element.querySelector('[data-test=airport-name]').textContent.trim(), 'Airport Name', 'airport name renders');
});
test('renders airport IATA', async function(assert) {
const airport = { iata: 'ABC' };
this.set('airportValue', airport);
await render(hbs`{{airport-item airportValue}}`);
assert.equal(this.element.querySelector('[data-test=airport-iata]').textContent.trim(), 'ABC', 'airport name renders');
});
test('renders formatted airport', async function(assert) {
const airport = { name: 'Airport Name', iata: 'ABC' };
this.set('airportValue', airport);
await render(hbs`{{airport-item airportValue}}`);
assert.equal(this.element.textContent.trim(), 'Airport Name (ABC)');
});
});
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | flight-item', function(hooks) {
setupRenderingTest(hooks);
test('renders formatted flight', async function(assert) {
const flight = {
number: '123',
origin: { iata: 'ABC' },
destination: { iata: 'XYZ' }
};
this.set('flightValue', flight);
await render(hbs`{{flight-item flightValue}}`);
assert.equal(this.element.textContent.trim(), '123: ABC to XYZ');
});
test('renders as native', async function(assert) {
const flight = {
number: '123',
origin: { iata: 'ABC' },
destination: { iata: 'XYZ' }
};
this.set('flightValue', flight);
await render(hbs`<FlightItem @flight={{this.flightValue}} />`);
assert.equal(this.element.textContent.trim(), '123: ABC to XYZ');
});
});
import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { assign } from '@ember/polyfills';
import { start } from 'ember-qunit';
let attributes = {
rootElement: '#test-root',
autoboot: false
};
attributes = assign(attributes, config.APP);
let application = Application.create(attributes);
setApplication(application);
start();
{
"version": "0.17.1",
"ENV": {
"ember-cli-mirage": {
"enabled": true
},
"environment": "test"
},
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": true
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"bootstrap": "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css",
"ember": "3.8.3",
"ember-template-compiler": "3.8.3",
"ember-testing": "3.8.3"
},
"addons": {
"ember-data": "3.8.1",
"ember-cli-mirage": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment