gnarails 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +21 -90
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +50 -0
  5. data/README.md +1 -34
  6. data/bin/ci_pronto +1 -1
  7. data/gnarails.gemspec +2 -3
  8. data/gnarly.rb +44 -137
  9. data/lib/gnarails/version.rb +1 -1
  10. data/templates/.circleci/config.yml +7 -2
  11. data/templates/Procfile +1 -0
  12. data/templates/{script → bin}/brakeman +1 -1
  13. data/templates/{script → bin}/ci_pronto +1 -1
  14. data/test-app/app/views/layouts/application.html.erb +4 -2
  15. data/test-app/spec/factories/job_postings.rb +1 -1
  16. metadata +9 -64
  17. data/bin/generate-react-test-app.sh +0 -2
  18. data/templates/.ruby-version +0 -1
  19. data/templates/Dockerfile-assets +0 -24
  20. data/templates/docker-compose.yml/docker-compose-webpack.yml +0 -26
  21. data/templates/react/.babelrc +0 -18
  22. data/templates/react/.eslintrc.js +0 -45
  23. data/templates/react/controllers/home_controller.rb +0 -4
  24. data/templates/react/js/Router/Router.jsx +0 -22
  25. data/templates/react/js/Router/index.js +0 -3
  26. data/templates/react/js/api/index.js +0 -17
  27. data/templates/react/js/api/sessions.js +0 -8
  28. data/templates/react/js/app_constants/index.js +0 -6
  29. data/templates/react/js/components/App/App.jsx +0 -15
  30. data/templates/react/js/components/App/App.tests.jsx +0 -15
  31. data/templates/react/js/components/App/_styles.scss +0 -3
  32. data/templates/react/js/components/App/index.js +0 -3
  33. data/templates/react/js/index.scss +0 -2
  34. data/templates/react/js/packs/main.jsx +0 -13
  35. data/templates/react/js/redux/entity_getter.js +0 -7
  36. data/templates/react/js/redux/history.js +0 -5
  37. data/templates/react/js/redux/initial_state.js +0 -5
  38. data/templates/react/js/redux/middlewares/authentication_middleware/authentication_middleware.tests.js +0 -109
  39. data/templates/react/js/redux/middlewares/authentication_middleware/helpers.js +0 -21
  40. data/templates/react/js/redux/middlewares/authentication_middleware/helpers.tests.js +0 -84
  41. data/templates/react/js/redux/middlewares/authentication_middleware/index.js +0 -20
  42. data/templates/react/js/redux/middlewares/index.js +0 -11
  43. data/templates/react/js/redux/nodes/app/actions.js +0 -36
  44. data/templates/react/js/redux/nodes/app/config.js +0 -12
  45. data/templates/react/js/redux/nodes/app/reducer.js +0 -35
  46. data/templates/react/js/redux/nodes/app/reducer.tests.js +0 -78
  47. data/templates/react/js/redux/reducers.js +0 -11
  48. data/templates/react/js/redux/store.js +0 -14
  49. data/templates/react/js/storage.js +0 -15
  50. data/templates/react/js/styles/_variables.scss +0 -1
  51. data/templates/react/js/test/.setup.js +0 -51
  52. data/templates/react/js/test/connect_wrapper.jsx +0 -28
  53. data/templates/react/js/test/create_request_mock.js +0 -29
  54. data/templates/react/js/test/mock_store.js +0 -12
  55. data/templates/react/layout.html.erb +0 -16
  56. data/templates/react/rails_routes.rb +0 -5
  57. data/templates/react/views/home/default.html.erb +0 -1
