Merge pull request #842 from theseyi/first-fridays

update configuration for mirage. fixes test for authenticate request handler. updates tests. adds assertion got authenticate action
This commit is contained in:
Seyi Adebajo 2017-11-06 09:46:39 -08:00 committed by GitHub
commit c80d843777
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 148 additions and 89 deletions

View File

@ -1,6 +1,6 @@
import Component from '@ember/component';
import { inject } from '@ember/service';
import { getProperties, computed } from '@ember/object';
import { getProperties, computed, set } from '@ember/object';
import ComputedProperty, { oneWay } from '@ember/object/computed';
import { baseCommentEditorOptions } from 'wherehows-web/constants';
import Notifications, { NotificationEvent } from 'wherehows-web/services/notifications';
@ -102,8 +102,12 @@ export default class DatasetDeprecation extends Component {
const { onUpdateDeprecation } = this;
if (onUpdateDeprecation) {
const noteValue = deprecatedAlias ? deprecationNoteAlias : '';
try {
await onUpdateDeprecation(deprecatedAlias, deprecationNoteAlias);
await onUpdateDeprecation(deprecatedAlias, noteValue);
set(this, 'deprecationNoteAlias', noteValue);
notify(NotificationEvent.success, {
content: 'Successfully updated deprecation status'
});

View File

@ -1,18 +0,0 @@
import Ember from 'ember';
const {
Component
} = Ember;
export default Component.extend({
classNames: ['nacho-login-form'],
actions: {
/**
* Handle the login for submission
*/
userDidSubmit() {
// Trigger action on parent controller
this.get('onSubmit')();
}
}
})

View File

@ -0,0 +1,35 @@
import Component from '@ember/component';
import { get } from '@ember/object';
import { assert } from '@ember/debug';
export default class LoginForm extends Component {
classNames = ['nacho-login-form'];
/**
* External action to be invoked on form submission
* @type {Function}
* @memberof LoginForm
*/
onSubmit: Function;
constructor() {
super(...arguments);
// Ensure that the onSubmit action passed in on instantiation is a callable action
const typeOfOnSubmit = typeof this.onSubmit;
assert(
`Expected action onSubmit to be an function (Ember action), got ${typeOfOnSubmit}`,
typeOfOnSubmit === 'function'
);
}
actions = {
/**
* Handle the login for submission
*/
userDidSubmit(this: LoginForm) {
// Trigger action on parent controller
get(this, 'onSubmit')();
}
};
}

View File

@ -1,12 +1,6 @@
import Ember from 'ember';
const {
Controller,
computed,
get,
setProperties,
inject: { service }
} = Ember;
const { Controller, computed, get, setProperties, inject: { service } } = Ember;
export default Controller.extend({
session: service(),
@ -22,15 +16,11 @@ export default Controller.extend({
* Using the session service, authenticate using the custom ldap authenticator
*/
authenticateUser() {
const { username, password } = this.getProperties([
'username',
'password'
]);
const { username, password } = this.getProperties(['username', 'password']);
get(this, 'session')
.authenticate('authenticator:custom-ldap', username, password)
.catch(({ responseText = 'Bad Credentials' }) =>
setProperties(this, { errorMessage: responseText }));
.catch(({ responseText = 'Bad Credentials' }) => setProperties(this, { errorMessage: responseText }));
}
}
});

View File

@ -1,32 +1,20 @@
import { faker } from 'ember-cli-mirage';
import { IFunctionRouteHandler, IMirageServer } from 'wherehows-web/typings/ember-cli-mirage';
import { ApiStatus } from 'wherehows-web/utils/api/shared';
import { getConfig } from "./helpers/config";
import { getConfig } from 'wherehows-web/mirage/helpers/config';
import { getAuth } from 'wherehows-web/mirage/helpers/authenticate';
export default function(this: IMirageServer) {
this.get('/config', getConfig);
this.post('/authenticate', function({}, request: any) {
const username = JSON.parse(request.requestBody).username;
const password = JSON.parse(request.requestBody).password;
if (password === null || password === undefined) {
return 'Missing or invalid [credentials]';
} else if (password === 'invalidPassword') {
return 'Invalid Password';
}
return {
status: ApiStatus.OK,
data: {username: username, uuid: faker.random.uuid()}
};
});
this.post('/authenticate', getAuth);
this.namespace = '/api/v1';
interface IComplianceSuggestionsObject {
complianceSuggestions: any;
}
this.get('/datasets/:id/compliance/suggestions', function(
this: IFunctionRouteHandler,
{ complianceSuggestions }: IComplianceSuggestionsObject
@ -44,9 +32,8 @@ export default function(this: IMirageServer) {
interface IFlowsObject {
flows: any;
}
this.get('/flows', function(
this: IFunctionRouteHandler,
{ flows }: IFlowsObject, request: any) {
this.get('/flows', function(this: IFunctionRouteHandler, { flows }: IFlowsObject, request: any) {
const { page } = request.queryParams;
const flowsArr = this.serialize(flows.all());
const count = faker.random.number({ min: 20000, max: 40000 });
@ -59,7 +46,7 @@ export default function(this: IMirageServer) {
flows: flowsArr,
itemsPerPage: itemsPerPage,
page: page,
totalPages: Math.round(count / itemsPerPage),
totalPages: Math.round(count / itemsPerPage)
}
};
});
@ -81,7 +68,10 @@ export default function(this: IMirageServer) {
}
this.get('/datasets', function(
this: IFunctionRouteHandler,
{ datasets }: IDatasetsObject, { owners }: IOwnersObject, request: any) {
{ datasets }: IDatasetsObject,
{ owners }: IOwnersObject,
request: any
) {
const { page } = request.queryParams;
const datasetsArr = this.serialize(datasets.all());
const ownersArr = this.serialize(owners.all());
@ -99,7 +89,7 @@ export default function(this: IMirageServer) {
page: page,
itemsPerPage: itemsPerPage,
totalPages: Math.round(count / itemsPerPage),
datasets: newDatasetsArr,
datasets: newDatasetsArr
}
};
});
@ -141,8 +131,8 @@ export default function(this: IMirageServer) {
email: testUser + '@linkedin.com',
name: testUser,
userSetting: {
"detailDefaultView": null,
"defaultWatch":null
detailDefaultView: null,
defaultWatch: null
}
},
status: ApiStatus.OK
@ -151,6 +141,4 @@ export default function(this: IMirageServer) {
this.passthrough();
}
export function testConfig(this: IMirageServer) {
this.get('/config', getConfig);
}
export function testConfig(this: IMirageServer) {}

View File

@ -0,0 +1,33 @@
import { ApiStatus } from 'wherehows-web/utils/api/shared';
import { Response, faker } from 'ember-cli-mirage';
type StringOrNullOrUndefined = string | null | void;
const textContentHeader = { 'Content-Type': 'text/plain; charset=utf-8' };
/**
* Returns a config object for the config endpoint
* @param {object} _schema the auth table / factory object
* @param {requestBody} property on the request object passed in to mirage function handlers
* @return {{status: ApiStatus, data: object}}
*/
const getAuth = (_schema: {}, { requestBody }: { requestBody: string }) => {
const { username, password } = <{ username: StringOrNullOrUndefined; password: StringOrNullOrUndefined }>JSON.parse(
requestBody
);
if (!password) {
return new Response(400, textContentHeader, 'Missing or invalid [credentials]');
}
if (password === 'invalidPassword') {
return new Response(401, textContentHeader, 'Invalid Password');
}
return {
status: ApiStatus.OK,
data: { username, uuid: faker.random.uuid() }
};
};
export { getAuth };

View File

@ -0,0 +1,3 @@
import { Model } from 'ember-cli-mirage';
export default Model.extend({});

View File

@ -1,14 +1,8 @@
export default function(server) {
const fixtures = [
'dataset-nodes',
'metric-metrics',
'user-entities'
];
const fixtures = ['dataset-nodes', 'metric-metrics', 'user-entities'];
server.loadFixtures(...fixtures);
server.createList('complianceSuggestion', 5);
server.createList('owner', 6);
server.createList('dataset', 10);
server.createList('flow', 10);
}

View File

@ -50,12 +50,12 @@
"ember-concurrency": "^0.8.10",
"ember-export-application-global": "^2.0.0",
"ember-fetch": "^3.4.3",
"ember-load-initializers": "^1.0.0",
"ember-lodash-shim": "^2.0.5",
"ember-metrics": "^0.12.1",
"ember-pikaday": "^2.2.1",
"ember-redux-shim": "^1.1.1",
"ember-redux-thunk-shim": "^1.1.2",
"ember-load-initializers": "^1.0.0",
"ember-resolver": "^4.5.0",
"ember-source": "~2.16.0",
"ember-symbol-observable": "^0.1.2",
@ -67,12 +67,12 @@
"eyeglass-restyle": "^1.1.0",
"husky": "^0.14.3",
"lint-staged": "^4.3.0",
"loader.js": "^4.6.0",
"node-sass": "^4.5.3",
"prettier": "^1.7.4",
"redux": "^3.6.0",
"redux-thunk": "^2.2.0",
"typescript": "^2.5.3",
"loader.js": "^4.6.0"
"typescript": "^2.5.3"
},
"dependencies": {
"dynamic-link": "^0.2.3",

View File

@ -1,11 +1,11 @@
import { test } from 'qunit';
import moduleForAcceptance from 'wherehows-web/tests/helpers/module-for-acceptance';
import wait from 'ember-test-helpers/wait';
import {
loginContainer,
authenticationUrl,
invalidCredentials,
testUser,
testPassword,
testPasswordInvalid
} from 'wherehows-web/tests/helpers/login/constants';
import {
@ -40,7 +40,9 @@ test('should render login form', function(assert) {
test('should display error message with empty credentials', async function(assert) {
assert.expect(2);
await fillIn(loginUserInput, testUser);
await click('button[type=submit]');
await click(loginSubmitButton);
await wait();
assert.ok(find('#login-error').text().length, 'error message element is rendered');
@ -48,31 +50,26 @@ test('should display error message with empty credentials', async function(asser
find('#login-error')
.text()
.trim(),
invalidCredentials
invalidCredentials,
'displays missing or invalid credentials message'
);
});
test('Login with an empty password', async function(assert) {
await fillIn(loginUserInput, testUser);
await click(loginSubmitButton);
assert.equal(
find('#login-error')
.text()
.trim(),
invalidCredentials
);
});
test('Login with an invalid password', async function(assert) {
test('should display invalid password message with invalid password entered', async function(assert) {
assert.expect(2);
await fillIn(loginUserInput, testUser);
await fillIn(loginPasswordInput, testPasswordInvalid);
await click(loginSubmitButton);
await wait();
assert.ok(find('#login-error').text().length, 'error message element is rendered');
assert.equal(
find('#login-error')
.text()
.trim(),
'Invalid Password'
'Invalid Password',
'displays invalid password message in error message container'
);
});

View File

@ -0,0 +1,32 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import { run } from '@ember/runloop';
moduleForComponent('login-form', 'Integration | Component | login form', {
integration: true
});
test('it renders', function(assert) {
this.set('authenticateUser', () => {});
this.render(hbs`{{login-form onSubmit=(action authenticateUser)}}`);
assert.equal(this.$('#login-username').length, 1, 'has an input for username');
assert.equal(this.$('#login-password').length, 1, 'has an input for password');
assert.equal(this.$('[type=submit]').length, 1, 'has a button for submission');
});
test('triggers the onSubmit action when clicked', function(assert) {
assert.expect(2);
let submitActionCallCount = false;
this.set('authenticateUser', function() {
submitActionCallCount = true;
});
this.render(hbs`{{login-form onSubmit=(action authenticateUser)}}`);
assert.equal(submitActionCallCount, false, 'submit action is not called on render');
run(() => document.querySelector('.nacho-login-form [type=submit]').click());
assert.equal(submitActionCallCount, true, 'submit action is called once');
});

View File

@ -20,7 +20,8 @@
"downlevelIteration": true,
"paths": {
"wherehows-web/*": ["app/*"],
"wherehows-web/tests/*": ["tests/*"]
"wherehows-web/tests/*": ["tests/*"],
"wherehows-web/mirage/*": ["mirage/*"]
}
},
"include": ["app/**/*", "tests/**/*", "mirage/**/*"],