diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue
index 8a7d3430063bc35bbd7da1d1bcc710210bdd8361..d811bb3b0bfa3b6b12bcea5c6284564943fc8a6f 100644
--- a/app/assets/javascripts/deploy_keys/components/key.vue
+++ b/app/assets/javascripts/deploy_keys/components/key.vue
@@ -115,10 +115,20 @@ export default {
{{ deployKey.title }}
-
- {{ __('MD5') }}:{{ deployKey.fingerprint }}
-
-
{{ __('SHA256') }}:{{ deployKey.fingerprint_sha256 }}
+
+ - {{ __('SHA256') }}
+ -
+ {{ deployKey.fingerprint_sha256 }}
+
+
+ -
+ {{ __('MD5') }}
+
+ -
+ {{ deployKey.fingerprint }}
+
+
+
diff --git a/app/assets/javascripts/projects/settings/access_dropdown.js b/app/assets/javascripts/projects/settings/access_dropdown.js
index 79dfa166b1a0110dd12dd6c5b013cbe030f2a2cb..060178a3cfbcb66aeaf4b400349c763b3d15ac9d 100644
--- a/app/assets/javascripts/projects/settings/access_dropdown.js
+++ b/app/assets/javascripts/projects/settings/access_dropdown.js
@@ -441,11 +441,13 @@ export default class AccessDropdown {
const {
id,
fingerprint,
+ fingerprint_sha256: fingerprintSha256,
title,
owner: { avatar_url, name, username },
} = response;
- const shortFingerprint = `(${fingerprint.substring(0, 14)}...)`;
+ const availableFingerprint = fingerprintSha256 || fingerprint;
+ const shortFingerprint = `(${availableFingerprint.substring(0, 14)}...)`;
return {
id,
diff --git a/app/assets/javascripts/projects/settings/components/access_dropdown.vue b/app/assets/javascripts/projects/settings/components/access_dropdown.vue
index a24eb1f5b203ad910da0dfd777ee2429d0fb3a53..fcf81c9d1f74c47e23db467d390306cf720e1bc5 100644
--- a/app/assets/javascripts/projects/settings/components/access_dropdown.vue
+++ b/app/assets/javascripts/projects/settings/components/access_dropdown.vue
@@ -203,11 +203,13 @@ export default {
const {
id,
fingerprint,
+ fingerprint_sha256: fingerprintSha256,
title,
owner: { avatar_url, name, username },
} = response;
- const shortFingerprint = `(${fingerprint.substring(0, 14)}...)`;
+ const availableFingerprint = fingerprintSha256 || fingerprint;
+ const shortFingerprint = `(${availableFingerprint.substring(0, 14)}...)`;
return {
id,
@@ -387,7 +389,7 @@ export default {
}}
{
const deployKey = responseBody[0];
const deployKey2 = responseBody[1];
+ const deployKeyWithoutMd5Fingerprint = responseBody[2];
const createComponent = (provide = {}) => {
wrapper = mountExtended(DeployKeysTable, {
@@ -57,9 +58,10 @@ describe('DeployKeysTable', () => {
const timeAgoTooltip = findTimeAgoTooltip(expectedRowIndex);
expect(wrapper.findByText(expectedDeployKey.title).exists()).toBe(true);
- expect(wrapper.findByText(expectedDeployKey.fingerprint, { selector: 'code' }).exists()).toBe(
- true,
- );
+
+ expect(
+ wrapper.findByText(expectedDeployKey.fingerprint_sha256, { selector: 'span' }).exists(),
+ ).toBe(true);
expect(timeAgoTooltip.exists()).toBe(true);
expect(timeAgoTooltip.props('time')).toBe(expectedDeployKey.created_at);
expect(editButton.exists()).toBe(true);
@@ -67,6 +69,13 @@ describe('DeployKeysTable', () => {
expect(findRemoveButton(expectedRowIndex).exists()).toBe(true);
};
+ const expectDeployKeyWithFingerprintIsRendered = (expectedDeployKey, expectedRowIndex) => {
+ expect(wrapper.findByText(expectedDeployKey.fingerprint, { selector: 'span' }).exists()).toBe(
+ true,
+ );
+ expectDeployKeyIsRendered(expectedDeployKey, expectedRowIndex);
+ };
+
const itRendersTheEmptyState = () => {
it('renders empty state', () => {
const emptyState = wrapper.findComponent(GlEmptyState);
@@ -127,8 +136,12 @@ describe('DeployKeysTable', () => {
});
it('renders deploy keys in table', () => {
- expectDeployKeyIsRendered(deployKey, 0);
- expectDeployKeyIsRendered(deployKey2, 1);
+ expectDeployKeyWithFingerprintIsRendered(deployKey, 0);
+ expectDeployKeyWithFingerprintIsRendered(deployKey2, 1);
+ });
+
+ it('renders deploy keys that do not have an MD5 fingerprint', () => {
+ expectDeployKeyIsRendered(deployKeyWithoutMd5Fingerprint, 2);
});
describe('when delete button is clicked', () => {
@@ -157,7 +170,7 @@ describe('DeployKeysTable', () => {
beforeEach(() => {
Api.deployKeys.mockResolvedValueOnce({
data: [deployKey],
- headers: { 'x-total': '2' },
+ headers: { 'x-total': '3' },
});
createComponent();
@@ -179,7 +192,7 @@ describe('DeployKeysTable', () => {
describe('when pagination is changed', () => {
it('calls API with `page` parameter', async () => {
const pagination = findPagination();
- expectDeployKeyIsRendered(deployKey, 0);
+ expectDeployKeyWithFingerprintIsRendered(deployKey, 0);
Api.deployKeys.mockResolvedValue({
data: [deployKey2],
@@ -199,7 +212,7 @@ describe('DeployKeysTable', () => {
page: 2,
public: true,
});
- expectDeployKeyIsRendered(deployKey2, 0);
+ expectDeployKeyWithFingerprintIsRendered(deployKey2, 0);
});
});
});
diff --git a/spec/frontend/fixtures/api_deploy_keys.rb b/spec/frontend/fixtures/api_deploy_keys.rb
index 7027b8c975bea94c73fa1e3823074c3af603191d..5ffc726f086f96445cc0780fe484e683591611b0 100644
--- a/spec/frontend/fixtures/api_deploy_keys.rb
+++ b/spec/frontend/fixtures/api_deploy_keys.rb
@@ -11,6 +11,7 @@
let_it_be(:project2) { create(:project) }
let_it_be(:deploy_key) { create(:deploy_key, public: true) }
let_it_be(:deploy_key2) { create(:deploy_key, public: true) }
+ let_it_be(:deploy_key_without_fingerprint) { create(:deploy_key, :without_md5_fingerprint, public: true) }
let_it_be(:deploy_keys_project) { create(:deploy_keys_project, :write_access, project: project, deploy_key: deploy_key) }
let_it_be(:deploy_keys_project2) { create(:deploy_keys_project, :write_access, project: project2, deploy_key: deploy_key) }
let_it_be(:deploy_keys_project3) { create(:deploy_keys_project, :write_access, project: project, deploy_key: deploy_key2) }
diff --git a/spec/frontend/projects/settings/components/new_access_dropdown_spec.js b/spec/frontend/projects/settings/components/new_access_dropdown_spec.js
index a42891423cde352e0fc16a640e75b666b474d1f6..1db48ce05d7aca037584ccfa00787783f2aa6a62 100644
--- a/spec/frontend/projects/settings/components/new_access_dropdown_spec.js
+++ b/spec/frontend/projects/settings/components/new_access_dropdown_spec.js
@@ -29,9 +29,20 @@ jest.mock('~/projects/settings/api/access_dropdown_api', () => ({
}),
getDeployKeys: jest.fn().mockResolvedValue({
data: [
- { id: 10, title: 'key10', fingerprint: 'abcdefghijklmnop', owner: { name: 'user1' } },
- { id: 11, title: 'key11', fingerprint: 'abcdefghijklmnop', owner: { name: 'user2' } },
- { id: 12, title: 'key12', fingerprint: 'abcdefghijklmnop', owner: { name: 'user3' } },
+ {
+ id: 10,
+ title: 'key10',
+ fingerprint: 'md5-abcdefghijklmnop',
+ fingerprint_sha256: 'sha256-abcdefghijklmnop',
+ owner: { name: 'user1' },
+ },
+ {
+ id: 11,
+ title: 'key11',
+ fingerprint_sha256: 'sha256-abcdefghijklmnop',
+ owner: { name: 'user2' },
+ },
+ { id: 12, title: 'key12', fingerprint: 'md5-abcdefghijklmnop', owner: { name: 'user3' } },
],
}),
}));
@@ -279,6 +290,7 @@ describe('Access Level Dropdown', () => {
{ id: 115, type: 'group', group_id: 5 },
{ id: 118, type: 'user', user_id: 8, name: 'user2' },
{ id: 121, type: 'deploy_key', deploy_key_id: 11 },
+ { id: 122, type: 'deploy_key', deploy_key_id: 12 },
];
const findSelected = (type) =>
@@ -309,8 +321,9 @@ describe('Access Level Dropdown', () => {
it('should set selected deploy keys as intersection between the server response and preselected mapping some keys', () => {
const selectedDeployKeys = findSelected(LEVEL_TYPES.DEPLOY_KEY);
- expect(selectedDeployKeys).toHaveLength(1);
- expect(selectedDeployKeys.at(0).text()).toContain('key11 (abcdefghijklmn...)');
+ expect(selectedDeployKeys).toHaveLength(2);
+ expect(selectedDeployKeys.at(0).text()).toContain('key11 (sha256-abcdefg...)');
+ expect(selectedDeployKeys.at(1).text()).toContain('key12 (md5-abcdefghij...)');
});
});