Skip to content
Snippets Groups Projects
Verified Commit 9bbbcec9 authored by Jacques Erasmus's avatar Jacques Erasmus 💬 Committed by GitLab
Browse files

Merge branch '450774-fork-suggestion-utils' into 'master'

Prepare util functions for a fork suggestion alert

See merge request !181156



Merged-by: default avatarJacques Erasmus <jerasmus@gitlab.com>
Approved-by: Chaoyue Zhao's avatarChaoyue Zhao <czhao@gitlab.com>
Approved-by: default avatarJacques Erasmus <jerasmus@gitlab.com>
Reviewed-by: Chaoyue Zhao's avatarChaoyue Zhao <czhao@gitlab.com>
Co-authored-by: default avatarpsjakubowska <psedlak-jakubowska@gitlab.com>
parents 7d072668 eb12b79c
No related branches found
No related tags found
2 merge requests!181156Prepare util functions for a fork suggestion alert,!180727Resolve "Extend job archival mechanism to the whole pipeline"
Pipeline #1669455938 passed
import { isLoggedIn } from '~/lib/utils/common_utils';
import { createAlert, VARIANT_INFO } from '~/alert';
import { __ } from '~/locale';
export function showForkSuggestionAlert(forkAndViewPath) {
const i18n = {
forkSuggestion: __(
"You can't edit files directly in this project. Fork this project and submit a merge request with your changes.",
),
fork: __('Fork'),
cancel: __('Cancel'),
};
const alert = createAlert({
message: i18n.forkSuggestion,
variant: VARIANT_INFO,
primaryButton: {
text: i18n.fork,
link: forkAndViewPath,
},
secondaryButton: {
text: i18n.cancel,
clickHandler: () => alert.dismiss(),
},
});
return alert;
}
/**
* Checks if the user can fork the project
* @param {Object} userPermissions - User permissions object
* @param {boolean} isUsingLfs - Whether the project is using LFS
* @returns {boolean}
*/
export const canFork = (userPermissions, isUsingLfs) => {
const { createMergeRequestIn, forkProject } = userPermissions;
return isLoggedIn() && !isUsingLfs && createMergeRequestIn && forkProject;
};
/**
* Checks if the fork suggestion should be shown for single file editor
* @param {Object} userPermissions - User permissions object
* @param {boolean} isUsingLfs - Whether the project is using LFS
* @param {boolean} canModifyBlob - Whether the user can modify the blob
* @returns {boolean}
*/
export const showSingleFileEditorForkSuggestion = (userPermissions, isUsingLfs, canModifyBlob) => {
return canFork(userPermissions, isUsingLfs) && !canModifyBlob;
};
/**
* Checks if the fork suggestion should be shown for Web IDE
* @param {Object} userPermissions - User permissions object
* @param {boolean} isUsingLfs - Whether the project is using LFS
* @param {boolean} canModifyBlobWithWebIde - Whether the user can modify the blob with Web IDE
* @returns {boolean}
*/
export const showWebIdeForkSuggestion = (userPermissions, isUsingLfs, canModifyBlobWithWebIde) => {
return canFork(userPermissions, isUsingLfs) && !canModifyBlobWithWebIde;
};
/**
* Checks if the fork suggestion should be shown
* @param {Object} userPermissions - User permissions object
* @param {boolean} isUsingLfs - Whether the project is using LFS
* @param {Object} blobInfo - blobInfo object, including canModifyBlob and canModifyBlobWithWebIde
* @returns {boolean}
*/
export const showForkSuggestion = (userPermissions, isUsingLfs, blobInfo) => {
return (
showSingleFileEditorForkSuggestion(userPermissions, isUsingLfs, blobInfo.canModifyBlob) ||
showWebIdeForkSuggestion(userPermissions, isUsingLfs, blobInfo.canModifyBlobWithWebIde)
);
};
......@@ -66487,6 +66487,9 @@ msgstr ""
msgid "You can't approve because you added one or more commits to this merge request."
msgstr ""
 
msgid "You can't edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
msgid "You can't follow more than %{limit} users. To follow more users, unfollow some others."
msgstr ""
 
