-
Notifications
You must be signed in to change notification settings - Fork 899
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
RUN-2307 unit tests for edit project file #9084
Changes from 2 commits
e39d1da
daaeff5
b2aa351
d57d5b4
7662d52
71be35b
fd2910e
270021e
3b6970d
36984ad
972c418
eddb439
8e3da89
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,140 @@ | ||||||
import { mount } from "@vue/test-utils"; | ||||||
import EditProjectFile from "./EditProjectFile.vue"; | ||||||
import * as editProjectFileService from "./editProjectFileService"; | ||||||
|
||||||
jest.mock("@/app/components/readme-motd/editProjectFileService", () => ({ | ||||||
getFileText: jest.fn(() => | ||||||
Promise.resolve({ | ||||||
success: true, | ||||||
contents: "sample file content", | ||||||
}), | ||||||
), | ||||||
saveProjectFile: jest.fn(() => | ||||||
Promise.resolve({ | ||||||
success: true, | ||||||
message: "File saved successfully.", | ||||||
}), | ||||||
), | ||||||
})); | ||||||
|
||||||
jest.mock("@/library/rundeckService", () => ({ | ||||||
getRundeckContext: jest.fn().mockReturnValue({ | ||||||
rundeckClient: { | ||||||
getFileText: jest.fn().mockResolvedValue({ | ||||||
filename: "readme.md", | ||||||
success: true, | ||||||
contents: "Some content", | ||||||
rdBase: "http://localhost:4440", | ||||||
}), | ||||||
saveProjectFile: jest.fn().mockResolvedValue({ | ||||||
success: true, | ||||||
message: "File saved successfully.", | ||||||
}), | ||||||
}, | ||||||
rdBase: "http://localhost:4440", | ||||||
}), | ||||||
url: jest.fn().mockReturnValue("http://localhost:4440"), | ||||||
})); | ||||||
let wrapper; | ||||||
const mountEditProjectFile = async (props = {}) => { | ||||||
wrapper = mount(EditProjectFile, { | ||||||
props: { | ||||||
filename: "readme.md", | ||||||
project: "default", | ||||||
authAdmin: true, | ||||||
...props, | ||||||
}, | ||||||
global: { | ||||||
mocks: { | ||||||
$t: (msg) => msg, | ||||||
}, | ||||||
}, | ||||||
}); | ||||||
}; | ||||||
|
||||||
describe("EditProjectFile", () => { | ||||||
beforeEach(async () => { | ||||||
await mountEditProjectFile(); | ||||||
}); | ||||||
|
||||||
afterEach(() => { | ||||||
jest.clearAllMocks(); | ||||||
}); | ||||||
|
||||||
it.each([ | ||||||
["readme.md", "edit.readme.label"], | ||||||
["motd.md", "edit.motd.label"], | ||||||
])("renders the correct title for %s", async (filename, expectedTitle) => { | ||||||
await mountEditProjectFile({ filename }); | ||||||
expect(wrapper.find('[data-test-id="title"]').text()).toContain( | ||||||
expectedTitle, | ||||||
); | ||||||
}); | ||||||
|
||||||
it("renders file content when getFileText method returns successfully", async () => { | ||||||
await wrapper.vm.$nextTick(); | ||||||
expect(wrapper.vm.fileText).toBe("sample file content"); | ||||||
}); | ||||||
|
||||||
it("handles failure when getFileText method fails", async () => { | ||||||
(editProjectFileService.getFileText as jest.Mock).mockImplementationOnce( | ||||||
() => Promise.reject(new Error("Failed to fetch file")), | ||||||
); | ||||||
wrapper.vm.notifyError = jest.fn(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to override |
||||||
await wrapper.vm.getFileText(); | ||||||
expect(wrapper.vm.notifyError).toHaveBeenCalledWith("Failed to fetch file"); | ||||||
}); | ||||||
|
||||||
it("handles failure when user edits the file and fails to save it", async () => { | ||||||
(editProjectFileService.saveProjectFile as jest.Mock).mockRejectedValue( | ||||||
new Error("Failed to save file"), | ||||||
); | ||||||
wrapper.vm.notifyError = jest.fn(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing here, please use spyOn |
||||||
wrapper.vm.fileText = "new content"; | ||||||
await wrapper.find('[data-test-id="save"]').trigger("click"); | ||||||
expect(wrapper.vm.notifyError).toHaveBeenCalledWith("Failed to save file"); | ||||||
}); | ||||||
|
||||||
it("handles success when user edits the file and saves it", async () => { | ||||||
wrapper.vm.fileText = "new content"; | ||||||
await wrapper.find('[data-test-id="save"]').trigger("click"); | ||||||
expect( | ||||||
editProjectFileService.saveProjectFile as jest.Mock, | ||||||
).toHaveBeenCalledWith("default", "readme.md", "new content"); | ||||||
}); | ||||||
|
||||||
it("displays admin specific message and configuration link when user is an admin", async () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
await mountEditProjectFile({ | ||||||
displayConfig: ["none"], | ||||||
}); | ||||||
const footerText = wrapper.find(".card-footer").text(); | ||||||
expect(footerText).toContain("file.warning.not.displayed.admin.message"); | ||||||
expect(wrapper.find(".card-footer a").text()).toBe( | ||||||
"project.configuration.label", | ||||||
); | ||||||
}); | ||||||
|
||||||
it("displays non-admin specific message when user is not an admin", async () => { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
await mountEditProjectFile({ | ||||||
authAdmin: false, | ||||||
displayConfig: ["none"], | ||||||
}); | ||||||
await wrapper.vm.$nextTick(); | ||||||
expect(wrapper.text()).toContain( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please use a data-test-id instead of using wrapper.text() |
||||||
"file.warning.not.displayed.nonadmin.message", | ||||||
); | ||||||
}); | ||||||
it("does not allow non-admin user to save the file", async () => { | ||||||
await mountEditProjectFile({ authAdmin: false }); | ||||||
expect(wrapper.find('[data-test-id="save"]').exists()).toBe(false); | ||||||
}); | ||||||
it("does not allow non-admin user to edit the file", async () => { | ||||||
await mountEditProjectFile({ authAdmin: false }); | ||||||
expect(wrapper.find('[data-test-id="editor"]').exists()).toBe(false); | ||||||
}); | ||||||
|
||||||
//TODO: working on this one | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @smartinellibenedetti Can you please look at it? This one not working. Thanks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you trigger actions that require the UI to re-render, remember to do a:
before trying to assert the values |
||||||
// it("does not change file content when user cancels the edit", async () => { | ||||||
// | ||||||
// }); | ||||||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
<div class="content"> | ||
<div id="layoutBody"> | ||
<div class="title"> | ||
<span class="text-h3"> | ||
<span class="text-h3" data-test-id="title"> | ||
<template v-if="filename === 'readme.md'"> | ||
<i class="fas fa-file-alt"></i> | ||
{{ $t("edit.readme.label") }} | ||
|
@@ -45,25 +45,30 @@ | |
</details> | ||
</div> | ||
<ace-editor | ||
v-if="authAdmin" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Important, the behaviour of the components shouldn't change while writing tests, therefore please undo the changes on lines 48 and 68. When the user doesn't have permissions to create/edit files, the component will render strings (whose logic is defined inside the block that starts with |
||
v-model="fileText" | ||
:soft-wrap-control="true" | ||
height="250" | ||
width="100%" | ||
lang="markdown" | ||
:read-only="false" | ||
data-test-id="ace-editor" | ||
/> | ||
</div> | ||
<div class="card-footer"> | ||
<button | ||
type="button" | ||
class="btn btn-default reset_page_confirm" | ||
data-test-id="cancel" | ||
@click="createProjectHomeLink" | ||
> | ||
Cancel | ||
</button> | ||
<button | ||
v-if="authAdmin" | ||
type="submit" | ||
class="btn btn-cta reset_page_confirm" | ||
data-test-id="save" | ||
@click="saveProjectFile" | ||
> | ||
Save | ||
|
@@ -127,6 +132,7 @@ export default defineComponent({ | |
data() { | ||
return { | ||
fileText: "", | ||
|
||
markdownSectionOpen: false, | ||
errorMsg: "", | ||
}; | ||
|
@@ -138,6 +144,7 @@ export default defineComponent({ | |
}, | ||
mounted() { | ||
this.getFileText(); | ||
this.originalFileText = this.fileText; | ||
}, | ||
methods: { | ||
async saveProjectFile() { | ||
|
@@ -185,6 +192,7 @@ export default defineComponent({ | |
async getFileText() { | ||
try { | ||
const response = await getFileText(this.project, this.filename); | ||
|
||
if (response.success) { | ||
this.fileText = response.contents; | ||
} | ||
|
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.
Could you please change this test to assert instead that the HTML rendered by ace-editor has this string inside of it?