diff --git a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.spec.ts index 0bbe04037a..24186ad427 100644 --- a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.spec.ts @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { ActivatedRoute, Router, RouterLink } from "@angular/router"; import { RouterTestingModule } from "@angular/router/testing"; import { MockProxy, mock } from "jest-mock-extended"; -import { of } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -13,7 +13,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service"; import { SendView } from "@bitwarden/common/tools/send/models/view/send.view"; import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; -import { ButtonModule, IconModule, ToastService } from "@bitwarden/components"; +import { ButtonModule, I18nMockService, IconModule, ToastService } from "@bitwarden/components"; import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component"; import { PopupFooterComponent } from "../../../../platform/popup/layout/popup-footer.component"; @@ -26,7 +26,6 @@ import { SendCreatedComponent } from "./send-created.component"; describe("SendCreatedComponent", () => { let component: SendCreatedComponent; let fixture: ComponentFixture; - let i18nService: MockProxy; let platformUtilsService: MockProxy; let sendService: MockProxy; let toastService: MockProxy; @@ -36,17 +35,10 @@ describe("SendCreatedComponent", () => { let router: MockProxy; const sendId = "test-send-id"; - const deletionDate = new Date(); - deletionDate.setDate(deletionDate.getDate() + 7); - const sendView: SendView = { - id: sendId, - deletionDate, - accessId: "abc", - urlB64Key: "123", - } as SendView; + let sendView: SendView; + let sendViewsSubject: BehaviorSubject; beforeEach(async () => { - i18nService = mock(); platformUtilsService = mock(); sendService = mock(); toastService = mock(); @@ -54,6 +46,17 @@ describe("SendCreatedComponent", () => { activatedRoute = mock(); environmentService = mock(); router = mock(); + + sendView = { + id: sendId, + deletionDate: new Date(), + accessId: "abc", + urlB64Key: "123", + } as SendView; + + sendViewsSubject = new BehaviorSubject([sendView]); + sendService.sendViews$ = sendViewsSubject.asObservable(); + Object.defineProperty(environmentService, "environment$", { configurable: true, get: () => of(new SelfHostedEnvironment({ webVault: "https://example.com" })), @@ -65,8 +68,6 @@ describe("SendCreatedComponent", () => { }, } as any; - sendService.sendViews$ = of([sendView]); - await TestBed.configureTestingModule({ imports: [ CommonModule, @@ -82,7 +83,25 @@ describe("SendCreatedComponent", () => { SendCreatedComponent, ], providers: [ - { provide: I18nService, useValue: i18nService }, + { + provide: I18nService, + useFactory: () => { + return new I18nMockService({ + back: "back", + loading: "loading", + copyLink: "copyLink", + close: "close", + createdSend: "createdSend", + createdSendSuccessfully: "createdSendSuccessfully", + popOutNewWindow: "popOutNewWindow", + sendExpiresInHours: (hours) => `sendExpiresInHours ${hours}`, + sendExpiresInHoursSingle: "sendExpiresInHoursSingle", + sendExpiresInDays: (days) => `sendExpiresInDays ${days}`, + sendExpiresInDaysSingle: "sendExpiresInDaysSingle", + sendLinkCopied: "sendLinkCopied", + }); + }, + }, { provide: PlatformUtilsService, useValue: platformUtilsService }, { provide: SendService, useValue: sendService }, { provide: ToastService, useValue: toastService }, @@ -94,54 +113,73 @@ describe("SendCreatedComponent", () => { { provide: Router, useValue: router }, ], }).compileComponents(); - }); - beforeEach(() => { fixture = TestBed.createComponent(SendCreatedComponent); component = fixture.componentInstance; + fixture.detectChanges(); }); it("should create", () => { - fixture.detectChanges(); expect(component).toBeTruthy(); }); - it("should initialize send and daysAvailable", () => { - fixture.detectChanges(); + it("should initialize send, daysAvailable, and hoursAvailable", () => { expect(component["send"]).toBe(sendView); - expect(component["daysAvailable"]).toBe(7); + expect(component["daysAvailable"]).toBe(0); + expect(component["hoursAvailable"]).toBe(0); }); it("should navigate back to send list on close", async () => { - fixture.detectChanges(); await component.close(); expect(router.navigate).toHaveBeenCalledWith(["/tabs/send"]); }); describe("getHoursAvailable", () => { it("returns the correct number of hours", () => { + sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 7); + sendViewsSubject.next([sendView]); fixture.detectChanges(); - expect(component.getHoursAvailable(sendView)).toBe(168); + + expect(component.getHoursAvailable(sendView)).toBeCloseTo(168, 0); }); }); describe("formatExpirationDate", () => { - it("returns hours if less than 24", () => { + it("returns days plural if expiry is more than 24 hours", () => { + sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 7); + sendViewsSubject.next([sendView]); fixture.detectChanges(); + expect(component.formatExpirationDate()).toBe("sendExpiresInDays 7"); }); - it("returns days if 24 or more", () => { - sendView.deletionDate = new Date(); + it("returns days singular if expiry is 24 hours", () => { sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 1); + sendViewsSubject.next([sendView]); fixture.detectChanges(); - expect(component.formatExpirationDate()).toBe("sendExpiresInDaySingle"); + + expect(component.formatExpirationDate()).toBe("sendExpiresInDaysSingle"); + }); + + it("returns hours plural if expiry is more than 1 hour but less than 24", () => { + sendView.deletionDate.setHours(sendView.deletionDate.getHours() + 2); + sendViewsSubject.next([sendView]); + fixture.detectChanges(); + + expect(component.formatExpirationDate()).toBe("sendExpiresInHours 2"); + }); + + it("returns hours singular if expiry is in 1 hour", () => { + sendView.deletionDate.setHours(sendView.deletionDate.getHours() + 1); + sendViewsSubject.next([sendView]); + fixture.detectChanges(); + + expect(component.formatExpirationDate()).toBe("sendExpiresInHoursSingle"); }); }); describe("copyLink", () => { it("should copy link and show toast", async () => { - fixture.detectChanges(); const link = "https://example.com/#/send/abc/123"; await component.copyLink(); @@ -150,7 +188,7 @@ describe("SendCreatedComponent", () => { expect(toastService.showToast).toHaveBeenCalledWith({ variant: "success", title: null, - message: i18nService.t("sendLinkCopied"), + message: "sendLinkCopied", }); }); }); diff --git a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts index 35413f9df5..ae66d14d3f 100644 --- a/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-created/send-created.component.ts @@ -56,7 +56,7 @@ export class SendCreatedComponent { this.send = sendViews.find((s) => s.id === sendId); if (this.send) { this.hoursAvailable = this.getHoursAvailable(this.send); - this.daysAvailable = this.hoursAvailable / 24; + this.daysAvailable = Math.ceil(this.hoursAvailable / 24); } }); }