@@ -1,3 +0,0 @@
1
- import App from './App';
2
-
3
- export default App;
@@ -1,2 +0,0 @@
1
- @import 'styles/variables';
2
- @import 'components/App/_styles.scss';
@@ -1,13 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom';
3
-
4
- import Router from 'Router';
5
- import 'index.scss';
6
-
7
- if (typeof window !== 'undefined') {
8
- global.document.addEventListener('DOMContentLoaded', () => {
9
- const mountNode = global.document.getElementById('react');
10
-
11
- ReactDOM.render(<Router />, mountNode);
12
- });
13
- };
@@ -1,7 +0,0 @@
1
- import entityGetter from 'react-entity-getter';
2
-
3
- const pathToEntities = (entityName) => {
4
- return `entities.${entityName}.data`;
5
- };
6
-
7
- export default entityGetter(pathToEntities);
@@ -1,5 +0,0 @@
1
- import createHistory from 'history/createBrowserHistory';
2
-
3
- global.window.gnarHistory = global.window.gnarHistory || createHistory();
4
-
5
- export default global.window.gnarHistory;
@@ -1,5 +0,0 @@
1
- export const app = { session: {}, loading: false };
2
-
3
- export default {
4
- app,
5
- };
@@ -1,109 +0,0 @@
1
- import expect from 'expect';
2
-
3
- import appConfig from 'redux/nodes/app/config';
4
- import mockStore from 'test/mock_store';
5
- import storage from 'storage';
6
-
7
- const authToken = 'abc123';
8
-
9
- describe('Authentication middleware', () => {
10
- beforeEach(() => storage.setItem('auth_token', authToken));
11
- afterEach(() => storage.removeItem('auth_token'));
12
-
13
- context('when the action type is for the login success action', () => {
14
- const action = {
15
- type: appConfig.actionTypes.LOGIN_SUCCESS,
16
- payload: { jwt: 'jwt' },
17
- };
18
- const store = mockStore({});
19
-
20
- it('adds the auth_token to local storage', () => {
21
- storage.removeItem('auth_token');
22
- store.dispatch(action);
23
-
24
- expect(storage.getItem('auth_token')).toEqual('jwt');
25
- });
26
- });
27
-
28
- context('when the action type is for the logout success action', () => {
29
- const action = {
30
- type: appConfig.actionTypes.LOGOUT_SUCCESS,
31
- payload: {},
32
- };
33
- const store = mockStore({});
34
-
35
- it('removes the auth_token from local storage', () => {
36
- store.dispatch(action);
37
-
38
- expect(storage.getItem('auth_token')).toEqual(undefined);
39
- });
40
- });
41
-
42
- context('when the action type is not for the logout success action', () => {
43
- const action = {
44
- type: 'FOO',
45
- payload: {},
46
- };
47
- const store = mockStore({});
48
-
49
- it('does not remove the auth_token from local storage', () => {
50
- store.dispatch(action);
51
-
52
- expect(storage.getItem('auth_token')).toEqual(authToken);
53
- });
54
- });
55
-
56
- context('when the action is for an entity that fails to load', () => {
57
- context('when the payload error is an unauthorized error', () => {
58
- const action = {
59
- type: 'entity_name_SOMETHING_FAILURE',
60
- payload: {
61
- errors: {
62
- http_status: 401,
63
- },
64
- },
65
- };
66
- const store = mockStore({});
67
-
68
- it('removes the auth_token from local storage', () => {
69
- store.dispatch(action);
70
-
71
- expect(storage.getItem('auth_token')).toEqual(undefined);
72
- });
73
- });
74
-
75
- context('when the payload error is not an unauthorized error', () => {
76
- const action = {
77
- type: 'entity_name_SOMETHING_FAILURE',
78
- payload: {
79
- errors: {},
80
- },
81
- };
82
- const store = mockStore({});
83
-
84
- it('does not remove the auth_token from local storage', () => {
85
- store.dispatch(action);
86
-
87
- expect(storage.getItem('auth_token')).toEqual(authToken);
88
- });
89
- });
90
- });
91
-
92
- context('when the action type is not a failure action', () => {
93
- const action = {
94
- type: 'entity_name_SOMETHING_SUCCESS',
95
- payload: {
96
- errors: {
97
- http_status: 401,
98
- },
99
- },
100
- };
101
- const store = mockStore({});
102
-
103
- it('does not remove the auth_token from local storage', () => {
104
- store.dispatch(action);
105
-
106
- expect(storage.getItem('auth_token')).toEqual(authToken);
107
- });
108
- });
109
- });
@@ -1,21 +0,0 @@
1
- import { endsWith, get } from 'lodash';
2
- import appConfig from 'redux/nodes/app/config';
3
-
4
- const { LOGIN_SUCCESS, LOGOUT_SUCCESS } = appConfig.actionTypes;
5
- const UNAUTHORIZED_ERROR = 401;
6
-
7
- const isFailureAction = (action) => {
8
- return endsWith(action.type, '_FAILURE');
9
- };
10
-
11
- const isLoginAction = action => action.type === LOGIN_SUCCESS;
12
- const isLogoutAction = action => action.type === LOGOUT_SUCCESS;
13
-
14
- const isUnauthorizedError = action => get(action, 'payload.errors.http_status') === UNAUTHORIZED_ERROR;
15
-
16
- export default {
17
- isFailureAction,
18
- isLoginAction,
19
- isLogoutAction,
20
- isUnauthorizedError,
21
- };
@@ -1,84 +0,0 @@
1
- import expect from 'expect';
2
-
3
- import helpers from 'redux/middlewares/authentication_middleware/helpers';
4
-
5
- describe('Authentication middleware - helpers', () => {
6
- describe('#isFailureAction', () => {
7
- it('returns true when the action type ends in _FAILURE', () => {
8
- const action = { type: 'SOMETHING_FAILURE' };
9
-
10
- expect(helpers.isFailureAction(action)).toEqual(true);
11
- });
12
-
13
- it('returns false when the action type does not end in _FAILURE', () => {
14
- const action = { type: 'SOMETHING_FAILUR' };
15
-
16
- expect(helpers.isFailureAction(action)).toEqual(false);
17
- });
18
- });
19
-
20
- describe('#isLoginAction', () => {
21
- it('returns true when the action type is the login success action type', () => {
22
- const action = { type: 'LOGIN_SUCCESS' };
23
-
24
- expect(helpers.isLoginAction(action)).toEqual(true);
25
- });
26
-
27
- it('returns false when the action type is not the login success action type', () => {
28
- const action = { type: 'LOGIN_FAILURE' };
29
-
30
- expect(helpers.isLoginAction(action)).toEqual(false);
31
- });
32
- });
33
-
34
- describe('#isLogoutAction', () => {
35
- it('returns true when the action type is the logout success action type', () => {
36
- const action = { type: 'LOGOUT_SUCCESS' };
37
-
38
- expect(helpers.isLogoutAction(action)).toEqual(true);
39
- });
40
-
41
- it('returns false when the action type is not the logout success action type', () => {
42
- const action = { type: 'LOGOUT_FAILURE' };
43
-
44
- expect(helpers.isLogoutAction(action)).toEqual(false);
45
- });
46
- });
47
-
48
- describe('#isUnauthorizedError', () => {
49
- it('returns true when the action payload has an unauthorized http status', () => {
50
- const action = {
51
- type: 'FOOBAR',
52
- payload: {
53
- errors: {
54
- http_status: 401,
55
- },
56
- },
57
- };
58
-
59
- expect(helpers.isUnauthorizedError(action)).toEqual(true);
60
- });
61
-
62
- it('returns false when the action payload does not have an unauthorized http status', () => {
63
- const action = {
64
- type: 'FOOBAR',
65
- payload: {
66
- errors: {
67
- http_status: 500,
68
- },
69
- },
70
- };
71
-
72
- expect(helpers.isUnauthorizedError(action)).toEqual(false);
73
- });
74
-
75
- it('returns false when there is no action payload http status', () => {
76
- const action = {
77
- type: 'FOOBAR',
78
- payload: {},
79
- };
80
-
81
- expect(helpers.isUnauthorizedError(action)).toEqual(false);
82
- });
83
- });
84
- });
@@ -1,20 +0,0 @@
1
- import helpers from 'redux/middlewares/authentication_middleware/helpers';
2
- import storage from 'storage';
3
-
4
- const authMiddleware = () => next => (action) => {
5
- if (helpers.isLoginAction(action)) {
6
- storage.setItem('auth_token', action.payload.jwt);
7
- }
8
-
9
- if (helpers.isLogoutAction(action)) {
10
- storage.removeItem('auth_token');
11
- }
12
-
13
- if (helpers.isFailureAction(action) && helpers.isUnauthorizedError(action)) {
14
- storage.removeItem('auth_token');
15
- }
16
-
17
- return next(action);
18
- };
19
-
20
- export default authMiddleware;
@@ -1,11 +0,0 @@
1
- import { routerMiddleware } from 'react-router-redux';
2
- import thunkMiddleware from 'redux-thunk';
3
-
4
- import authenticationMiddleware from 'redux/middlewares/authentication_middleware';
5
- import history from 'redux/history';
6
-
7
- export default [
8
- thunkMiddleware,
9
- routerMiddleware(history),
10
- authenticationMiddleware,
11
- ];
@@ -1,36 +0,0 @@
1
- import API from 'api';
2
- import config from 'redux/nodes/app/config';
3
-
4
- const { actionTypes } = config;
5
-
6
- const loginRequest = { type: actionTypes.LOGIN_REQUEST };
7
- const loginFailure = { type: actionTypes.LOGIN_FAILURE };
8
- const loginSuccess = (jwt) => {
9
- return { type: actionTypes.LOGIN_SUCCESS, payload: { jwt } };
10
- };
11
-
12
- const logoutRequest = { type: actionTypes.LOGOUT_REQUEST };
13
- const logoutFailure = { type: actionTypes.LOGOUT_FAILURE };
14
- const logoutSuccess = { type: actionTypes.LOGOUT_FAILURE };
15
-
16
- const login = ({ email, password }) => {
17
- return (dispatch) => {
18
- dispatch(loginRequest);
19
-
20
- return API.sessions.create({ email, password })
21
- .then(({ jwt }) => dispatch(loginSuccess(jwt)))
22
- .catch(() => dispatch(loginFailure));
23
- };
24
- };
25
-
26
- const logout = () => {
27
- return (dispatch) => {
28
- dispatch(logoutRequest);
29
-
30
- return API.sessions.destroy()
31
- .then(() => dispatch(logoutSuccess))
32
- .catch(() => dispatch(logoutFailure));
33
- };
34
- };
35
-
36
- export default { login, logout };
@@ -1,12 +0,0 @@
1
- const actionTypes = {
2
- LOGIN_REQUEST: 'LOGIN_REQUEST',
3
- LOGIN_SUCCESS: 'LOGIN_SUCCESS',
4
- LOGIN_FAILURE: 'LOGIN_FAILURE',
5
- LOGOUT_REQUEST: 'LOGOUT_REQUEST',
6
- LOGOUT_SUCCESS: 'LOGOUT_SUCCESS',
7
- LOGOUT_FAILURE: 'LOGOUT_FAILURE',
8
- };
9
-
10
- export default {
11
- actionTypes,
12
- };
@@ -1,35 +0,0 @@
1
- import config from 'redux/nodes/app/config';
2
- import initialState from 'redux/initial_state';
3
-
4
- const { actionTypes } = config;
5
-
6
- export default (state = initialState.app, action) => {
7
- switch (action.type) {
8
- case actionTypes.LOGIN_REQUEST:
9
- case actionTypes.LOGOUT_REQUEST:
10
- return {
11
- ...state,
12
- loading: true,
13
- };
14
- case actionTypes.LOGIN_SUCCESS:
15
- return {
16
- ...state,
17
- loading: false,
18
- session: { jwt: action.payload.jwt },
19
- };
20
- case actionTypes.LOGIN_FAILURE:
21
- case actionTypes.LOGOUT_SUCCESS:
22
- return {
23
- ...state,
24
- session: {},
25
- loading: false,
26
- };
27
- case actionTypes.LOGOUT_FAILURE:
28
- return {
29
- ...state,
30
- loading: false,
31
- };
32
- default:
33
- return state;
34
- }
35
- };
@@ -1,78 +0,0 @@
1
- import expect from 'expect';
2
-
3
- import reducer from 'redux/nodes/app/reducer';
4
- import { app as appState } from 'redux/initial_state';
5
-
6
- describe('App - reducer', () => {
7
- describe('dispatching the login actions', () => {
8
- describe('LOGIN_REQUEST', () => {
9
- it('sets the loading boolean to true', () => {
10
- const action = { type: 'LOGIN_REQUEST' };
11
-
12
- expect(reducer(appState, action)).toEqual({
13
- ...appState,
14
- loading: true,
15
- });
16
- });
17
- });
18
-
19
- describe('LOGIN_SUCCESS', () => {
20
- it('saves the JWT to state', () => {
21
- const action = { type: 'LOGIN_SUCCESS', payload: { jwt: 'jwt' } };
22
- expect(reducer(appState, action)).toEqual({
23
- ...appState,
24
- session: { jwt: 'jwt' },
25
- });
26
- });
27
- });
28
-
29
- describe('LOGIN_FAILURE', () => {
30
- it('removes the JWT from state', () => {
31
- const action = { type: 'LOGIN_FAILURE' };
32
- const state = { ...appState, session: { jwt: 'jwt' } };
33
-
34
- expect(reducer(state, action)).toEqual({
35
- ...appState,
36
- session: {},
37
- });
38
- });
39
- });
40
- });
41
-
42
- describe('dispatching the logout actions', () => {
43
- describe('LOGOUT_REQUEST', () => {
44
- it('sets the loading boolean to true', () => {
45
- const action = { type: 'LOGOUT_REQUEST' };
46
-
47
- expect(reducer(appState, action)).toEqual({
48
- ...appState,
49
- loading: true,
50
- });
51
- });
52
- });
53
-
54
- describe('LOGOUT_SUCCESS', () => {
55
- it('removes the JWT from state', () => {
56
- const action = { type: 'LOGOUT_SUCCESS' };
57
- const state = { ...appState, session: { jwt: 'jwt' } };
58
-
59
- expect(reducer(state, action)).toEqual({
60
- ...appState,
61
- session: {},
62
- });
63
- });
64
- });
65
-
66
- describe('LOGOUT_FAILURE', () => {
67
- it('sets the loading boolean to false', () => {
68
- const action = { type: 'LOGOUT_FAILURE' };
69
- const state = { ...appState, loading: true };
70
-
71
- expect(reducer(state, action)).toEqual({
72
- ...appState,
73
- loading: false,
74
- });
75
- });
76
- });
77
- });
78
- });