Skip to content

Commit abeb4b9

Browse files
committed
Fix: Helm Chart Copy Button in UI (goharbor#21969)
* fix: helm chart copy btn in UI Signed-off-by: bupd <[email protected]> * add: tests for pull command component in UI Signed-off-by: bupd <[email protected]> --------- Signed-off-by: bupd <[email protected]>
1 parent 785b60b commit abeb4b9

File tree

3 files changed

+87
-14
lines changed

3 files changed

+87
-14
lines changed

src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/pull-command/pull-command.component.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*ngIf="isImage(artifact)"
44
[title]="getPullCommandForRuntimeByDigest(artifact)"
55
[iconMode]="true"
6+
id="pullCommandForDigest"
67
(onCopySuccess)="
78
onCpSuccess(getPullCommandForRuntimeByDigest(artifact))
89
"
@@ -12,6 +13,7 @@
1213
<div
1314
*ngIf="isCNAB(artifact)"
1415
class="flex"
16+
id="pullCommandForCNAB"
1517
aria-label="Dropdown header Action">
1618
<hbr-copy-input
1719
[title]="getPullCommandForCNAB(artifact)"
@@ -20,8 +22,9 @@
2022
[defaultValue]="getPullCommandForCNAB(artifact)"></hbr-copy-input>
2123
</div>
2224
<div
23-
*ngIf="isChart(artifact)"
25+
*ngIf="isChart(artifact) && artifact.tagNumber > 0"
2426
class="flex"
27+
id="pullCommandForChart"
2528
aria-label="Dropdown header Action">
2629
<hbr-copy-input
2730
[title]="getPullCommandForChart(artifact)"

src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/pull-command/pull-command.component.spec.ts

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
import { PullCommandComponent } from './pull-command.component';
1515
import { ComponentFixture, TestBed } from '@angular/core/testing';
1616
import { SharedTestingModule } from '../../../../../../../../shared/shared.module';
17-
import { ArtifactType } from '../../../../artifact'; // Import the necessary type
17+
import { ArtifactType, Clients } from '../../../../artifact'; // Import the necessary type
18+
import { ArtifactFront } from '../../../../artifact';
1819

1920
describe('PullCommandComponent', () => {
2021
let component: PullCommandComponent;
@@ -29,11 +30,11 @@ describe('PullCommandComponent', () => {
2930
fixture = TestBed.createComponent(PullCommandComponent);
3031
component = fixture.componentInstance;
3132

32-
// Mock the artifact input with a valid value
3333
component.artifact = {
34-
type: ArtifactType.IMAGE,
35-
digest: 'sampleDigest',
36-
tags: [{ name: 'latest' }],
34+
type: ArtifactType.CHART,
35+
tagNumber: 1,
36+
digest: 'sha256@digest',
37+
tags: [{ name: '1.0.0' }],
3738
};
3839

3940
fixture.detectChanges();
@@ -42,4 +43,69 @@ describe('PullCommandComponent', () => {
4243
it('should create', () => {
4344
expect(component).toBeTruthy();
4445
});
46+
47+
it('should not display pull command for chart', async () => {
48+
// Mock the artifact input with a valid value
49+
component.artifact = {
50+
type: ArtifactType.CHART,
51+
tagNumber: 0,
52+
digest: 'sha256@digest',
53+
tags: [],
54+
};
55+
component.getPullCommandForChart(component.artifact);
56+
expect(
57+
component.getPullCommandForChart(component.artifact).length
58+
).toBe(0);
59+
fixture.detectChanges();
60+
await fixture.whenStable();
61+
const modal =
62+
fixture.nativeElement.querySelector(`#pullCommandForChart`);
63+
expect(modal).toBeFalsy();
64+
});
65+
66+
it('should display when pull command for chart is available', async () => {
67+
// Mock the artifact input with a valid value
68+
component.artifact = {
69+
type: ArtifactType.CHART,
70+
tagNumber: 1,
71+
digest: 'sha256@digest',
72+
tags: [{ name: '1.0.0' }],
73+
};
74+
component.getPullCommandForChart(component.artifact);
75+
expect(
76+
component.getPullCommandForChart(component.artifact).length
77+
).toBeGreaterThan(0);
78+
fixture.detectChanges();
79+
await fixture.whenStable();
80+
const modal =
81+
fixture.nativeElement.querySelector(`#pullCommandForChart`);
82+
expect(modal).toBeTruthy();
83+
});
84+
85+
it('should display when pull command for digest is available', async () => {
86+
// Mock the artifact input with a valid value
87+
component.artifact = {
88+
type: ArtifactType.IMAGE,
89+
};
90+
component.getPullCommandForRuntimeByDigest(component.artifact);
91+
fixture.detectChanges();
92+
await fixture.whenStable();
93+
const modal = fixture.nativeElement.querySelector(
94+
`#pullCommandForDigest`
95+
);
96+
expect(modal).toBeTruthy();
97+
});
98+
99+
it('should display when pull command for CNAB is available', async () => {
100+
// Mock the artifact input with a valid value
101+
component.artifact = {
102+
type: ArtifactType.CNAB,
103+
};
104+
component.getPullCommandForCNAB(component.artifact);
105+
fixture.detectChanges();
106+
await fixture.whenStable();
107+
const modal =
108+
fixture.nativeElement.querySelector(`#pullCommandForCNAB`);
109+
expect(modal).toBeTruthy();
110+
});
45111
});

src/portal/src/app/base/project/repository/artifact/artifact-list-page/artifact-list/artifact-list-tab/pull-command/pull-command.component.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,18 @@ export class PullCommandComponent {
100100
}
101101

102102
getPullCommandForChart(artifact: Artifact): string {
103-
return getPullCommandByTag(
104-
artifact.type,
105-
`${this.registryUrl ? this.registryUrl : location.hostname}/${
106-
this.projectName
107-
}/${this.repoName}`,
108-
artifact.tags[0].name,
109-
Clients.CHART
110-
);
103+
if (artifact.tagNumber > 0) {
104+
return getPullCommandByTag(
105+
artifact.type,
106+
`${this.registryUrl ? this.registryUrl : location.hostname}/${
107+
this.projectName
108+
}/${this.repoName}`,
109+
artifact.tags[0].name,
110+
Clients.CHART
111+
);
112+
} else {
113+
return '';
114+
}
111115
}
112116

113117
// For tagMode

0 commit comments

Comments
 (0)