This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

ConnectButton Tests using Jest - #378

Merged
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test
Feb 22, 2018
Merged

ConnectButton Tests using Jest#378
shannonlal merged 9 commits into
plotly:masterfrom
shannonlal:Issue-362-ConnectButton-Test

Conversation

@shannonlal

Copy link
Copy Markdown
Contributor

The following is a first stab at the unit testing the front end components using Jest. The goal is to help document the front end and resolve some of the UI issues. I am hoping by breaking this down into small Unit Tests it will make it easy to see the expected behaviour of each of the components. I welcome any and all comments for this.

@n-riesco If you get a chance could you have a look at this. Are you the best person to review this or should I run this by someone else?

}

/**
* Will check whether connection requests are equal to or greater then 400

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

than

* Will check whether connection requests are equal to or greater then 400
* @returns {boolean} true if connection error
*/
isConnectionError() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about connectionFailed?

* @returns {boolean} true if status is loading
*/
loadingStatus() {
return (isLoading(this.props.connectRequest.status) || isLoading(this.props.saveConnectionsRequest.status));

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

isLoading is only used here. I'd get rid of isLoading and rename loadingStatus to isLoading (it's confusing to have two function so similar in name and purpose)

* Checks whether the connection request status (HTTP) is greater or equal to 200 and less then 300
* @returns {boolean} true if connection request status >=200 and <300
*/
isValidConnection() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How about isConnected?

* Checks whether connection status is defined
* @returns {boolean} true if connection status is invalid
*/
isInvalidConnectionStatus() {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This one if weird. The function name implies that it checks whether the connection failed, but the code checks we're still waiting for a response to out connection request.

I also suspect this may be the source of bug #372 (see my comment below; I'll test if I'm right).

Comment threadpackage.json Outdated
"style-loader": "^0.19.0",
"webpack": "^3.8.1",
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we keep the dependencies in alphabetical order

@@ -0,0 +1,289 @@
jest.dontMock('../../../../../app/components/Settings/ConnectButton/ConnectButton.react.js');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are we affected by this issue with unmocked imports?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No. Jest mocks modules by default. I specify that it should not mock this component so that we can test the component. This is a pattern that I have used before on other projects and seems to have worked

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I understand. What I meant is whether we need to use unmock instead.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

@n-riesco It looks like unmock is now the recommended approach. Here is a link to a link on SO (https://stackoverflow.com/questions/36571357/difference-between-unmock-and-dontmock-in-jest). I have updated the test and and added it to the PR

Comment threadpackage.json Outdated
"jest":"^22.3.0",
"babel-jest":"latest",
"react-test-renderer":"latest",
"react-addons-test-utils": "latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we don't need react-addons-test-utils, as we're using React 15.5

Comment threadpackage.json Outdated
"yamljs": "^0.3.0"
"yamljs": "^0.3.0",
"jest":"^22.3.0",
"babel-jest":"latest",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pin to major version number

describe('Connect Button Tests', () => {

beforeAll(() => {
// Setup the test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

import Adapter from 'enzyme-adapter-react-15';

describe('Connect Button Tests', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tests

configure({ adapter: new Adapter() });
});

it('Should verify Connection Request Error', () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

s/Should/should/ so that it reads "Connect Button should verify Connection Request Error".

Or even better "Connect Button should check for connection errors"

});

it('Should verify Connection Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this check (import would've failed before)

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

no need for this test

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd tighten this test: .toBe(true)

});

it('Should verify Save Connections Request Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify Save Connections Request without Error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().isConnectionError()).toBeFalsy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(false)

});

it('Should verify loading connection request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify loading save connections request loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

/>);

expect(button).toBeDefined();
expect(button.instance().loadingStatus()).toBeTruthy();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

toBe(true)

});

it('Should verify not loading status', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

});

