gnarails 1.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/actions/test-rails/action.yml +27 -0
- data/.github/workflows/bundler-audit.yml +19 -0
- data/.github/workflows/pronto.yml +30 -0
- data/.github/workflows/rails-test-app.yml +87 -0
- data/.github/workflows/run-unit-tests.yml +17 -0
- data/.railsrc +3 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +68 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +1 -2
- data/README.md +7 -35
- data/RELEASE_PROCESS.md +7 -8
- data/Rakefile +1 -1
- data/bin/bundle +120 -0
- data/bin/pronto +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/gnarails.gemspec +16 -6
- data/gnarly.rb +118 -176
- data/lib/gnarails/cli/application.rb +25 -153
- data/lib/gnarails/version.rb +3 -1
- data/templates/.github/workflows/brakeman.yml +22 -0
- data/templates/.github/workflows/run-tests.yml +26 -0
- data/templates/Procfile +1 -0
- data/templates/README.md +6 -6
- data/templates/bin/pronto +29 -0
- data/templates/bin/rspec +29 -0
- data/templates/bin/rubocop +29 -0
- data/templates/bin/setup +30 -0
- data/templates/docker-compose.yml/docker-compose-standard.yml +1 -1
- data/templates/esbuild.config.js +11 -0
- data/test-app/app/views/layouts/application.html.erb +6 -4
- data/test-app/spec/factories/job_postings.rb +1 -1
- data/test-app/spec/system/viewing_all_job_postings_spec.rb +5 -9
- metadata +39 -76
- data/.circleci/config.yml +0 -225
- data/bin/ci_pronto +0 -6
- data/bin/generate-react-test-app.sh +0 -2
- data/bin/generate-test-app.sh +0 -22
- data/templates/.circleci/config.yml +0 -66
- data/templates/.gitignore +0 -20
- data/templates/.ruby-version +0 -1
- data/templates/.scss-lint.yml +0 -33
- data/templates/Dockerfile-assets +0 -24
- data/templates/docker-compose.yml/docker-compose-webpack.yml +0 -26
- data/templates/react/.babelrc +0 -18
- data/templates/react/.eslintrc.js +0 -45
- data/templates/react/controllers/home_controller.rb +0 -4
- data/templates/react/js/Router/Router.jsx +0 -22
- data/templates/react/js/Router/index.js +0 -3
- data/templates/react/js/api/index.js +0 -17
- data/templates/react/js/api/sessions.js +0 -8
- data/templates/react/js/app_constants/index.js +0 -6
- data/templates/react/js/components/App/App.jsx +0 -15
- data/templates/react/js/components/App/App.tests.jsx +0 -15
- data/templates/react/js/components/App/_styles.scss +0 -3
- data/templates/react/js/components/App/index.js +0 -3
- data/templates/react/js/index.scss +0 -2
- data/templates/react/js/packs/main.jsx +0 -13
- data/templates/react/js/redux/entity_getter.js +0 -7
- data/templates/react/js/redux/history.js +0 -5
- data/templates/react/js/redux/initial_state.js +0 -5
- data/templates/react/js/redux/middlewares/authentication_middleware/authentication_middleware.tests.js +0 -109
- data/templates/react/js/redux/middlewares/authentication_middleware/helpers.js +0 -21
- data/templates/react/js/redux/middlewares/authentication_middleware/helpers.tests.js +0 -84
- data/templates/react/js/redux/middlewares/authentication_middleware/index.js +0 -20
- data/templates/react/js/redux/middlewares/index.js +0 -11
- data/templates/react/js/redux/nodes/app/actions.js +0 -36
- data/templates/react/js/redux/nodes/app/config.js +0 -12
- data/templates/react/js/redux/nodes/app/reducer.js +0 -35
- data/templates/react/js/redux/nodes/app/reducer.tests.js +0 -78
- data/templates/react/js/redux/reducers.js +0 -11
- data/templates/react/js/redux/store.js +0 -14
- data/templates/react/js/storage.js +0 -15
- data/templates/react/js/styles/_variables.scss +0 -1
- data/templates/react/js/test/.setup.js +0 -51
- data/templates/react/js/test/connect_wrapper.jsx +0 -28
- data/templates/react/js/test/create_request_mock.js +0 -29
- data/templates/react/js/test/mock_store.js +0 -12
- data/templates/react/layout.html.erb +0 -16
- data/templates/react/rails_routes.rb +0 -5
- data/templates/react/views/home/default.html.erb +0 -1
- data/templates/script/brakeman +0 -15
- data/templates/script/ci_pronto +0 -6
data/bin/generate-test-app.sh
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
bundle exec exe/gnarails new rails-test-app
|
3
|
-
|
4
|
-
mkdir rails-test-app/app/views/job_postings
|
5
|
-
mkdir rails-test-app/db/migrate
|
6
|
-
mkdir rails-test-app/spec/factories
|
7
|
-
mkdir rails-test-app/spec/models
|
8
|
-
mkdir rails-test-app/spec/system
|
9
|
-
mkdir rails-test-app/spec/requests
|
10
|
-
|
11
|
-
cp test-app/app/controllers/job_postings_controller.rb rails-test-app/app/controllers/job_postings_controller.rb
|
12
|
-
cp test-app/app/models/job_posting.rb rails-test-app/app/models/job_posting.rb
|
13
|
-
cp test-app/app/models/comment.rb rails-test-app/app/models/comment.rb
|
14
|
-
cp test-app/app/views/job_postings/index.html.erb rails-test-app/app/views/job_postings/index.html.erb
|
15
|
-
yes | cp test-app/app/views/layouts/application.html.erb rails-test-app/app/views/layouts/application.html.erb
|
16
|
-
yes | cp test-app/config/routes.rb rails-test-app/config/routes.rb
|
17
|
-
cp test-app/db/migrate/20170918002433_create_job_postings.rb rails-test-app/db/migrate/20170918002433_create_job_postings.rb
|
18
|
-
cp test-app/db/migrate/20170918002455_create_comments.rb rails-test-app/db/migrate/20170918002455_create_comments.rb
|
19
|
-
cp test-app/spec/factories/job_postings.rb rails-test-app/spec/factories/job_postings.rb
|
20
|
-
cp test-app/spec/models/job_posting_spec.rb rails-test-app/spec/models/job_posting_spec.rb
|
21
|
-
cp test-app/spec/system/viewing_all_job_postings_spec.rb rails-test-app/spec/system/viewing_all_job_postings_spec.rb
|
22
|
-
cp test-app/spec/requests/status_spec.rb rails-test-app/spec/requests/status_spec.rb
|
@@ -1,66 +0,0 @@
|
|
1
|
-
version: 2.0
|
2
|
-
jobs:
|
3
|
-
build:
|
4
|
-
docker:
|
5
|
-
- image: circleci/ruby:__ruby_version__-stretch-node-browsers
|
6
|
-
environment:
|
7
|
-
RAILS_ENV: test
|
8
|
-
- image: circleci/postgres:9.6.5
|
9
|
-
steps:
|
10
|
-
- checkout
|
11
|
-
|
12
|
-
# Restore bundle cache
|
13
|
-
- restore_cache:
|
14
|
-
key: __application_name__-{{ checksum "Gemfile.lock" }}
|
15
|
-
|
16
|
-
# cmake is required by Rugged, a dependency of Pronto
|
17
|
-
- run:
|
18
|
-
name: Install cmake
|
19
|
-
command: sudo apt-get -y -qq update && sudo apt-get -y -qq install cmake
|
20
|
-
|
21
|
-
# Bundle install dependencies
|
22
|
-
- run:
|
23
|
-
name: Install dependencies
|
24
|
-
command: bundle install --path vendor/bundle
|
25
|
-
|
26
|
-
# Store bundle cache
|
27
|
-
- save_cache:
|
28
|
-
key: __application_name__-{{ checksum "Gemfile.lock" }}
|
29
|
-
paths:
|
30
|
-
- vendor/bundle
|
31
|
-
|
32
|
-
# Database setup
|
33
|
-
- run:
|
34
|
-
name: Create database
|
35
|
-
command: bundle exec rake db:create
|
36
|
-
- run:
|
37
|
-
name: Load database schema
|
38
|
-
command: bundle exec rake db:schema:load
|
39
|
-
|
40
|
-
# Tests
|
41
|
-
- run:
|
42
|
-
name: RSpec
|
43
|
-
command: bundle exec rspec
|
44
|
-
|
45
|
-
# Security analysis
|
46
|
-
- run:
|
47
|
-
name: Bundler Audit
|
48
|
-
command: bundle exec bundle-audit update && bundle exec bundle-audit check
|
49
|
-
- run:
|
50
|
-
name: Brakeman
|
51
|
-
command: ./script/brakeman
|
52
|
-
|
53
|
-
# Pronto
|
54
|
-
- run:
|
55
|
-
name: Pronto
|
56
|
-
command: ./script/ci_pronto
|
57
|
-
|
58
|
-
# Save Brakeman
|
59
|
-
- store_artifacts:
|
60
|
-
path: tmp/brakeman.html
|
61
|
-
destination: security/brakeman.html
|
62
|
-
|
63
|
-
# Save Coverage Analysis
|
64
|
-
- store_artifacts:
|
65
|
-
path: coverage
|
66
|
-
destination: coverage
|
data/templates/.gitignore
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
2
|
-
#
|
3
|
-
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
-
# or operating system, you probably want to add a global ignore instead:
|
5
|
-
# git config --global core.excludesfile '~/.gitignore_global'
|
6
|
-
|
7
|
-
# Ignore bundler config.
|
8
|
-
/.bundle
|
9
|
-
|
10
|
-
# Ignore all logfiles and tempfiles.
|
11
|
-
/log/*
|
12
|
-
/tmp/*
|
13
|
-
!/log/.keep
|
14
|
-
!/tmp/.keep
|
15
|
-
|
16
|
-
# Ignore Byebug command history file.
|
17
|
-
.byebug_history
|
18
|
-
|
19
|
-
# Ignore output of simplecov
|
20
|
-
coverage
|
data/templates/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
__ruby_version__
|
data/templates/.scss-lint.yml
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
scss_files: 'app/assets/stylesheets/**/*.scss'
|
2
|
-
exclude: 'app/assets/stylesheets/plugins/**'
|
3
|
-
|
4
|
-
linters:
|
5
|
-
StringQuotes:
|
6
|
-
enabled: false
|
7
|
-
|
8
|
-
LeadingZero:
|
9
|
-
enabled: false
|
10
|
-
|
11
|
-
BorderZero:
|
12
|
-
enabled: false
|
13
|
-
|
14
|
-
ColorVariable:
|
15
|
-
enabled: false
|
16
|
-
|
17
|
-
Comment:
|
18
|
-
enabled: false
|
19
|
-
|
20
|
-
FinalNewline:
|
21
|
-
enabled: false
|
22
|
-
|
23
|
-
IdSelector:
|
24
|
-
enabled: false
|
25
|
-
|
26
|
-
NestingDepth:
|
27
|
-
enabled: true
|
28
|
-
max_depth: 6
|
29
|
-
ignore_parent_selectors: false
|
30
|
-
|
31
|
-
SelectorDepth:
|
32
|
-
enabled: true
|
33
|
-
max_depth: 6
|
data/templates/Dockerfile-assets
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
FROM ruby:__ruby_version__
|
2
|
-
|
3
|
-
# use a newer version of Node to use Yarn
|
4
|
-
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
|
5
|
-
|
6
|
-
# nodejs: Rails needs a JS runtime
|
7
|
-
# cmake: required by Rugged, dependency of Pronto
|
8
|
-
RUN apt-get update -qq \
|
9
|
-
&& apt-get install -y -qq nodejs cmake
|
10
|
-
|
11
|
-
RUN npm install -g yarn
|
12
|
-
|
13
|
-
RUN mkdir /app
|
14
|
-
WORKDIR /app
|
15
|
-
|
16
|
-
ADD Gemfile /app/Gemfile
|
17
|
-
ADD Gemfile.lock /app/Gemfile.lock
|
18
|
-
RUN bundle install
|
19
|
-
|
20
|
-
ADD package.json /app/package.json
|
21
|
-
ADD yarn.lock /app/yarn.lock
|
22
|
-
RUN yarn install
|
23
|
-
|
24
|
-
ADD . /app
|
@@ -1,26 +0,0 @@
|
|
1
|
-
version: '3'
|
2
|
-
services:
|
3
|
-
db:
|
4
|
-
image: postgres
|
5
|
-
assets:
|
6
|
-
build:
|
7
|
-
context: .
|
8
|
-
dockerfile: Dockerfile-assets
|
9
|
-
command: yarn start
|
10
|
-
volumes:
|
11
|
-
- .:/app
|
12
|
-
- /app/node_modules
|
13
|
-
env_file:
|
14
|
-
- .env.docker-assets
|
15
|
-
web:
|
16
|
-
build: .
|
17
|
-
command: bash -c 'rm -f tmp/pids/server.pid && bundle exec rails s --port 3000 --binding 0.0.0.0'
|
18
|
-
volumes:
|
19
|
-
- .:/app
|
20
|
-
ports:
|
21
|
-
- 3000:3000
|
22
|
-
depends_on:
|
23
|
-
- db
|
24
|
-
- assets
|
25
|
-
env_file:
|
26
|
-
- .env.docker
|
data/templates/react/.babelrc
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
var path = require('path');
|
2
|
-
|
3
|
-
module.exports = {
|
4
|
-
extends: 'airbnb',
|
5
|
-
parser: 'babel-eslint',
|
6
|
-
env: {
|
7
|
-
'node': true,
|
8
|
-
'mocha': true
|
9
|
-
},
|
10
|
-
globals: {
|
11
|
-
'expect': false,
|
12
|
-
'describe': false
|
13
|
-
},
|
14
|
-
rules: {
|
15
|
-
'consistent-return': 1,
|
16
|
-
'arrow-body-style': 0,
|
17
|
-
'max-len': 0,
|
18
|
-
'jsx-a11y/img-has-alt': 0,
|
19
|
-
'no-use-before-define': [2, 'nofunc'],
|
20
|
-
'no-unused-expressions': 0,
|
21
|
-
'no-console': 0,
|
22
|
-
'space-before-function-paren': 0,
|
23
|
-
'react/prefer-stateless-function': 0,
|
24
|
-
'react/no-multi-comp': 0,
|
25
|
-
'react/no-unused-prop-types': [1, { 'customValidators': [], skipShapeProps: true }],
|
26
|
-
'no-param-reassign': 0,
|
27
|
-
'new-cap': 0,
|
28
|
-
'import/no-unresolved': 'error',
|
29
|
-
'import/no-extraneous-dependencies': ['error', { 'devDependencies': true }],
|
30
|
-
'linebreak-style': 0,
|
31
|
-
'import/no-named-as-default': 'off',
|
32
|
-
'import/no-named-as-default-member': 'off',
|
33
|
-
'no-underscore-dangle': 0
|
34
|
-
},
|
35
|
-
settings: {
|
36
|
-
'import/resolver': {
|
37
|
-
webpack: {
|
38
|
-
config: path.join(__dirname, 'webpack.config.js')
|
39
|
-
},
|
40
|
-
node: {
|
41
|
-
paths: 'app/javascript'
|
42
|
-
}
|
43
|
-
}
|
44
|
-
}
|
45
|
-
}
|
@@ -1,22 +0,0 @@
|
|
1
|
-
import React, { Component } from 'react';
|
2
|
-
import { Provider } from 'react-redux';
|
3
|
-
import { ConnectedRouter } from 'react-router-redux'
|
4
|
-
import { Route } from 'react-router';
|
5
|
-
|
6
|
-
import App from 'components/App';
|
7
|
-
import history from 'redux/history';
|
8
|
-
import store from 'redux/store';
|
9
|
-
|
10
|
-
export default class Router extends Component {
|
11
|
-
render () {
|
12
|
-
return (
|
13
|
-
<Provider store={store}>
|
14
|
-
<ConnectedRouter history={history}>
|
15
|
-
<App>
|
16
|
-
<h1>Welcome to Gnarails</h1>
|
17
|
-
</App>
|
18
|
-
</ConnectedRouter>
|
19
|
-
</Provider>
|
20
|
-
)
|
21
|
-
}
|
22
|
-
}
|
@@ -1,17 +0,0 @@
|
|
1
|
-
import Schlepp from 'schlepp';
|
2
|
-
|
3
|
-
import appConstants from 'app_constants';
|
4
|
-
import sessionMethods from 'api/sessions';
|
5
|
-
|
6
|
-
class Api extends Schlepp {
|
7
|
-
constructor(options) {
|
8
|
-
super(options);
|
9
|
-
|
10
|
-
this.sessions = sessionMethods(this);
|
11
|
-
}
|
12
|
-
}
|
13
|
-
|
14
|
-
export default new Api({
|
15
|
-
host: appConstants.API_HOST,
|
16
|
-
bearerTokenKeyInLocalStorage: `${appConstants.APP_NAME}:auth_token`,
|
17
|
-
});
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import React, { Component } from 'react';
|
2
|
-
import { withRouter } from 'react-router-dom';
|
3
|
-
|
4
|
-
class App extends Component {
|
5
|
-
render () {
|
6
|
-
const { children } = this.props;
|
7
|
-
return (
|
8
|
-
<div className="app">
|
9
|
-
{children}
|
10
|
-
</div>
|
11
|
-
);
|
12
|
-
}
|
13
|
-
};
|
14
|
-
|
15
|
-
export default withRouter(App);
|
@@ -1,15 +0,0 @@
|
|
1
|
-
import React from 'react';
|
2
|
-
import expect from 'expect';
|
3
|
-
import { mount } from 'enzyme';
|
4
|
-
|
5
|
-
import App from 'components/App';
|
6
|
-
import connectWrapper from 'test/connect_wrapper';
|
7
|
-
|
8
|
-
describe('App - component', () => {
|
9
|
-
it('renders', () => {
|
10
|
-
const WrappedApp = connectWrapper(App);
|
11
|
-
const Component = mount(<WrappedApp />);
|
12
|
-
|
13
|
-
expect(Component.find('App').length).toEqual(1);
|
14
|
-
});
|
15
|
-
});
|
@@ -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,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
|
-
];
|