Skip to content

Commit

Permalink
Release v1.1.2 (#167)
Browse files Browse the repository at this point in the history
* Fix default options for remote connections

* feat(add scenario): Add ability to create a new scenario by pressing enter in new scenario dialog

#160

* fix(Import): Fix mocked request overriding when importing a scenario with new mocks

If you exported each mock in a scenario to its own file it currently would override the existing

mocks in that scenario, this makes sure that the scenarios are merged properly

fixes #152

* feat(Mock Editing): Add ability to give a name to a mock

Now those that have many mocks can name these mocks to better allow them to understand which

requests went out

Fixes #154

* feat(Mock editing): Allow to duplicate a mocked request

You can now duplicate a mocked request by clicking the duplicate button, editing the request and

saving it. Until you save this request it won't be saved

Fixes #155

* refactor(Mock name): Use mock name everywhere and redesign layout to fit it in edit screen

* Update version in package.json
  • Loading branch information
morsdyce authored Jan 23, 2017
1 parent c531e06 commit 248ff2e
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 35 deletions.
5 changes: 3 additions & 2 deletions lib/api/models/mocked-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { UrlUtils } from 'api/utils/url';

export class MockedRequest {

constructor({ id = uuid.v4(), active = true, method, url, headers, params, response }) {
Object.assign(this, { id, active, method, url, headers, params, response });
constructor({ id = uuid.v4(), active = true, method, url, headers, params, response, name }) {
Object.assign(this, { id, active, method, url, headers, params, response, name });
}

getRequestHash() {
Expand All @@ -19,6 +19,7 @@ export class MockedRequest {
this.response.status = request.response.status;
this.response.delay = request.response.delay;
this.response.body = request.response.body;
this.name = request.name;
this.params = request.params;
this.url = request.url;
this.headers = Object.assign({}, request.headers);
Expand Down
3 changes: 2 additions & 1 deletion lib/api/models/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ export class Request {
delete this.mock;
}

update(url) {
update(url, name) {
this.url = url;
this.name = name;
this.requestHash = this.buildRequestHash(this.params);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/api/models/scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class Scenario {
updateMockedRequest(mockRequestId, request) {
Requests.capturedRequests
.filter((capturedRequest) => get(capturedRequest, 'mock.id') === mockRequestId)
.forEach((capturedRequest) => Requests.updateUrl(capturedRequest.id, request.url));
.forEach((capturedRequest) => Requests.update(capturedRequest.id, request.url, request.name));

this.findMockedRequestById(mockRequestId).update(request);
}
Expand Down
6 changes: 2 additions & 4 deletions lib/api/remote.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import Interceptor from 'api/interceptor';
import { API } from 'api';

function connect(options = { hostname: 'localhost', port: 5000 }) {
function connect({ hostname = 'localhost', port = 5000 } = {}) {
API.setMode('remote');
new Interceptor('remote', options);
new Interceptor('remote', { hostname, port });

return API;
}

export default connect;


4 changes: 2 additions & 2 deletions lib/api/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default class Requests {
return capturedRequests.filter((request) => request.id === id)[0];
}

static updateUrl(id, url) {
this.getById(id).update(url);
static update(id, url, name) {
this.getById(id).update(url, name);
}
}
6 changes: 5 additions & 1 deletion lib/api/scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import uuid from 'uuid';
import flatten from 'lodash/flatten';
import isObject from 'lodash/isObject';
import cloneDeep from 'lodash/cloneDeep';
import merge from 'lodash/merge';
import uniqBy from 'lodash/uniqBy';

export class Scenarios {

Expand Down Expand Up @@ -164,7 +166,9 @@ export class Scenarios {
const existingScenario = this.getById(scenario.id);

if (existingScenario) {
Object.assign(existingScenario, scenario);
const mockedRequests = uniqBy([...existingScenario.mockedRequests, ...scenario.mockedRequests], 'id');
scenario.mockedRequests = mockedRequests;
merge(existingScenario, scenario);
} else {
this.scenarios.push(new Scenario(scenario));
}
Expand Down
5 changes: 3 additions & 2 deletions lib/ui/components/modals/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ let styles = {
`
};

const mockOption = ({ method, url, params }) => (
const mockOption = ({ method, name, url, params }) => (
<div>
<p style={{ margin: 0 }}>{method} ({url})</p>
<p style={{ margin: 0 }}>{method} ({ name || url})</p>
<p style={{ margin: 0 }}>{params}</p>
</div>
);
Expand Down Expand Up @@ -119,6 +119,7 @@ export class ExportModal extends Component {
value: mockedRequest.id,
method: mockedRequest.method,
url: mockedRequest.url,
name: mockedRequest.name,
params: mockedRequest.params
}));

Expand Down
23 changes: 20 additions & 3 deletions lib/ui/components/modals/new-scenario-modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ import TextField from 'material-ui/lib/text-field';

export class NewScenarioModal extends Component {

constructor(props) {
super(props);

this.onKeyUp = this.onKeyUp.bind(this);
}

onKeyUp(event) {
if (event.keyCode === 13) {
this.handleSubmit();
}
}

render() {
const actions = [
<FlatButton
Expand All @@ -28,7 +40,11 @@ export class NewScenarioModal extends Component {
modal={ false }
open={ this.props.open }
onRequestClose={ this.props.onClose }>
<TextField floatingLabelText="Scenario Name" style={{ width: '100%' }} onChange={ this.handleScenarioChange.bind(this) } />
<TextField
floatingLabelText="Scenario Name"
style={{ width: '100%' }}
onChange={ this.handleScenarioChange.bind(this) }
onKeyUp={ this.onKeyUp }/>
</Dialog>
</div>
);
Expand All @@ -38,12 +54,13 @@ export class NewScenarioModal extends Component {
if (this.props.onConfirm) {
this.props.onConfirm(this.state.scenarioName);
}

this.props.onClose();
}

handleScenarioChange(event) {
console.log({ event });
this.setState({ scenarioName: event.target.value });
}

}
}
23 changes: 22 additions & 1 deletion lib/ui/components/request-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class RequestDetails extends Component {
return {
selectedScenario: this.getCurrentScenario(props.mock) || _get(props.scenarios[0], 'id'),
originalScenario: this.getCurrentScenario(props.mock) || _get(props.scenarios[0], 'id'),
name: _get(props.mock, 'name', props.name),
url: _get(props.mock, 'url', props.url),
headers: _get(props.mock, 'headers', props.response.headers),
status: _get(props.mock, 'response.status', props.response.status),
Expand Down Expand Up @@ -66,6 +67,21 @@ class RequestDetails extends Component {
this.props.navigate('scenarios');
}

_handleDuplicate() {
this.props.navigate('request-details', {
method: this.props.method,
name: this.state.name,
url: this.state.url,
headers: this.state.headers,
params: this.state.params,
response: {
delay: this.state.delay,
status: this.state.status,
body: this.state.responseBody
}
});
}

_handleDelete() {
this.props.removeMock(this.state.originalScenario, this.props.mock.id);
this.props.navigate('scenarios');
Expand All @@ -74,6 +90,7 @@ class RequestDetails extends Component {
_handleSave() {
if (this.props.mock && this.state.selectedScenario === this.state.originalScenario) {
this.props.updateMock(this.state.selectedScenario, this.props.mock.id, {
name: this.state.name,
url: this.state.url,
headers: this.state.headers,
params: this.state.params,
Expand All @@ -87,6 +104,7 @@ class RequestDetails extends Component {
this.props.mockRequest(this.state.selectedScenario, {
requestId: this.props.id,
active: true,
name: this.state.name,
url: this.state.url,
method: this.props.method,
headers: this.state.headers,
Expand Down Expand Up @@ -239,11 +257,13 @@ class RequestDetails extends Component {
onSave={ this._handleSave.bind(this) }
onDelete={ this._handleDelete.bind(this) }
onChange={ this._selectScenario.bind(this) }
onDuplicate={ this._handleDuplicate.bind(this) }
scenarios={ scenarios }
mocked={ !!mock }
selectedScenario={ this.state.selectedScenario }/>

<RequestInfo url={ this.state.url }
name={ this.state.name }
method={ method }
params={ params }
status={ this.state.status }
Expand All @@ -252,7 +272,8 @@ class RequestDetails extends Component {
onUrlChange={ this._requestInfoChange.bind(this, 'url') }
onDelayChange={ this._requestInfoChange.bind(this, 'delay') }
onStatusChange={ this._requestInfoChange.bind(this, 'status') }
onToggleRequestParams={ this._toggleShowRequestParams.bind(this) } />
onToggleRequestParams={ this._toggleShowRequestParams.bind(this) }
onNameChange={ this._requestInfoChange.bind(this, 'name') } />


{ this.renderRequestParams() }
Expand Down
17 changes: 6 additions & 11 deletions lib/ui/components/request-details/request-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import RaisedButton from 'material-ui/lib/raised-button';
import Select from 'react-select';

export const RequestActions = ({ onCancel, onSave, onDelete, onChange, scenarios, mocked, selectedScenario }) => {
export const RequestActions = ({ onCancel, onSave, onDelete, onChange, onDuplicate, scenarios, mocked, selectedScenario }) => {

const scenarioList = scenarios.map((scenario) => ({ label: scenario.name, value: scenario.id }));

Expand All @@ -23,16 +23,11 @@ export const RequestActions = ({ onCancel, onSave, onDelete, onChange, scenarios
<RaisedButton label={ saveButtonLabel } primary={ true } onClick={ onSave }/>
</div>

<div className="col-xs-3 col-xs-offset-3">
<div className="row end-xs" style={{ paddingRight: mocked ? '20px' : '0'}}>
<div className="col-xs-6">
<RaisedButton label="Cancel" secondary={ true } onClick={ onCancel }/>
</div>
{ mocked && (
<div className="col-xs-3">
<RaisedButton label="Delete" secondary={ true } onClick={ onDelete }/>
</div>
) }
<div className="col-xs-5 col-xs-offset-1">
<div className="row end-xs" style={{ paddingRight: mocked ? '3px' : '0'}}>
<RaisedButton style={{ margin: '0 5px' }} label="Cancel" secondary={ true } onClick={ onCancel }/>
<RaisedButton style={{ margin: '0 5px' }} label="Duplicate" primary={ true } onClick={ onDuplicate }/>
{ mocked && (<RaisedButton style={{ margin: '0 5px' }} label="Delete" secondary={ true } onClick={ onDelete }/>) }
</div>
</div>
</div>
Expand Down
13 changes: 11 additions & 2 deletions lib/ui/components/request-details/request-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const httpStatusCodes = map(
omit(HttpStatus, 'getStatusText'), (value, key) => ({ value, label: key.replace(/_/g, ' ') })
).sort((a, b) => a.value - b.value);

export const RequestInfo = ({ url, method, status, delay, showRequestParams, onUrlChange, onStatusChange, onDelayChange, onToggleRequestParams }) => {
export const RequestInfo = ({ name, url, method, status, delay, showRequestParams, onUrlChange, onStatusChange, onDelayChange, onToggleRequestParams, onNameChange }) => {

const HttpOption = ({ value, label }) => <div key={ value }>{ value } { label }</div>;
const HttpValue = ({ value, label }) => <div>{value} {label}</div>;
Expand Down Expand Up @@ -45,7 +45,16 @@ export const RequestInfo = ({ url, method, status, delay, showRequestParams, onU
</div>
</div>

<div className="row request-details-status-code">
<div className="row between-xs request-details-status-code">
<div className="col-xs-2">
<TextField
className="request-alias"
hintText="Name"
value={ name }
floatingLabelText="Mock Name"
onChange={ onNameChange }/>
</div>

<div className="col-xs-3">
<p className="http-status-code-label">HTTP Status Code</p>
<Select value={ status }
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/components/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function mockedState(mocked) {
);
}

export const Request = ({ url, method, params, mocked, handleClick}) => (
export const Request = ({ name, url, method, params, mocked, handleClick }) => (
<div onClick={ handleClick } className="cursor-pointer" style={{ position: 'relative', padding: '0 10px 15px' }}>

<div className="row middle-xs">
Expand All @@ -27,7 +27,7 @@ export const Request = ({ url, method, params, mocked, handleClick}) => (
</div>
<div className="row">
<div className="col-xs">
<span style={{ wordBreak: 'break-word'}}>{url}</span>
<span style={{ wordBreak: 'break-word'}}>{ name || url}</span>
</div>
</div>
<div className="row" style={{ color: '#8D8E8E'}}>
Expand Down
2 changes: 2 additions & 0 deletions lib/ui/components/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Paper from 'material-ui/lib/paper';
import Divider from 'material-ui/lib/divider';
import SearchIcon from 'material-ui/lib/svg-icons/action/search';
import _includes from 'lodash/includes';
import get from 'lodash/get';

import {fetch} from 'ui/actions/api';
import {navigate} from 'ui/actions/location';
Expand Down Expand Up @@ -89,6 +90,7 @@ export class Requests extends Component {
return (
<div key={ request.id } style={ styles }>
<Request url={ request.url }
name={ get(request, 'mock.name') }
method={ request.method }
params={ request.params }
mocked={ !!request.mock }
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/components/scenario-overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export class ScenarioOverview extends Component {
</div>
<div className="row" style={{ cursor: 'pointer' }}>
<div className="col-xs" onClick={ () => this.props.editMock({ ...mockedRequest, mock: mockedRequest }) }>
{mockedRequest.url}
{mockedRequest.name || mockedRequest.url}
</div>
</div>
<div className="row" style={{ color: '#8D8E8E'}}>
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/components/scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Scenario extends Component {
<div className="col-xs">
<ListItem
onClick={ this.editMock.bind(this, mockedRequest) }
primaryText={ `${mockedRequest.method} ${mockedRequest.url}`}
primaryText={ `${mockedRequest.method} ${mockedRequest.name || mockedRequest.url}`}
secondaryTextLines={2}
secondaryText={ mockedRequest.params }>
</ListItem>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mimic",
"version": "1.1.1",
"version": "1.1.2",
"description": "Bad ass client side mocking solution",
"main": "dist/mimic.js",
"scripts": {
Expand Down

0 comments on commit 248ff2e

Please sign in to comment.