it('Should connected button with error due to connect request error', () => {
expect(ConnectButton).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

editMode={editMode}
/>);

expect(button).toBeDefined();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✂️

* The following is the Connect Button which triggers the connection
* @param {function} connect - Connect function
* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [connectRequest.error]

* @param {object} connectRequest - Connection Request
* @param {number || string} connectRequest.status -- 400 or loading
* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also * @param {Error} [saveConnectionsRequest.error]


const isLoading = (status) => status === 'loading';

/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This JSDoc comment should go above static propTypes

* @param {object} saveConnectionsRequest - Saved Connection Request
* @param {number || string } saveConnectionsRequest.status -- 400 or loading
* @param {boolean} editMode - Enabled if Editting credentials
* @returns {ConnectButton}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@returns {ConnectButton}

buttonText = 'Connected';
}
} else if (!connectRequest.status) {
} else if (this.isInvalidConnectionStatus()) {

@n-riescon-riescoFeb 19, 2018

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The return below wasn't properly indented. Could you fix it, please?

@n-riesco

n-riesco commented Feb 19, 2018

Copy link
Copy Markdown
Contributor

@shannonlal A very comprehensive set of specs!

I find the logic in render() difficult to follow. How about something like this?

/** * @returns {boolean} true if waiting for a response to a connection request */isConnecting(){returnthis.props.connectRequest.status==='loading';}/** * @returns {boolean} true if successfully connected to database */isConnected(){conststatus=Number(this.props.connectRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */connectionFailed(){returnNumber(this.props.connectRequest.status)>=400;}/** * @returns {boolean} true if waiting for a response to a save request */isSaving(){returnthis.props.saveConnectionsRequest.status==='loading';}/** * @returns {boolean} true if connection has been saved */isSaved(){conststatus=Number(this.props.saveConnectionsRequest.status);return(status>=200||status<300);}/** * @returns {boolean} true if successfully connected to database */saveFailed(){returnNumber(this.props.saveConnectionsRequest.status)>=400;}render(){const{
connect,
connectRequest,
saveConnectionsRequest,
editMode
}=this.props;letbuttonText;letbuttonClick=()=>{};leterror=null;if(!editMode){buttonText='Connected';}elseif(this.isConnecting()||this.isSaving()){buttonText='Connecting...';}elseif(this.connectionFailed()||this.saveFailed()){buttonText='Connect';buttonClick=connect;constconnectErrorMessage=pathOr(null,['content','error'],connectRequest);constsaveErrorMessage=pathOr(null,['content','error','message'],saveConnectionsRequest);constgenericErrorMessage='Hm... had trouble connecting.';consterrorMessage=connectErrorMessage||saveErrorMessage||genericErrorMessage;error=<divclassName={'errorMessage'}>{errorMessage}</div>;}elseif(this.isConnected()&&this.isSaved()){buttonText='Save changes';buttonClick=connect;}else{buttonText='Connect';buttonClick=connect;}return(<divclassName={'connectButtonContainer'}><buttonid="test-connect-button"onClick={buttonClick}>{buttonText}</button>{error}</div>);}

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I think I fixed most of the changes you recommended. I had to modify the logic flow a little bit for the Button Connect to get it to work but I tested it and it seems to be working. Please have a look and let me know if you think this makes sense

Merge branch 'upstream-master' into Issue-362-ConnectButton-Test
@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

  1. Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

} else {

} else if (this.isConnected()) {
buttonText = 'Save changes';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

'Save changes' should be shown only after we have successfully connected to a DB (i.e. this.isConnected() is true) and we have pressed Edit Credentials (i.e. editMode is true).

Also, see that editMode is false only if we have successfully connected to a DB (i.e. if editMode is false, then this.isConnected() is true). This is the reason why I wrote first if (!editMode) {...}`.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

I don't think your logic flow worked for the Connect Button. I will revisit this and step through it to get it working again. Keep you posted.

What was the mistake?

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal

It looks like there is an issue with the ElasticSearch spec. I don't think it is related to anything I committed in. Here is the error:

Elasticsearch: connect returns a list of indices:

Would you mind having a look at the error to let me know what might be causing the issue

The tests are failing because authentication is now enabled in the elasticsearch server.

I've opened PR #382 to disable the tests in CircleCI against the elasticsearch server (we still have the tests against the mocked servers).

@n-riesco

Copy link
Copy Markdown
Contributor

Have you seen these comments: 1 and 2?

Do you prefer instead:?

* @param {object} [connectRequest.error]
* @param {string} [connectRequest.error.message] Connection error message

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I did some more testing and understand how the edit button should be working. I implemented the Connect Button as you suggested and modified the Jest Test cases to work accordingly. If you have a chance to look this over I would appreciate it.

@n-riesco

Copy link
Copy Markdown
Contributor

@shannonlal LGTM 💃

Please, wait until #382 is merged, so that we can test this PR on CircleCI.

@shannonlal

Copy link
Copy Markdown
ContributorAuthor

@n-riesco I saw that #382 was just merged. If tests pass tonight I will merge this PR in.

@shannonlal
shannonlal merged commit 854e6d5 into plotly:masterFeb 22, 2018
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@shannonlal@n-riesco