Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

RUN-2307 unit tests for edit project file #9084

Merged
merged 13 commits into from May 8, 2024

Conversation

jayas006
Copy link
Contributor

@jayas006 jayas006 commented Apr 25, 2024

Is this a bugfix, or an enhancement? Please describe.
This is an enhancement. I have added unit tests for the EditProjectFile.vue component to ensure its functionality and behavior are as expected

Describe the solution you've implemented
I have written a series of unit tests using Jest and Vue Test Utils. These tests cover various scenarios including:

  • Rendering the correct title based on the filename.
  • Rendering file content when the getFileText method returns successfully.
  • Handling failure when the getFileText method fails.
  • Handling failure when a user edits the file and fails to save it.
  • Handling success when a user edits the file and saves it.
  • Displaying admin-specific messages and configuration links when the user is an admin.
  • Displaying non-admin specific messages when the user is not an admin.
  • Not allowing non-admin users to save or edit the file.
  • Rendering the Ace Editor.
  • file content does not change when the user cancels the edit

Describe alternatives you've considered

Additional context
These tests will help ensure that the component works correctly and continues to do so as the application evolves.

const aceEditor = wrapper.find('[data-test-id="ace-editor"]');
expect(aceEditor.exists()).toBe(true);
});
//TODO: working on this one
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@smartinellibenedetti Can you please look at it? This one not working. Thanks

Copy link
Contributor

Choose a reason for hiding this comment

The 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:

await wrapper.vm.$nextTick();

before trying to assert the values

@@ -45,25 +45,30 @@
</details>
</div>
<ace-editor
v-if="authAdmin"
Copy link
Contributor

Choose a reason for hiding this comment

The 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 <template v-if="displayConfig.includes('none')">) and the tests should confirm that the right strings are being rendered in such cases.

Copy link
Contributor

@smartinellibenedetti smartinellibenedetti left a comment

Choose a reason for hiding this comment

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

A few things to fix/adjust, but overall looking good.

});

it("renders file content when getFileText method returns successfully", async () => {
expect(wrapper.vm.fileText).toBe("sample file content");
Copy link
Contributor

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?

Comment on lines 128 to 130
it("does not allow non-admin user to edit the file", async () => {
await mountEditProjectFile({ authAdmin: false });
expect(wrapper.find('[data-test-id="my-ace-editor"]').exists()).toBe(false);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please remove this test as the original component doesn't have the behavior of not rendering the editor if the user isn't an admin

Comment on lines 146 to 148
wrapper.vm.createProjectHomeLink = jest.fn(() => {
wrapper.vm.fileText = wrapper.vm.originalFileText;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

When I wrote the ticket description, I was aware that if the user pressed cancel, the text wouldn't be saved and was under the impression that the component would revert back to the the original text, but turns out that upon clicking cancel, the component is triggering a navigation.

So best thing to do is remove lines 146-148, and you trigger click on the cancel button, await the next tick and assert the document location. If the document won't be easy to test, you can replace this line in the component:

document.location = url("project/" + this.project + "/home").href;

to:

window.location = url("project/" + this.project + "/home").href;

document.location and window.location will have the same outcome, but it's easier to test the window.

And then you won't need to assert the content of fileText (line 151)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes I was getting error with the [object object] and when I searched they recommended to use window.location. As I didn't want to change the component. Thanks I will do it

(editProjectFileService.getFileText as jest.Mock).mockImplementationOnce(
() => Promise.reject(new Error("Failed to fetch file")),
);
wrapper.vm.notifyError = jest.fn();
Copy link
Contributor

Choose a reason for hiding this comment

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

no need to override wrapper.vm.notifyError, you can use spyOn instead (https://jestjs.io/docs/jest-object#jestspyonobject-methodname)

(editProjectFileService.saveProjectFile as jest.Mock).mockRejectedValue(
new Error("Failed to save file"),
);
wrapper.vm.notifyError = jest.fn();
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing here, please use spyOn

Comment on lines 119 to 127
it("does not allow non-admin user to save the file", async () => {
await mountEditProjectFile({ authAdmin: false });
wrapper.vm.save = jest.fn();
wrapper.vm.getFileText = jest.fn();

wrapper.find('[data-test-id="save"]').trigger("click");
await wrapper.vm.$nextTick();
expect(wrapper.vm.save).not.toHaveBeenCalled();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

This test is wrong, there's no 'save' method, which is the reason why after the click, it wasn't called.

But checked now the component logic and the API, a non-admin user will be able to save the file, but they won't be able to adjust where the message will be displayed. So safe to delete this test.

).toHaveBeenCalledWith("default", "readme.md", "new content");
});

it("displays admin specific message and configuration link when user is an admin", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
it("displays admin specific message and configuration link when user is an admin", async () => {
it("displays warning message and configuration link when user is an admin and displayConfig value is 'none'", async () => {

);
});

it("displays non-admin specific message when user is not an admin", async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
it("displays non-admin specific message when user is not an admin", async () => {
it("displays warning message and configuration link when user isn't an admin and displayConfig value is 'none'", async () => {

Comment on lines 132 to 142
it("renders the correct strings when user doesn't have permissions", async () => {
await mountEditProjectFile({ authAdmin: false });
expect(wrapper.text()).toContain(
"file.warning.not.displayed.nonadmin.message",
);
});
it("renders the correct strings when user has permissions", async () => {
expect(wrapper.text()).toContain(
"file.warning.not.displayed.admin.message",
);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

repeated tests, please remove

await mountEditProjectFile({
authAdmin: false,
});
expect(wrapper.text()).toContain(
Copy link
Contributor

Choose a reason for hiding this comment

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

please use a data-test-id instead of using wrapper.text()

@ltamaster ltamaster added this to the 5.3.0 milestone May 8, 2024
@ltamaster ltamaster changed the title Run- 2307 unit tests for edit project file RUN-2307 unit tests for edit project file May 8, 2024
Copy link
Contributor

@smartinellibenedetti smartinellibenedetti left a comment

Choose a reason for hiding this comment

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

I'm marking this PR as approved as the tests are done, but I will also add a ticket to the backlog to refactor this test suite and clean it up.

It's fine to have the wrapper initialized before the tests. Whenever following this approach, it is required to be aware that a lot of actions may have already happened, which you don't need to re-trigger to be able to test things, while some you might need to trigger again, which may deviate from the component's original behavior if this component doesn't have any logic to do so.

@jayas006
Copy link
Contributor Author

jayas006 commented May 8, 2024

I'm marking this PR as approved as the tests are done, but I will also add a ticket to the backlog to refactor this test suite and clean it up.

It's fine to have the wrapper initialized before the tests. Whenever following this approach, it is required to be aware that a lot of actions may have already happened, which you don't need to re-trigger to be able to test things, while some you might need to trigger again, which may deviate from the component's original behavior if this component doesn't have any logic to do so.

Yes, that makes sense.

@ltamaster ltamaster merged commit 1e2978e into main May 8, 2024
3 checks passed
@ltamaster ltamaster deleted the feat/unit-test-for-edit-project-file branch May 8, 2024 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants