Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add url interception without listening #133

Merged
merged 59 commits into from
Jul 23, 2018

Conversation

amitmbee
Copy link
Contributor

@amitmbee amitmbee commented Jun 15, 2018

  • Adds ability to intercept requests without explicitly having to listen to them

Add URL Modal:

screen shot 2018-06-18 at 12 34 31 pm

After the URL is added for interception:

screen shot 2018-06-18 at 12 34 41 pm

screen shot 2018-06-18 at 12 34 55 pm

  • Add ability to edit URL's inline by changing the URL fields

edit_url

  • more screenshots (Design by @cgirish )

screen shot 2018-07-13 at 12 37 06 pm

screen shot 2018-07-13 at 7 21 50 pm

screen shot 2018-07-13 at 7 22 01 pm

screen shot 2018-07-13 at 7 22 14 pm

screen shot 2018-07-13 at 7 22 41 pm

@amitmbee amitmbee requested a review from revathskumar June 15, 2018 11:54
Copy link
Contributor

@revathskumar revathskumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attach some screenshots and add test cases.

.find("button")
.at(0)
.hasClass("button-start-listening")
).toEqual(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use toBeTruthy()

type="text"
name="modal-url"
id="url-input-modal"
onChange={e => props.updateModalUrl(e.target.value)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onChange={props.updateModalUrl}.
updateModalUrl will receive event object as first argument and do the e.target.value inside updateModalUrl.

Advantage: avoiding function declaration on reach render.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had missed this point^^. Thanks for reminding. Better to use this pattern everytime we pass event/event properties

export const AddRuleModal: React.SFC<{}> = props => {
return (
<Modal show={props.showModal} handleClose={props.handleClose}>
<label htmlFor="modal-url">URL</label>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for should be associated with id not name

<input
className="form-control"
type="text"
name="modal-url"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name like modal-url can be better. no need to have modal in context for the name of this input.
better will be request_url.

avoid - (hypen) for names.

id="url-input-modal"
onChange={e => props.updateModalUrl(e.target.value)}
/>
<label htmlFor="modal-method">Method</label>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for should be associated with id not name

defaultValue="GET"
value={props.modalMethod}
className="modal-method"
onChange={e => props.updateModalMethod(e.target.value)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onChange={props.updateModalUrl}. for the same reason above.

@@ -0,0 +1,14 @@
import * as React from "react";
export const Modal = ({ handleClose, show, children }) => {
const showHideClassName = show ? "modal display-block" : "modal display-none";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to switch the css classes.
Instead either we render or no render the component.

@@ -28,6 +31,11 @@ const isChromeUrl = (url: string) => {
return CHROME_URL_REGEX.test(url);
};
export class Popup extends React.Component<POPUP_PROPS & DispatchProps, {}> {
state = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to redux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since its a container component and the state defined here is used just to show/hide the modal window(not much complication regarding state involved), should we move this to redux ?

@revathskumar
Copy link
Contributor

@cgirish Can you take a look into this for a better design?
Should we really need to go with Modal any alternate approach?

@Amit-MB if we are deciding to go with Modal we need a backdrop.

Copy link
Contributor

@revathskumar revathskumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need validation for the user input URL.

expect(wrapper.find("Modal")).toHaveLength(1);
});
test("Contains a input, select and a button element", () => {
expect(wrapper.find("input")).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, this won't work. wrapper.find("input") always returns an object. so we have to check for the length to make sure the element exists

showModal: false,
modalMethod: "GET",
addRequest: jest.fn(),
modalUrl: "www.codemancers.com",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't modal data based on UI. what if tomorrow we decided to not go with Modal?
the name become meaningless and since data is used everywhere, renaming will impact a lot of places.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. ^^ that makes sense. Will change names.

return { type: INITIALISE_DEFAULTS, payload: { currentTab, currentUrl, interceptStatus } };
return {
type: INITIALISE_DEFAULTS,
payload: { currentTab, currentUrl, interceptStatus }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we already have initialState, why we need to send the payload?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although initialState is defined in the reducer, we dont have any data about the currentTabId, currentTabUrl. Therefore, I dispatch this action as soon as the popup is opened so that we can store information based on tabId. Better to rename this as currentTabId, currentTabUrl.

I also dispatch interceptStatus with empty string so that after each time the popup is opened, the Success or Error message gets erased.

@@ -0,0 +1,16 @@
import * as React from "react";
export const Modal = ({ handleClose, show, children }) => {
if (!show) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition shouldn't be a part of this component.

{showModal && <Modal {...props} />}

@amitmbee amitmbee requested a review from cgirish June 29, 2018 05:24
@revathskumar
Copy link
Contributor

@cgirish @Amit-MB Are we going forward with Modal itself? Or any better approach we are looking?

@revathskumar
Copy link
Contributor

@Amit-MB Also please put the error message of URL validaiton near the text box itself. Don't put those error message in global error.

@amitmbee
Copy link
Contributor Author

amitmbee commented Jul 5, 2018

I have also added the ability to edit url's in this PR (see 4th screenshot in PR description). Let's for @girish and check if there are any better design approaches.

@revathskumar , error message of URL validaiton near the text box itself,good idea than showing as global error, i will make necessary changes required and push 👍

@amitmbee amitmbee force-pushed the Add-url-interception-without-listening branch from 47e30fe to 8a2d9a9 Compare July 5, 2018 10:12
updateAddRequestMethod: (value: string, tabId: number) => void;
updateAddRequestUrl: (value: string, tabId: number) => void;
}
export const AddRuleModal: React.SFC<AddRuleModalProps> = props => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it extend from Component.
As already discussed, if we need instance methods never use Function component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are using functions(defined internally) and not methods or lifecycle methods as well. Do we really need a stateful component here ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

functions defining in render method is not good, this is similar to it.
This will define all the methods again and again when each time it renders.

By using Component doesn't mean stateful. we are not using internal state.

</button>
<button
className="btn btn-primary btn-add-rule"
onClick={() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid inline method and move to instance method.


const handleClose = () => {
//erase the previously set error message on each re-render
props.addRuleErrorNotify(``, props.tabId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why using backticks?

props.addRuleErrorNotify(``, props.tabId);
//reset the url to empty string and request method to "GET"
props.updateAddRequestUrl(``, props.tabId);
props.updateAddRequestMethod(`GET`, props.tabId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backticks

//erase the previously set error message on each re-render
props.addRuleErrorNotify(``, props.tabId);
//reset the url to empty string and request method to "GET"
props.updateAddRequestUrl(``, props.tabId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backticks

updateInterceptorStatus?: (tabId: number) => void;
fetchResponse: React.MouseEvent<HTMLSpanElement>;
handleSwitchToggle: any;
handleChangeUrl: any;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicate?

@revathskumar
Copy link
Contributor

This will fix the failing test

    test ('on clear button click, should trigger props.clearFields', () => {
      let localProps = createTestProps ();
      wrapper = mount (<Popup {...localProps} />);
      wrapper.find ('.btn-clear').last ().simulate ('click');
      expect (localProps.clearFields).toBeCalledWith (1);
    });

Copy link
Contributor

@revathskumar revathskumar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@revathskumar revathskumar merged commit 154edbd into master Jul 23, 2018
@revathskumar revathskumar deleted the Add-url-interception-without-listening branch July 23, 2018 08:12
@revathskumar revathskumar mentioned this pull request Jul 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants