diff --git a/src/app/components/shared/hidden-copy/hidden-copy.component.spec.ts b/src/app/components/shared/hidden-copy/hidden-copy.component.spec.ts index 640a372e1..c0db598bf 100644 --- a/src/app/components/shared/hidden-copy/hidden-copy.component.spec.ts +++ b/src/app/components/shared/hidden-copy/hidden-copy.component.spec.ts @@ -1,19 +1,21 @@ import { BootstrapColorTypes } from "@helpers/bootstrapTypes"; import { NgbTooltipModule } from "@ng-bootstrap/ng-bootstrap"; -import { createHostFactory, SpectatorHost } from "@ngneat/spectator"; +import { createHostFactory, SpectatorHost, SpyObject } from "@ngneat/spectator"; import { IconsModule } from "@shared/icons/icons.module"; import { modelData } from "@test/helpers/faker"; -import { ClipboardModule } from "ngx-clipboard"; +import { ClipboardModule, ClipboardService } from "ngx-clipboard"; import { HiddenCopyComponent } from "./hidden-copy.component"; describe("HiddenCopyComponent", () => { let spec: SpectatorHost; + let clipboardService: SpyObject; + const createHost = createHostFactory({ component: HiddenCopyComponent, imports: [IconsModule, NgbTooltipModule, ClipboardModule], }); - function setup(props: Partial) { + function setup(props: Partial = {}) { props.value ??= "value"; props.content ??= "content"; props.tooltip ??= "tooltip"; @@ -21,6 +23,9 @@ describe("HiddenCopyComponent", () => { spec = createHost("", { props, }); + + clipboardService = spec.inject(ClipboardService); + clipboardService.copyFromContent = jasmine.createSpy("copyFromContent") as any; } function getVisibilityButton() { @@ -31,6 +36,14 @@ describe("HiddenCopyComponent", () => { return spec.query("#copy-btn"); } + function getCopyIcon() { + return spec.query("#copy-icon"); + } + + function getCopiedTooltip() { + return spec.query("[ngbTooltip='Coped!']"); + } + it("should create", () => { setup({}); expect(spec.component).toBeTruthy(); @@ -45,7 +58,7 @@ describe("HiddenCopyComponent", () => { it("should have tooltip", () => { const tooltip = modelData.random.words(); setup({ tooltip }); - // Container is body so that we dont have issues with the tooltip + // Container is body so that we don't have issues with the tooltip // breaking css and clipping expect(getVisibilityButton()).toHaveTooltip(tooltip, { container: "body", @@ -75,19 +88,39 @@ describe("HiddenCopyComponent", () => { it("should have tooltip", () => { const tooltip = modelData.random.words(); setup({ tooltip }); - // Container is body so that we dont have issues with the tooltip + // Container is body so that we don't have issues with the tooltip // breaking css and clipping + + // if we hover over the "Copied!" tooltip element, it should not show + spec.focus(getCopyButton()); + // Tooltip should only show on click - expect(getCopyButton()).toHaveTooltip("Copied!", { - triggers: "manual", - container: "body", - }); + expect(getCopiedTooltip()).not.toBeVisible(); + + // after the button is clicked, we expect that the tooltip will be visible + spec.click(getCopyButton()); + expect(getCopiedTooltip()).not.toBeVisible(); }); it("should not be disabled", () => { setup({ disabled: undefined }); expect(getCopyButton()).not.toHaveAttribute("disabled"); }); + + // these tests were not always present which resulted in bugs such as the + // copy button not copying the text + // see: https://github.com/QutEcoacoustics/workbench-client/issues/2146 + it("should copy if the copy icon is clicked", () => { + setup({ content: modelData.authToken() }); + spec.click(getCopyIcon()); + expect(clipboardService.copyFromContent).toHaveBeenCalledTimes(1); + }); + + it("should copy if the copy button is clicked", () => { + setup({ content: modelData.authToken() }); + spec.click(getCopyButton()); + expect(clipboardService.copyFromContent).toHaveBeenCalledTimes(1); + }); }); describe("content", () => { @@ -135,6 +168,12 @@ describe("HiddenCopyComponent", () => { setup({ disabled }); expect(getCopyButton()).toHaveAttribute("disabled"); }); + + it("should not copy if disabled and the copy button is clicked", () => { + setup({ content: modelData.authToken(), disabled: "true" }); + spec.click(getCopyButton()); + expect(clipboardService.copyFromContent).not.toHaveBeenCalled(); + }); }); describe("color", () => { diff --git a/src/app/components/shared/hidden-copy/hidden-copy.component.ts b/src/app/components/shared/hidden-copy/hidden-copy.component.ts index 29797658e..5b52bd841 100644 --- a/src/app/components/shared/hidden-copy/hidden-copy.component.ts +++ b/src/app/components/shared/hidden-copy/hidden-copy.component.ts @@ -1,9 +1,6 @@ import { Component, Input } from "@angular/core"; import { BootstrapColorTypes } from "@helpers/bootstrapTypes"; -/** - * Loading Animation - */ @Component({ selector: "baw-hidden-copy", template: ` @@ -22,29 +19,36 @@ import { BootstrapColorTypes } from "@helpers/bootstrapTypes"; -
{{ visible ? content : "..." }}
+
{{ visible ? content : "..." }}
- + + + `, styles: [ @@ -53,6 +57,21 @@ import { BootstrapColorTypes } from "@helpers/bootstrapTypes"; margin: 0; white-space: pre-wrap; } + + /* + In bootstrap, any element that is inside the same form-control has + its edge border radius set to 0 so that all inner form-control + elements are flush. + However, because we have wrapped the copy-btn inside a tooltip , + bootstrap attempts to flatten the span's border radius (which is not + visible) instead of the copy buttons. + to keep consistent with the bootstrap styling, I manually flatten the + left edges of the copy button. + */ + #copy-btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } `, ], })