Sets user's gravatar URL in the API client (#629)

This commit is contained in:
Mike Stone 2016-12-15 10:00:44 -05:00 committed by GitHub
parent 0b70f58614
commit 1fc7be0715
9 changed files with 90 additions and 64 deletions

View file

@ -1,8 +1,21 @@
import { kebabCase, pick } from 'lodash';
import md5 from 'js-md5';
const ORG_INFO_ATTRS = ['org_name', 'org_logo_url'];
const ADMIN_ATTRS = ['email', 'name', 'password', 'password_confirmation', 'username'];
export const addGravatarUrlToResource = (resource) => {
const { email } = resource;
const emailHash = md5(email.toLowerCase());
const gravatarURL = `https://www.gravatar.com/avatar/${emailHash}?d=blank`;
return {
...resource,
gravatarURL,
};
};
const labelSlug = (label) => {
const { display_text: displayText } = label;
@ -29,4 +42,4 @@ const setupData = (formData) => {
};
};
export default { labelSlug, setupData };
export default { addGravatarUrlToResource, labelSlug, setupData };

View file

@ -44,7 +44,13 @@ class Kolide extends Base {
const { INVITES } = endpoints;
return this.authenticatedGet(this.endpoint(INVITES))
.then((response) => { return response.invites; });
.then((response) => {
const { invites } = response;
return invites.map((invite) => {
return helpers.addGravatarUrlToResource(invite);
});
});
}
getHosts = () => {
@ -162,21 +168,40 @@ class Kolide extends Base {
const { USERS } = endpoints;
return this.authenticatedGet(this.endpoint(USERS))
.then((response) => { return response.users; });
.then((response) => {
const { users } = response;
return users.map((user) => {
return helpers.addGravatarUrlToResource(user);
});
});
}
inviteUser = (formData) => {
const { INVITES } = endpoints;
return this.authenticatedPost(this.endpoint(INVITES), JSON.stringify(formData))
.then((response) => { return response.invite; });
.then((response) => {
const { invite } = response;
return helpers.addGravatarUrlToResource(invite);
});
}
loginUser ({ username, password }) {
const { LOGIN } = endpoints;
const loginEndpoint = this.baseURL + LOGIN;
return Base.post(loginEndpoint, JSON.stringify({ username, password }));
return Base.post(loginEndpoint, JSON.stringify({ username, password }))
.then((response) => {
const { user } = response;
const userWithGravatarUrl = helpers.addGravatarUrlToResource(user);
return {
...response,
user: userWithGravatarUrl,
};
});
}
logout () {
@ -190,7 +215,12 @@ class Kolide extends Base {
const { ME } = endpoints;
const meEndpoint = this.baseURL + ME;
return this.authenticatedGet(meEndpoint);
return this.authenticatedGet(meEndpoint)
.then((response) => {
const { user } = response;
return helpers.addGravatarUrlToResource(user);
});
}
resetPassword (formData) {
@ -227,7 +257,11 @@ class Kolide extends Base {
const updateUserEndpoint = `${this.baseURL}${USERS}/${user.id}`;
return this.authenticatedPatch(updateUserEndpoint, JSON.stringify(formData))
.then((response) => { return response.user; });
.then((response) => {
const { user: updatedUser } = response;
return helpers.addGravatarUrlToResource(updatedUser);
});
}
}

View file

@ -221,7 +221,7 @@ describe('Kolide - API client', () => {
username: 'admin',
password: 'secret',
})
.then((user) => {
.then(({ user }) => {
expect(user).toEqual(validUser);
expect(request.isDone()).toEqual(true);
done();

View file

@ -1,5 +1,3 @@
import md5 from 'js-md5';
import { configSuccess } from 'redux/nodes/app/actions';
import Kolide from 'kolide';
import userActions from 'redux/nodes/entities/users/actions';
@ -39,12 +37,7 @@ export const fetchCurrentUser = () => {
return (dispatch) => {
dispatch(loginRequest);
return Kolide.me()
.then((response) => {
const { user } = response;
const { email } = user;
const emailHash = md5(email.toLowerCase());
user.gravatarURL = `https://www.gravatar.com/avatar/${emailHash}?d=blank`;
.then((user) => {
return dispatch(loginSuccess({ user }));
})
.catch((response) => {
@ -59,15 +52,12 @@ export const loginUser = (formData) => {
return (dispatch) => {
return new Promise((resolve, reject) => {
dispatch(loginRequest);
return Kolide.loginUser(formData)
.then((response) => {
const { user } = response;
const { email } = user;
const emailHash = md5(email.toLowerCase());
dispatch(loginSuccess(response));
user.gravatarURL = `https://www.gravatar.com/avatar/${emailHash}?d=blank`;
dispatch(loginSuccess({ ...response, user }));
return resolve(user);
return resolve(response.user);
})
.catch((response) => {
const { error } = response;
@ -111,9 +101,9 @@ export const updateUser = (targetUser, formData) => {
return new Promise((resolve, reject) => {
dispatch(updateUserRequest);
return dispatch(userActions.update(targetUser, formData))
.then((response) => {
const { user } = response;
.then((user) => {
dispatch(updateUserSuccess(user));
return resolve(user);
})
.catch((response) => {

View file

@ -1,5 +1,6 @@
import configureStore from 'redux-mock-store';
import expect from 'expect';
import { find } from 'lodash';
import thunk from 'redux-thunk';
import authMiddleware from '../../middlewares/auth';
@ -48,11 +49,15 @@ describe('Auth - reducer', () => {
it('calls the api login endpoint', (done) => {
const loginRequestMock = validLoginRequest();
const expectedBearerToken = 'expected-bearer-token';
const loginRequestMock = validLoginRequest(expectedBearerToken);
store.dispatch(loginUser(formData))
.then((user) => {
.then(() => {
const loginSuccessAction = find(store.getActions(), { type: 'LOGIN_SUCCESS' });
expect(loginSuccessAction.payload.token).toEqual(expectedBearerToken);
expect(loginRequestMock.isDone()).toEqual(true);
expect(local.getItem('auth_token')).toEqual(user.token);
done();
})
.catch(done);
@ -70,22 +75,24 @@ describe('Auth - reducer', () => {
});
it('sets the users auth token in local storage', (done) => {
validLoginRequest();
const expectedBearerToken = 'expected-bearer-token';
validLoginRequest(expectedBearerToken);
store.dispatch(loginUser(formData))
.then((user) => {
expect(local.getItem('auth_token')).toEqual(user.token);
.then(() => {
expect(local.getItem('auth_token')).toEqual(expectedBearerToken);
done();
})
.catch(done);
});
it('sets the api client bearerToken', (done) => {
validLoginRequest();
const expectedBearerToken = 'expected-bearer-token';
validLoginRequest(expectedBearerToken);
store.dispatch(loginUser(formData))
.then((user) => {
expect(kolide.bearerToken).toEqual(user.token);
.then(() => {
expect(kolide.bearerToken).toEqual(expectedBearerToken);
done();
})
.catch(done);

View file

@ -1,22 +1,9 @@
import md5 from 'js-md5';
import { pickBy } from 'lodash';
export const addGravatarUrlToResource = (resource) => {
const { email } = resource;
const emailHash = md5(email.toLowerCase());
const gravatarURL = `https://www.gravatar.com/avatar/${emailHash}?d=blank`;
return {
...resource,
gravatarURL,
};
};
export const entitiesExceptID = (entities, id) => {
return pickBy(entities, (entity, key) => {
return String(key) !== String(id);
});
};
export default { entitiesExceptID, addGravatarUrlToResource };
export default { entitiesExceptID };

View file

@ -1,7 +1,6 @@
import { addGravatarUrlToResource } from '../base/helpers';
import Kolide from '../../../../kolide';
import reduxConfig from '../base/reduxConfig';
import schemas from '../base/schemas';
import Kolide from 'kolide';
import reduxConfig from 'redux/nodes/entities/base/reduxConfig';
import schemas from 'redux/nodes/entities/base/schemas';
const { INVITES: schema } = schemas;
@ -10,6 +9,5 @@ export default reduxConfig({
destroyFunc: Kolide.revokeInvite,
entityName: 'invites',
loadAllFunc: Kolide.getInvites,
parseEntityFunc: addGravatarUrlToResource,
schema,
});

View file

@ -1,14 +1,12 @@
import { addGravatarUrlToResource } from '../base/helpers';
import Kolide from '../../../../kolide';
import reduxConfig from '../base/reduxConfig';
import schemas from '../base/schemas';
import Kolide from 'kolide';
import reduxConfig from 'redux/nodes/entities/base/reduxConfig';
import schemas from 'redux/nodes/entities/base/schemas';
const { USERS } = schemas;
export default reduxConfig({
entityName: 'users',
loadAllFunc: Kolide.getUsers,
parseEntityFunc: addGravatarUrlToResource,
schema: USERS,
updateFunc: Kolide.updateUser,
});

View file

@ -3,7 +3,6 @@ import nock from 'nock';
import helpers from 'kolide/helpers';
export const validUser = {
token: 'auth_token',
id: 1,
username: 'admin',
email: 'admin@kolide.co',
@ -11,7 +10,7 @@ export const validUser = {
admin: true,
enabled: true,
needs_password_reset: false,
gravatarURL: 'https://www.gravatar.com/avatar/7157f4758f8423b59aaee869d919f6b9',
gravatarURL: 'https://www.gravatar.com/avatar/7157f4758f8423b59aaee869d919f6b9?d=blank',
};
export const validCreateLabelRequest = (bearerToken, labelParams) => {
@ -85,7 +84,7 @@ export const validInviteUserRequest = (bearerToken, formData) => {
},
})
.post('/api/v1/kolide/invites', JSON.stringify(formData))
.reply(200, formData);
.reply(200, { invite: formData });
};
export const validGetHostsRequest = (bearerToken) => {
@ -149,10 +148,10 @@ export const validGetUsersRequest = (bearerToken) => {
.reply(200, { users: [validUser] });
};
export const validLoginRequest = () => {
export const validLoginRequest = (bearerToken = 'abc123') => {
return nock('http://localhost:8080')
.post('/api/v1/kolide/login')
.reply(200, validUser);
.reply(200, { user: validUser, token: bearerToken });
};
export const validMeRequest = (bearerToken) => {
@ -162,7 +161,7 @@ export const validMeRequest = (bearerToken) => {
},
})
.get('/api/v1/kolide/me')
.reply(200, validUser);
.reply(200, { user: validUser });
};
export const validLogoutRequest = (bearerToken) => {
@ -236,7 +235,7 @@ export const validUpdateQueryRequest = (bearerToken, query, formData) => {
export const validUpdateUserRequest = (user, formData) => {
return nock('http://localhost:8080')
.patch(`/api/v1/kolide/users/${user.id}`, JSON.stringify(formData))
.reply(200, validUser);
.reply(200, { user: validUser });
};