New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fixed shouldOverwrite is never called when rename target exists #12543
Conversation
Thanks for making a pull request to jupyterlab! |
Thanks for submitting your first pull request! You are awesome! 🤗 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ephes
I added some pointers on how to use proper Jest mock (the JS test library used by JupyterLab).
Let me know if you need more help.
import { DocumentManager, renameFile } from '../src'; | ||
|
||
function shouldOverwriteFalse(path: string): Promise<boolean> { | ||
return Promise.resolve(false); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are using Jest for testing. The documentation for mocking is there.
Something like the following should to the trick
import { DocumentManager, renameFile } from '../src'; | |
function shouldOverwriteFalse(path: string): Promise<boolean> { | |
return Promise.resolve(false); | |
} | |
import { DocumentManager, renameFile } from '../src'; | |
jest.mock('../src', () => { | |
const originalModule = jest.requireActual('../src'); | |
//Mock the shouldOverwrite | |
return { | |
__esModule: true, | |
...originalModule, | |
shouldOverwrite: jest.fn().mockReturnValue(false), | |
}; | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I didn't know about mocking partials, which seems to be very useful. But in this case it doesn't work, because it only mocks shouldOverwrite if you call it from the test. But it's called from within dialog.ts
and stays unmocked there. A lot of people seem to have run into this (even found a comment from myself 2 years ago in this thread 😬).
I tried option 1 but ended up with the typescript error message TypeError: Cannot redefine property: shouldOverwrite
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for trying that path @ephes
I look a bit more at the code of shouldOverwrite
. And as this is triggering a dialog, you could make use of the test helper dimissDialog
(as you are emulating a rejection). See that example:
const dismiss = dismissDialog(); |
Something like the following code should do the trick:
await Promise.all([dismissDialog(), renameFile(
manager,
'foo.ipynb',
'bar.ipynb'
)]).catch(error => {
// error should be 'File not renamed'
expect(error).not.toBe(alreadyExistsError);
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow, this is much better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ephes
@meeseeksdev please backport to 3.4.x |
…hen rename target exists
Benchmark reportThe execution time (in milliseconds) are grouped by test file, test type and browser. The mean relative comparison is computed with 95% confidence. Results table
Changes are computed with expected as reference. |
… target exists (#12565) Co-authored-by: Jochen Wersdörfer <jochen-github@wersdoerfer.de>
Thank you too @fcollonval :) |
References
Fix #12541
Code changes
The main fix is to not look at
error.message
to determine if the error was cause by an already existing notebook with this name buterror.response.status
.I also added 3 tests to make sure
shouldOverwrite
is called whenerror.response.status
is409
. And that other errors are re-thrown and don't causeshouldOverwrite
to be called.I'm a javascript newbie and had trouble to mock
shouldOverwrite
. Therefore I added a callback parameter torenameFile
to be able to pass a mock callback in the tests. But probably somebody with more javascript experience should have a look at the tests, there's probably an easier way.User-facing changes
Nothing really changed besides the missing dialog is now shown.
Backwards-incompatible changes
Edited to link the issue