automock 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/LISENCE.txt +22 -0
- data/README.md +110 -0
- data/Rakefile +11 -0
- data/automock/data/test.json +1 -0
- data/automock/data/test2.json +1 -0
- data/automock.gemspec +27 -0
- data/bin/console +14 -0
- data/bin/server +3 -0
- data/bin/setup +13 -0
- data/lib/automock/response_mock.rb +55 -0
- data/lib/automock/rspec.rb +11 -0
- data/lib/automock/version.rb +3 -0
- data/lib/automock.rb +24 -0
- data/lib/tasks/automock.rake +31 -0
- data/server/.babelrc +3 -0
- data/server/.eslintrc +104 -0
- data/server/.flowconfig +11 -0
- data/server/.gitignore +4 -0
- data/server/app/db/database.json +10 -0
- data/server/app/db/sequelize.js +4 -0
- data/server/app/index.js +75 -0
- data/server/app/models/selected_file.js +11 -0
- data/server/app/proxy_server.js +50 -0
- data/server/assets/index.html +12 -0
- data/server/assets/javascripts/actions/mock_files_actions.js +18 -0
- data/server/assets/javascripts/actions/selected_files_actions.js +46 -0
- data/server/assets/javascripts/components/file_list.react.js +23 -0
- data/server/assets/javascripts/components/select_buttons.react.js +18 -0
- data/server/assets/javascripts/components/selectable_lists.react.js +44 -0
- data/server/assets/javascripts/containers/app.react.js +56 -0
- data/server/assets/javascripts/index.js +23 -0
- data/server/assets/javascripts/reducers/index.js +7 -0
- data/server/assets/javascripts/reducers/mock_files.js +11 -0
- data/server/assets/javascripts/reducers/selected_files.js +15 -0
- data/server/assets/stylesheets/application.scss +4 -0
- data/server/assets/stylesheets/components/_file_list.scss +9 -0
- data/server/assets/stylesheets/components/_select_buttons.scss +6 -0
- data/server/assets/stylesheets/components/_selectable_list.scss +3 -0
- data/server/bin/server +13 -0
- data/server/gulpfile.coffee +35 -0
- data/server/migrations/20160101185711-add-selected-files.js +15 -0
- data/server/migrations/20160102233558-add-columns-to-selected-files.js +17 -0
- data/server/package.json +58 -0
- data/server/test/fixtures/mock/api/v1/api_test.json +1 -0
- data/server/test/fixtures/mock/test.json +1 -0
- data/server/test/request/common_hooks.js +20 -0
- data/server/test/request/mock_files_test.js +34 -0
- data/server/test/request/selected_files_test.js +63 -0
- metadata +182 -0
data/server/app/index.js
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const express = require('express');
|
4
|
+
const app = express();
|
5
|
+
const recursive = require('recursive-readdir');
|
6
|
+
const path = require('path');
|
7
|
+
const SelectedFile = require('./models/selected_file');
|
8
|
+
const bodyParser = require('body-parser');
|
9
|
+
const fs = require('fs');
|
10
|
+
|
11
|
+
app.use(express.static(__dirname + '/assets'));
|
12
|
+
app.use(bodyParser.urlencoded());
|
13
|
+
app.use(bodyParser.json());
|
14
|
+
let proxyServer;
|
15
|
+
|
16
|
+
app.get('/mock_files', function(_req, res){
|
17
|
+
recursive(process.env.AUTOMOCK_DATA_PATH, (_err, filePaths) => {
|
18
|
+
Promise.all(filePaths.map((filePath) =>
|
19
|
+
new Promise((resolve) => {
|
20
|
+
fs.readFile(filePath, 'utf8', (_err2, text) => {
|
21
|
+
const mockData = JSON.parse(text);
|
22
|
+
mockData.name = path.relative(process.env.AUTOMOCK_DATA_PATH, filePath);
|
23
|
+
resolve(mockData);
|
24
|
+
});
|
25
|
+
})
|
26
|
+
)).then((files) => {
|
27
|
+
res.status(200).send(files);
|
28
|
+
});
|
29
|
+
});
|
30
|
+
});
|
31
|
+
|
32
|
+
app.get('/selected_files', function(req, res){
|
33
|
+
SelectedFile.findAll().
|
34
|
+
then((files) => {
|
35
|
+
const response = files.map((file) => {
|
36
|
+
return {
|
37
|
+
id: file.id,
|
38
|
+
name: file.name
|
39
|
+
};
|
40
|
+
});
|
41
|
+
res.status(200).send(response);
|
42
|
+
});
|
43
|
+
});
|
44
|
+
|
45
|
+
app.post('/selected_files', function(req, res){
|
46
|
+
SelectedFile.create({
|
47
|
+
name: req.body.name,
|
48
|
+
uri: req.body.uri,
|
49
|
+
method: req.body.method
|
50
|
+
}).then((selectedFile) => {
|
51
|
+
res.status(201).send(selectedFile);
|
52
|
+
if (proxyServer) {
|
53
|
+
proxyServer.loadSelectedFiles();
|
54
|
+
}
|
55
|
+
});
|
56
|
+
});
|
57
|
+
|
58
|
+
app.delete('/selected_files/:id', function(req, res){
|
59
|
+
SelectedFile.destroy({ where: { id: req.params.id } }).then(() => {
|
60
|
+
res.status(204).send();
|
61
|
+
if (proxyServer) {
|
62
|
+
proxyServer.loadSelectedFiles();
|
63
|
+
}
|
64
|
+
});
|
65
|
+
});
|
66
|
+
|
67
|
+
if (!module.parent) {
|
68
|
+
app.listen(process.env.AUTOMOCK_PORT || 8000);
|
69
|
+
const ProxyServer = require('./proxy_server');
|
70
|
+
proxyServer = new ProxyServer();
|
71
|
+
proxyServer.start();
|
72
|
+
}
|
73
|
+
|
74
|
+
|
75
|
+
module.exports = app;
|
@@ -0,0 +1,11 @@
|
|
1
|
+
const Sequelize = require('sequelize');
|
2
|
+
const sequelize = require('./../db/sequelize');
|
3
|
+
const SelectedFile = sequelize.define('selected_files', {
|
4
|
+
name: { type: Sequelize.STRING },
|
5
|
+
method: { type: Sequelize.STRING },
|
6
|
+
uri: { type: Sequelize.STRING }
|
7
|
+
}, {
|
8
|
+
freezeTableName: true
|
9
|
+
});
|
10
|
+
|
11
|
+
module.exports = SelectedFile;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const httpProxy = require('http-proxy');
|
4
|
+
const SelectedFile = require('./models/selected_file');
|
5
|
+
const _ = require('underscore');
|
6
|
+
const fs = require('fs');
|
7
|
+
|
8
|
+
class ProxyServer {
|
9
|
+
constructor() {
|
10
|
+
const targetPort = process.env.AUTOMOCK_TARGET_PORT || 3000;
|
11
|
+
const proxyPort = process.env.AUTOMOCK_PROXY_PORT || 8001;
|
12
|
+
this.server = httpProxy.createProxyServer({
|
13
|
+
target:`http://localhost:${targetPort}`
|
14
|
+
}).listen(proxyPort);
|
15
|
+
this.selectedFiles = [];
|
16
|
+
}
|
17
|
+
|
18
|
+
loadSelectedFiles() {
|
19
|
+
SelectedFile.findAll().then((records) => {
|
20
|
+
this.selectedFiles = records;
|
21
|
+
});
|
22
|
+
}
|
23
|
+
|
24
|
+
start() {
|
25
|
+
this.loadSelectedFiles();
|
26
|
+
this.server.on('proxyRes', (_proxyRes, req, res) => {
|
27
|
+
const lookupedSelectedFile = _.find(this.selectedFiles, (selectedFile) =>
|
28
|
+
(selectedFile.uri === req.url) && (selectedFile.method === req.method)
|
29
|
+
);
|
30
|
+
if (lookupedSelectedFile) {
|
31
|
+
const write = res.write, writeHead = res.writeHead, end = res.end, bufs = [];
|
32
|
+
res.writeHead = (_status, _headers) => {
|
33
|
+
res.write = (body) => {
|
34
|
+
bufs.push(body);
|
35
|
+
};
|
36
|
+
res.end = () => {
|
37
|
+
fs.readFile(`${process.env.AUTOMOCK_DATA_PATH}/${lookupedSelectedFile.name}`, 'utf8', function (_err, text) {
|
38
|
+
const mockData = JSON.parse(text);
|
39
|
+
writeHead.call(res, mockData.status, mockData.response_header);
|
40
|
+
write.call(res, mockData.response_body);
|
41
|
+
end.call(res);
|
42
|
+
});
|
43
|
+
};
|
44
|
+
};
|
45
|
+
}
|
46
|
+
});
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
module.exports = ProxyServer;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<title>automock</title>
|
6
|
+
<link rel="stylesheet" href="stylesheets/application.css" media="screen">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id="application"></div>
|
10
|
+
<script src="bundle.js"></script>
|
11
|
+
</body>
|
12
|
+
</html>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/* flow */
|
2
|
+
|
3
|
+
import request from 'superagent';
|
4
|
+
export const GET_MOCK_FILES = 'GET_MOCK_FILES';
|
5
|
+
|
6
|
+
export function getMockFiles() {
|
7
|
+
return (dispatch) => {
|
8
|
+
request.
|
9
|
+
get('./mock_files').
|
10
|
+
end((_err, res) => {
|
11
|
+
dispatch({
|
12
|
+
type: GET_MOCK_FILES,
|
13
|
+
mockFiles: res.body
|
14
|
+
});
|
15
|
+
}
|
16
|
+
);
|
17
|
+
};
|
18
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
/* flow */
|
2
|
+
|
3
|
+
import request from 'superagent';
|
4
|
+
export const GET_SELECTED_FILES = 'GET_SELECTED_FILES';
|
5
|
+
export const CREATE_SELECTED_FILES = 'CREATE_SELECTED_FILES';
|
6
|
+
export const DELETE_SELECTED_FILES = 'DELETE_SELECTED_FILES';
|
7
|
+
|
8
|
+
export function getSelectedFiles() {
|
9
|
+
return (dispatch) => {
|
10
|
+
request.
|
11
|
+
get('/selected_files').
|
12
|
+
end((_err, res) => {
|
13
|
+
dispatch({
|
14
|
+
type: GET_SELECTED_FILES,
|
15
|
+
selectedFiles: res.body
|
16
|
+
});
|
17
|
+
}
|
18
|
+
);
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
export function createSelectedFile(file) {
|
23
|
+
return (dispatch) => {
|
24
|
+
request.
|
25
|
+
post('/selected_files').
|
26
|
+
send(file).
|
27
|
+
end((_err, res) => {
|
28
|
+
dispatch({
|
29
|
+
type: CREATE_SELECTED_FILES,
|
30
|
+
selectedFile: res.body
|
31
|
+
});
|
32
|
+
}
|
33
|
+
);
|
34
|
+
};
|
35
|
+
}
|
36
|
+
|
37
|
+
export function deleteSelectedFile(id) {
|
38
|
+
return (dispatch) => {
|
39
|
+
request.
|
40
|
+
delete(`/selected_files/${id}`).
|
41
|
+
end((_err, _res) => {
|
42
|
+
dispatch({ type: DELETE_SELECTED_FILES, id });
|
43
|
+
}
|
44
|
+
);
|
45
|
+
};
|
46
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
export default class FileList extends React.Component {
|
4
|
+
handleSelect(e) {
|
5
|
+
const selectedFile = this.props.files.filter((file) => file.name === e.target.value).toArray()[0];
|
6
|
+
this.props.onChange(selectedFile);
|
7
|
+
}
|
8
|
+
render() {
|
9
|
+
const options = this.props.files.map((file) =>
|
10
|
+
<option value={file.name} key={file.name}>{file.name}</option>
|
11
|
+
);
|
12
|
+
return(
|
13
|
+
<div className="file-list col-xs-5">
|
14
|
+
<div className="title">{this.props.title}</div>
|
15
|
+
<div>
|
16
|
+
<select size="10" onChange={this.handleSelect.bind(this)}>
|
17
|
+
{options}
|
18
|
+
</select>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
);
|
22
|
+
}
|
23
|
+
};
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
export default class SelectButtons extends React.Component {
|
4
|
+
handleClickSelectButton() {
|
5
|
+
this.props.onClickSelectButton(this.props.selectedFromNotSelectedFiles);
|
6
|
+
}
|
7
|
+
handleClickUnselectButton() {
|
8
|
+
this.props.onClickUnselectButton(this.props.selectedFromSelectedFiles.id);
|
9
|
+
}
|
10
|
+
render() {
|
11
|
+
return(
|
12
|
+
<div className="select-buttons col-xs-1">
|
13
|
+
<button className="btn btn-primary" onClick={this.handleClickSelectButton.bind(this)}>→</button>
|
14
|
+
<button className="btn" onClick={this.handleClickUnselectButton.bind(this)}>←</button>
|
15
|
+
</div>
|
16
|
+
);
|
17
|
+
}
|
18
|
+
};
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import FileList from './file_list';
|
3
|
+
import SelectButtons from './select_buttons';
|
4
|
+
|
5
|
+
export default class SelectableLists extends React.Component {
|
6
|
+
constructor() {
|
7
|
+
super();
|
8
|
+
this.state = {
|
9
|
+
selectedFromNotSelectedFiles: '',
|
10
|
+
selectedFromSelectedFiles: ''
|
11
|
+
};
|
12
|
+
}
|
13
|
+
|
14
|
+
handleSelectFromNotSelectedFiles(selectedFile) {
|
15
|
+
this.setState({ selectedFromNotSelectedFiles: selectedFile });
|
16
|
+
}
|
17
|
+
|
18
|
+
handleSelectFromSelectedFiles(selectedFile) {
|
19
|
+
this.setState({ selectedFromSelectedFiles: selectedFile });
|
20
|
+
}
|
21
|
+
|
22
|
+
render() {
|
23
|
+
const { selectedFiles, unselectedFiles } = this.props;
|
24
|
+
return(
|
25
|
+
<div className="selectable-lists row">
|
26
|
+
<FileList
|
27
|
+
title={"not selected files"}
|
28
|
+
files={unselectedFiles}
|
29
|
+
onChange={this.handleSelectFromNotSelectedFiles.bind(this)}
|
30
|
+
/>
|
31
|
+
<SelectButtons
|
32
|
+
onClickSelectButton={this.props.onCreateSelectedFile}
|
33
|
+
onClickUnselectButton={this.props.onDeleteSelectedFile}
|
34
|
+
{...this.state}
|
35
|
+
/>
|
36
|
+
<FileList
|
37
|
+
title={"selected files"}
|
38
|
+
files={selectedFiles}
|
39
|
+
onChange={this.handleSelectFromSelectedFiles.bind(this)}
|
40
|
+
/>
|
41
|
+
</div>
|
42
|
+
);
|
43
|
+
}
|
44
|
+
};
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { bindActionCreators } from 'redux';
|
3
|
+
import { connect } from 'react-redux';
|
4
|
+
import * as SelectedFilesActions from '../actions/selected_files_actions';
|
5
|
+
import * as MockFilesActions from '../actions/mock_files_actions';
|
6
|
+
import SelectableLists from './../components/selectable_lists';
|
7
|
+
import assign from 'object-assign';
|
8
|
+
import _ from 'underscore';
|
9
|
+
|
10
|
+
class AppContainer extends React.Component {
|
11
|
+
componentDidMount() {
|
12
|
+
const { getSelectedFiles, getMockFiles } = this.props;
|
13
|
+
getSelectedFiles();
|
14
|
+
getMockFiles();
|
15
|
+
}
|
16
|
+
|
17
|
+
handleCreateSelectedFile(file) {
|
18
|
+
const { createSelectedFile } = this.props;
|
19
|
+
createSelectedFile(file);
|
20
|
+
}
|
21
|
+
|
22
|
+
handleDeleteSelectedFile(id) {
|
23
|
+
const { deleteSelectedFile } = this.props;
|
24
|
+
deleteSelectedFile(id);
|
25
|
+
}
|
26
|
+
|
27
|
+
render() {
|
28
|
+
const { selectedFiles, mockFiles } = this.props;
|
29
|
+
const selectedFileNames = selectedFiles.map((file) => file.name).toArray();
|
30
|
+
const unselectedFiles = mockFiles.filter((file) => !_.includes(selectedFileNames, file.name));
|
31
|
+
return (
|
32
|
+
<div className="container">
|
33
|
+
<SelectableLists
|
34
|
+
selectedFiles={selectedFiles}
|
35
|
+
unselectedFiles={unselectedFiles}
|
36
|
+
onCreateSelectedFile={this.handleCreateSelectedFile.bind(this)}
|
37
|
+
onDeleteSelectedFile={this.handleDeleteSelectedFile.bind(this)}
|
38
|
+
/>
|
39
|
+
</div>
|
40
|
+
);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function mapStateToProps(state) {
|
45
|
+
return {
|
46
|
+
selectedFiles: state.selectedFiles,
|
47
|
+
mockFiles: state.mockFiles
|
48
|
+
};
|
49
|
+
}
|
50
|
+
|
51
|
+
function mapDispatchToProps(dispatch) {
|
52
|
+
const actions = assign({}, SelectedFilesActions, MockFilesActions);
|
53
|
+
return bindActionCreators(actions, dispatch);
|
54
|
+
}
|
55
|
+
|
56
|
+
export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { render } from 'react-dom';
|
3
|
+
import { createStore, applyMiddleware } from 'redux';
|
4
|
+
import { Provider } from 'react-redux';
|
5
|
+
import App from './containers/app';
|
6
|
+
import reducers from './reducers';
|
7
|
+
import thunk from 'redux-thunk';
|
8
|
+
import logger from 'redux-logger';
|
9
|
+
|
10
|
+
const middleware = process.env.NODE_ENV === 'production' ?
|
11
|
+
[ thunk ] :
|
12
|
+
[ thunk, logger() ];
|
13
|
+
|
14
|
+
const createStoreWithMiddleware = applyMiddleware(...middleware)(createStore);
|
15
|
+
const store = createStoreWithMiddleware(reducers);
|
16
|
+
|
17
|
+
const rootElement = document.getElementById('application');
|
18
|
+
render(
|
19
|
+
<Provider store={store}>
|
20
|
+
<App />
|
21
|
+
</Provider>,
|
22
|
+
rootElement
|
23
|
+
);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { List } from 'immutable';
|
2
|
+
import { GET_MOCK_FILES } from '../actions/mock_files_actions';
|
3
|
+
|
4
|
+
export default function mockFiles(state = List(), action) {
|
5
|
+
switch (action.type) {
|
6
|
+
case GET_MOCK_FILES:
|
7
|
+
return List(action.mockFiles);
|
8
|
+
default:
|
9
|
+
return state;
|
10
|
+
}
|
11
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { List } from 'immutable';
|
2
|
+
import { GET_SELECTED_FILES, CREATE_SELECTED_FILES, DELETE_SELECTED_FILES } from '../actions/selected_files_actions';
|
3
|
+
|
4
|
+
export default function selectedFiles(state = List(), action) {
|
5
|
+
switch (action.type) {
|
6
|
+
case GET_SELECTED_FILES:
|
7
|
+
return List(action.selectedFiles);
|
8
|
+
case CREATE_SELECTED_FILES:
|
9
|
+
return state.push(action.selectedFile);
|
10
|
+
case DELETE_SELECTED_FILES:
|
11
|
+
return state.filter((file) => file.id !== action.id);
|
12
|
+
default:
|
13
|
+
return state;
|
14
|
+
}
|
15
|
+
}
|
data/server/bin/server
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
gulp = require 'gulp'
|
2
|
+
babelify = require 'babelify'
|
3
|
+
browserify = require 'browserify'
|
4
|
+
source = require 'vinyl-source-stream'
|
5
|
+
sass = require 'gulp-sass'
|
6
|
+
seq = require 'run-sequence'
|
7
|
+
|
8
|
+
gulp.path =
|
9
|
+
src: 'assets'
|
10
|
+
dist: 'app/assets'
|
11
|
+
|
12
|
+
gulp.task 'build', ->
|
13
|
+
seq ['build:html', 'build:browserify', 'build:scss']
|
14
|
+
|
15
|
+
gulp.task 'build:html', ->
|
16
|
+
gulp.src "#{@path.src}/**/*.html"
|
17
|
+
.pipe gulp.dest(@path.dist)
|
18
|
+
|
19
|
+
gulp.task 'build:browserify', ->
|
20
|
+
browserify(
|
21
|
+
entries: ["#{@path.src}/javascripts/index.js"]
|
22
|
+
extensions: ['.js', '.react.js']
|
23
|
+
).transform(babelify)
|
24
|
+
.bundle()
|
25
|
+
.pipe source 'bundle.js'
|
26
|
+
.pipe gulp.dest(@path.dist)
|
27
|
+
|
28
|
+
gulp.task 'build:scss', ->
|
29
|
+
gulp.src "#{@path.src}/**/*.scss"
|
30
|
+
.pipe sass({ includePaths: [ 'node_modules' ] }).on('error', sass.logError)
|
31
|
+
.pipe gulp.dest(@path.dist)
|
32
|
+
|
33
|
+
gulp.task 'watch', ['build'], ->
|
34
|
+
gulp.watch("#{@path.src}/**/*.js", ['build:browserify'])
|
35
|
+
gulp.watch("#{@path.src}/**/*.scss", ['build:scss'])
|
@@ -0,0 +1,15 @@
|
|
1
|
+
var dbm = global.dbm || require('db-migrate');
|
2
|
+
var type = dbm.dataType;
|
3
|
+
|
4
|
+
exports.up = function(db, callback) {
|
5
|
+
db.createTable('selected_files', {
|
6
|
+
id: { type: 'int', primaryKey: true, autoIncrement: true },
|
7
|
+
name: { type: 'string', unique: true, notNull: 'true' },
|
8
|
+
createdAt: { type: 'datetime' },
|
9
|
+
updatedAt: { type: 'datetime' }
|
10
|
+
}, callback);
|
11
|
+
};
|
12
|
+
|
13
|
+
exports.down = function(db, callback) {
|
14
|
+
callback();
|
15
|
+
};
|
@@ -0,0 +1,17 @@
|
|
1
|
+
var dbm = global.dbm || require('db-migrate');
|
2
|
+
var type = dbm.dataType;
|
3
|
+
var async = require('async');
|
4
|
+
|
5
|
+
exports.up = function(db, callback) {
|
6
|
+
async.series([
|
7
|
+
db.addColumn.bind(db, 'selected_files', 'method', { type: 'string', notNull: true, defaultValue: 'dummy' }),
|
8
|
+
db.addColumn.bind(db, 'selected_files', 'uri', { type: 'string', notNull: true, defaultValue: 'dummy' })
|
9
|
+
], callback);
|
10
|
+
};
|
11
|
+
|
12
|
+
exports.down = function(db, callback) {
|
13
|
+
async.series([
|
14
|
+
db.removeColumn.bind(db, 'selected_files', 'method'),
|
15
|
+
db.removeColumn.bind(db, 'selected_files', 'uri')
|
16
|
+
], callback);
|
17
|
+
};
|
data/server/package.json
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
{
|
2
|
+
"name": "automock",
|
3
|
+
"devDependencies": {
|
4
|
+
"async": "^1.5.1",
|
5
|
+
"babel": "^6.1.18",
|
6
|
+
"babel-cli": "^6.2.0",
|
7
|
+
"babel-core": "^6.3.26",
|
8
|
+
"babel-preset-es2015": "^6.1.18",
|
9
|
+
"babel-preset-react": "^6.3.13",
|
10
|
+
"babelify": "^7.2.0",
|
11
|
+
"browserify": "^12.0.1",
|
12
|
+
"coffee-script": "^1.10.0",
|
13
|
+
"db-migrate": "^0.9.23",
|
14
|
+
"gulp": "^3.9.0",
|
15
|
+
"gulp-sass": "^2.1.1",
|
16
|
+
"http-proxy": "^1.12.0",
|
17
|
+
"mocha": "^2.3.4",
|
18
|
+
"power-assert": "^1.2.0",
|
19
|
+
"redux-devtools": "^3.0.1",
|
20
|
+
"run-sequence": "^1.1.5",
|
21
|
+
"supertest": "^1.1.0",
|
22
|
+
"vinyl-source-stream": "^1.1.0"
|
23
|
+
},
|
24
|
+
"dependencies": {
|
25
|
+
"body-parser": "^1.14.2",
|
26
|
+
"bootstrap": "^4.0.0-alpha.2",
|
27
|
+
"express": "^4.13.3",
|
28
|
+
"immutable": "^3.7.6",
|
29
|
+
"object-assign": "^4.0.1",
|
30
|
+
"react": "^0.14.3",
|
31
|
+
"react-dom": "^0.14.3",
|
32
|
+
"react-redux": "^4.0.5",
|
33
|
+
"recursive-readdir": "^1.3.0",
|
34
|
+
"redux": "^3.0.5",
|
35
|
+
"redux-logger": "^2.3.1",
|
36
|
+
"redux-thunk": "^1.0.2",
|
37
|
+
"sequelize": "^3.15.1",
|
38
|
+
"sqlite3": "^3.1.1",
|
39
|
+
"superagent": "^1.6.1",
|
40
|
+
"underscore": "^1.8.3"
|
41
|
+
},
|
42
|
+
"scripts": {
|
43
|
+
"test": "mocha --require babel-core/register --recursive test",
|
44
|
+
"build": "gulp build",
|
45
|
+
"watch": "gulp watch"
|
46
|
+
},
|
47
|
+
"repository": {
|
48
|
+
"type": "git",
|
49
|
+
"url": "git+https://github.com/joe-re/automock.git"
|
50
|
+
},
|
51
|
+
"keywords": [],
|
52
|
+
"author": "",
|
53
|
+
"license": "MIT",
|
54
|
+
"bugs": {
|
55
|
+
"url": "https://github.com/joe-re/automock/issues"
|
56
|
+
},
|
57
|
+
"homepage": "https://github.com/joe-re/automock#readme"
|
58
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"description":"description","method":"GET","uri":"/api/v1/users","status": "200","response_body":"{\"users\":[{\"username\":\"sample\",\"email\":\"sample@ggg.com\"}]}"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"description":"api description","method":"POST","uri":"/api/v1/users","status": "201","response_body":"{\"users\":[{\"username\":\"sample\",\"email\":\"sample@ggg.com\"}]}"}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
process.env.AUTOMOCK_DATA_PATH=__dirname + '/../fixtures/mock';
|
2
|
+
process.env.NODE_ENV='test';
|
3
|
+
|
4
|
+
const sequelize = require('../../app/db/sequelize');
|
5
|
+
const SelectedFile = require('../../app/models/selected_file');
|
6
|
+
|
7
|
+
before(function() {
|
8
|
+
const execSync = require('child_process').execSync;
|
9
|
+
execSync('node ./node_modules/db-migrate/bin/db-migrate up --config app/db/database.json -e test');
|
10
|
+
});
|
11
|
+
|
12
|
+
beforeEach(function () {
|
13
|
+
SelectedFile.truncate();
|
14
|
+
});
|
15
|
+
|
16
|
+
after(function() {
|
17
|
+
sequelize.
|
18
|
+
getQueryInterface().
|
19
|
+
dropAllTables();
|
20
|
+
});
|
@@ -0,0 +1,34 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
require('./common_hooks');
|
4
|
+
const request = require('supertest');
|
5
|
+
|
6
|
+
let server;
|
7
|
+
describe('GET /mock_files', function () {
|
8
|
+
beforeEach(function () {
|
9
|
+
server = require('./../../app/index');
|
10
|
+
});
|
11
|
+
it('receives mock_files and 200', function testSlash(done) {
|
12
|
+
request(server).
|
13
|
+
get('/mock_files').
|
14
|
+
expect(200, [
|
15
|
+
{
|
16
|
+
description: 'api description',
|
17
|
+
method: 'POST',
|
18
|
+
name: 'test.json',
|
19
|
+
status: '201',
|
20
|
+
response_body: '{\"users\":[{\"username\":\"sample\",\"email\":\"sample@ggg.com\"}]}',
|
21
|
+
uri: '/api/v1/users'
|
22
|
+
},
|
23
|
+
{
|
24
|
+
description: 'description',
|
25
|
+
method: 'GET',
|
26
|
+
name: 'api/v1/api_test.json',
|
27
|
+
status: '200',
|
28
|
+
response_body: '{\"users\":[{\"username\":\"sample\",\"email\":\"sample@ggg.com\"}]}',
|
29
|
+
uri: '/api/v1/users'
|
30
|
+
}
|
31
|
+
], done);
|
32
|
+
});
|
33
|
+
});
|
34
|
+
|