import { createAlert, VARIANT_INFO } from '~/alert';
import * as commonUtils from '~/lib/utils/common_utils';
import {
showForkSuggestionAlert,
canFork,
showSingleFileEditorForkSuggestion,
showWebIdeForkSuggestion,
showForkSuggestion,
} from '~/repository/utils/fork_suggestion_utils';
jest.mock('~/alert');
jest.mock('~/lib/utils/common_utils');
describe('forkSuggestionUtils', () => {
let userPermissions;
const createUserPermissions = (createMergeRequestIn = true, forkProject = true) => ({
createMergeRequestIn,
forkProject,
});
beforeEach(() => {
commonUtils.isLoggedIn.mockReturnValue(true);
userPermissions = createUserPermissions();
});
describe('canFork', () => {
it('returns true when all conditions are met', () => {
expect(canFork(userPermissions, false)).toBe(true);
});
it('returns false when user is not logged in', () => {
commonUtils.isLoggedIn.mockReturnValue(false);
expect(canFork(userPermissions, false)).toBe(false);
});
it('returns false when project is using LFS', () => {
expect(canFork(userPermissions, true)).toBe(false);
});
it('returns false when user cannot create merge request', () => {
userPermissions = createUserPermissions(false, true);
expect(canFork(userPermissions, false)).toBe(false);
});
it('returns false when user cannot fork project', () => {
userPermissions = createUserPermissions(true, false);
expect(canFork(userPermissions, false)).toBe(false);
});
});
describe('showSingleFileEditorForkSuggestion', () => {
it('returns true when user can fork but cannot modify blob', () => {
expect(showSingleFileEditorForkSuggestion(userPermissions, false, false)).toBe(true);
});
it('returns false when user can fork and can modify blob', () => {
expect(showSingleFileEditorForkSuggestion(userPermissions, false, true)).toBe(false);
});
});
describe('showWebIdeForkSuggestion', () => {
it('returns true when user can fork but cannot modify blob with Web IDE', () => {
expect(showWebIdeForkSuggestion(userPermissions, false, false)).toBe(true);
});
it('returns false when user can fork and can modify blob with Web IDE', () => {
expect(showWebIdeForkSuggestion(userPermissions, false, true)).toBe(false);
});
});
describe('showForkSuggestion', () => {
it('returns true when single file editor fork suggestion is true', () => {
expect(
showForkSuggestion(userPermissions, false, {
canModifyBlob: false,
canModifyBlobWithWebIde: true,
}),
).toBe(true);
});
it('returns true when Web IDE fork suggestion is true', () => {
expect(
showForkSuggestion(userPermissions, false, {
canModifyBlob: true,
canModifyBlobWithWebIde: false,
}),
).toBe(true);
});
it('returns false when both fork suggestions are false', () => {
expect(
showForkSuggestion(userPermissions, false, {
canModifyBlob: true,
canModifyBlobWithWebIde: true,
}),
).toBe(false);
});
it('returns false when user cannot fork', () => {
commonUtils.isLoggedIn.mockReturnValue(false);
expect(
showForkSuggestion(userPermissions, false, {
canModifyBlob: false,
canModifyBlobWithWebIde: false,
}),
).toBe(false);
});
});
describe('showForkSuggestionAlert', () => {
const forkAndViewPath = '/path/to/fork';
beforeEach(() => {
createAlert.mockClear();
});
it('calls createAlert with correct parameters', () => {
showForkSuggestionAlert(forkAndViewPath);
expect(createAlert).toHaveBeenCalledTimes(1);
expect(createAlert).toHaveBeenCalledWith({
message:
"You can't edit files directly in this project. Fork this project and submit a merge request with your changes.",
variant: VARIANT_INFO,
primaryButton: {
text: 'Fork',
link: forkAndViewPath,
},
secondaryButton: {
text: 'Cancel',
clickHandler: expect.any(Function),
},
});
});
it('secondary button click handler dismisses the alert', () => {
const mockAlert = { dismiss: jest.fn() };
createAlert.mockReturnValue(mockAlert);
showForkSuggestionAlert(forkAndViewPath);
const secondaryButtonClickHandler = createAlert.mock.calls[0][0].secondaryButton.clickHandler;
secondaryButtonClickHandler(mockAlert);
expect(mockAlert.dismiss).toHaveBeenCalledTimes(1);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment