diff --git a/app/adapters/task.js b/app/adapters/task.js index 59477aa2f..c0af77107 100644 --- a/app/adapters/task.js +++ b/app/adapters/task.js @@ -4,8 +4,7 @@ import Ember from 'ember'; const { String: { underscore }, get, - isEmpty, - isPresent + isBlank } = Ember; export default ApplicationAdapter.extend({ @@ -17,21 +16,21 @@ export default ApplicationAdapter.extend({ // to preserve a clean url with just `&page=X` we only // transform the page number to the proper JSON api format here, in the // adapter, instead of back in the route - if (isPresent(query.page)) { + if (isBlank(query.page)) { + delete query.page; + } else { query.page = { page: query.page }; } // we don't want to send the status parameter to the API if it does not // have a proper value - if (isEmpty(query.status)) { + if (isBlank(query.status)) { delete query.status; } // projectId is part of the url in `projects/:projectId/tasks`, so we // do not want to see it in the query as well - if (query.projectId) { - delete query.projectId; - } + delete query.projectId; // any remaining fields are in camelCase, so we want to serialize them into // underscore_format diff --git a/app/components/power-select/before-options.js b/app/components/power-select/before-options.js index 9c0727388..9a05b5f0a 100644 --- a/app/components/power-select/before-options.js +++ b/app/components/power-select/before-options.js @@ -1,9 +1,12 @@ import BeforeOptionsComponent from 'ember-power-select/components/power-select/before-options'; +import Ember from 'ember'; + +const { get } = Ember; export default BeforeOptionsComponent.extend({ actions: { close() { - this.get('selectRemoteController').actions.close(); + get(this, 'selectRemoteController').actions.close(); } } }); diff --git a/tests/integration/components/select-inline-dropdown/list-item-test.js b/tests/integration/components/select-inline-dropdown/list-item-test.js index caff72256..2806bcad9 100644 --- a/tests/integration/components/select-inline-dropdown/list-item-test.js +++ b/tests/integration/components/select-inline-dropdown/list-item-test.js @@ -1,12 +1,51 @@ import { moduleForComponent, test } from 'ember-qunit'; import hbs from 'htmlbars-inline-precompile'; +import pageComponent from 'code-corps-ember/tests/pages/components/select-inline-dropdown/list-item'; +import PageObject from 'ember-cli-page-object'; +import Ember from 'ember'; -moduleForComponent('select-inline-dropdown/list-item', 'Integration | Component | select inline dropdown/list item', { - integration: true -}); +const { setProperties } = Ember; + +let page = PageObject.create(pageComponent); + +moduleForComponent( + 'select-inline-dropdown/list-item', + 'Integration | Component | select inline dropdown/list item', { + integration: true, + beforeEach() { + page.setContext(this); + }, + afterEach() { + page.removeContext(); + } + } +); + +function renderPage() { + page.render(hbs` + {{select-inline-dropdown/list-item + iconUrl=iconUrl + primaryText=primaryText + secondaryText=secondaryText + lastSearchedText=lastSearchedText + }}`); +} + +test('it renders correctly', function(assert) { + assert.expect(5); + + let iconUrl = 'testurl'; + let primaryText = 'Test'; + let secondaryText = 'testuser'; + let lastSearchedText = 'est'; + + setProperties(this, { iconUrl, primaryText, secondaryText, lastSearchedText }); -test('it renders', function(assert) { - this.render(hbs`{{select-inline-dropdown/list-item}}`); + renderPage(); - assert.equal(this.$().text().trim(), ''); + assert.equal(page.icon.url, iconUrl, 'Icon is rendered.'); + assert.equal(page.primary.text, primaryText, 'Primary text is rendered.'); + assert.equal(page.primary.highlighted.text, lastSearchedText, 'Filtered text is rendered on primary.'); + assert.equal(page.secondary.text, secondaryText, 'Secondary text is rendered.'); + assert.equal(page.secondary.highlighted.text, lastSearchedText, 'Filtered text is rendered on secondary.'); }); diff --git a/tests/pages/components/select-inline-dropdown/list-item.js b/tests/pages/components/select-inline-dropdown/list-item.js new file mode 100644 index 000000000..fb28f51a3 --- /dev/null +++ b/tests/pages/components/select-inline-dropdown/list-item.js @@ -0,0 +1,22 @@ +import { attribute } from 'ember-cli-page-object'; + +export default { + icon: { + scope: '.select-inline-dropdown__list-item__icon', + url: attribute('src', 'img') + }, + + primary: { + scope: '.select-inline-dropdown__list-item__content__primary', + highlighted: { + scope: 'strong' + } + }, + + secondary: { + scope: '.select-inline-dropdown__list-item__content__secondary', + highlighted: { + scope: 'strong' + } + } +}; diff --git a/tests/unit/adapters/task-test.js b/tests/unit/adapters/task-test.js new file mode 100644 index 000000000..73d0547e6 --- /dev/null +++ b/tests/unit/adapters/task-test.js @@ -0,0 +1,128 @@ +import { moduleFor, test } from 'ember-qunit'; +import Ember from 'ember'; + +const { set } = Ember; + +moduleFor('adapter:task', 'Unit | Adapter | task'); + +test('"sortQueryParams" passes through (and underscores) any keys that arent special', function(assert) { + assert.expect(2); + + let adapter = this.subject(); + + assert.deepEqual( + adapter.sortQueryParams({ foo: 'bar' }), + { foo: 'bar' }, + 'Leaves single-word keys untouched.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ camelFoo: 'bar' }), + { camel_foo: 'bar' }, + 'Underscores camelCase keys.' + ); +}); + +test('"sortQueryParams" moves page param into query sub-object if present', function(assert) { + assert.expect(5); + + let adapter = this.subject(); + + assert.deepEqual( + adapter.sortQueryParams({ page: 'foo' }), + { page: { page: 'foo' } }, + 'When there is a page key, it needs to be nested.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ page: undefined }), + { }, + 'An undefined value is discarded.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ page: null }), + { }, + 'A null value is discarded.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ page: null }), + { }, + 'An empty string value is discarded.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ page: '' }), + { }, + 'An empty string value is discarded.' + ); +}); + +test('"sortQueryParams" discards "projectId"', function(assert) { + assert.expect(6); + + let adapter = this.subject(); + + assert.deepEqual( + adapter.sortQueryParams({ projectId: 'bar' }), + { }, + 'Discards "projectId" when it has a value.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ projectId: '' }), + { }, + 'Discards "projectId" when empty string.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ projectId: null }), + { }, + 'Discards "projectId" when null.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ projectId: undefined }), + { }, + 'Discards "projectId" undefined.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ projectId: [] }), + { }, + 'Discards "projectId" when blank array.' + ); + + assert.deepEqual( + adapter.sortQueryParams({ }), + { }, + 'Works on blank object.' + ); +}); + +test('"urlForQuery" makes "projectId" part of the path', function(assert) { + assert.expect(1); + + let adapter = this.subject(); + set(adapter, 'host', 'test'); + + assert.equal( + adapter.urlForQuery({ projectId: 2 }), + 'test/projects/2/tasks', + '"projectId" is correctly made part of the path.' + ); +}); + +test('"urlForQueryRecord" makes "projectId" and "number" part of the path', function(assert) { + assert.expect(1); + + let adapter = this.subject(); + set(adapter, 'host', 'test'); + + assert.equal( + adapter.urlForQueryRecord({ projectId: 2, number: 5 }), + 'test/projects/2/tasks/5', + '"projectId" and "number" are correctly made part of the path.' + ); +}); diff --git a/tests/unit/components/power-select/before-options-test.js b/tests/unit/components/power-select/before-options-test.js new file mode 100644 index 000000000..284a84475 --- /dev/null +++ b/tests/unit/components/power-select/before-options-test.js @@ -0,0 +1,28 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import Ember from 'ember'; + +const { Controller, set } = Ember; + +moduleForComponent( + 'power-select/before-options', + 'Unit | Component | power select before options', + { + unit: true + } +); + +test('close action calls "close" action on assigned "selectRemoteController"', function(assert) { + assert.expect(1); + + let stubController = Controller.extend({ + actions: { + close() { + assert.ok(true, 'Action was called'); + } + } + }); + + let component = this.subject(); + set(component, 'selectRemoteController', stubController.create()); + component.send('close'); +});