[PM-11926] - fix send created page text (#11467)
* fix send created page * remove unused i18n key * remove superfluous spec * fix failing tests
This commit is contained in:
parent
c6169432bb
commit
4ce6df3040
|
@ -2498,7 +2498,25 @@
|
|||
"message": "Send created successfully!",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendAvailability": {
|
||||
"sendExpiresInHoursSingle": {
|
||||
"message": "The Send will be available to anyone with the link for the next 1 hour.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendExpiresInHours": {
|
||||
"message": "The Send will be available to anyone with the link for the next $HOURS$ hours.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||
"placeholders": {
|
||||
"hours": {
|
||||
"content": "$1",
|
||||
"example": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sendExpiresInDaysSingle": {
|
||||
"message": "The Send will be available to anyone with the link for the next 1 day.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendExpiresInDays": {
|
||||
"message": "The Send will be available to anyone with the link for the next $DAYS$ days.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||
"placeholders": {
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
>
|
||||
<bit-icon [icon]="sendCreatedIcon"></bit-icon>
|
||||
<h3 class="tw-font-semibold">{{ "createdSendSuccessfully" | i18n }}</h3>
|
||||
<p class="tw-text-center">{{ "sendAvailability" | i18n: daysAvailable }}</p>
|
||||
<p class="tw-text-center">
|
||||
{{ formatExpirationDate() }}
|
||||
</p>
|
||||
<button bitButton type="button" buttonType="primary" (click)="copyLink()">
|
||||
<b>{{ "copyLink" | i18n }}</b>
|
||||
</button>
|
||||
|
|
|
@ -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<SendCreatedComponent>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
let platformUtilsService: MockProxy<PlatformUtilsService>;
|
||||
let sendService: MockProxy<SendService>;
|
||||
let toastService: MockProxy<ToastService>;
|
||||
|
@ -36,17 +35,10 @@ describe("SendCreatedComponent", () => {
|
|||
let router: MockProxy<Router>;
|
||||
|
||||
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<SendView[]>;
|
||||
|
||||
beforeEach(async () => {
|
||||
i18nService = mock<I18nService>();
|
||||
platformUtilsService = mock<PlatformUtilsService>();
|
||||
sendService = mock<SendService>();
|
||||
toastService = mock<ToastService>();
|
||||
|
@ -54,6 +46,17 @@ describe("SendCreatedComponent", () => {
|
|||
activatedRoute = mock<ActivatedRoute>();
|
||||
environmentService = mock<EnvironmentService>();
|
||||
router = mock<Router>();
|
||||
|
||||
sendView = {
|
||||
id: sendId,
|
||||
deletionDate: new Date(),
|
||||
accessId: "abc",
|
||||
urlB64Key: "123",
|
||||
} as SendView;
|
||||
|
||||
sendViewsSubject = new BehaviorSubject<SendView[]>([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,40 +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("getDaysAvailable", () => {
|
||||
it("returns the correct number of days", () => {
|
||||
describe("getHoursAvailable", () => {
|
||||
it("returns the correct number of hours", () => {
|
||||
sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 7);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
expect(component.getDaysAvailable(sendView)).toBe(7);
|
||||
|
||||
expect(component.getHoursAvailable(sendView)).toBeCloseTo(168, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatExpirationDate", () => {
|
||||
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 singular if expiry is 24 hours", () => {
|
||||
sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 1);
|
||||
sendViewsSubject.next([sendView]);
|
||||
fixture.detectChanges();
|
||||
|
||||
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();
|
||||
|
@ -136,7 +188,7 @@ describe("SendCreatedComponent", () => {
|
|||
expect(toastService.showToast).toHaveBeenCalledWith({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: i18nService.t("sendLinkCopied"),
|
||||
message: "sendLinkCopied",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,6 +39,7 @@ export class SendCreatedComponent {
|
|||
protected sendCreatedIcon = SendCreatedIcon;
|
||||
protected send: SendView;
|
||||
protected daysAvailable = 0;
|
||||
protected hoursAvailable = 0;
|
||||
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
|
@ -54,14 +55,26 @@ export class SendCreatedComponent {
|
|||
this.sendService.sendViews$.pipe(takeUntilDestroyed()).subscribe((sendViews) => {
|
||||
this.send = sendViews.find((s) => s.id === sendId);
|
||||
if (this.send) {
|
||||
this.daysAvailable = this.getDaysAvailable(this.send);
|
||||
this.hoursAvailable = this.getHoursAvailable(this.send);
|
||||
this.daysAvailable = Math.ceil(this.hoursAvailable / 24);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getDaysAvailable(send: SendView): number {
|
||||
formatExpirationDate(): string {
|
||||
if (this.hoursAvailable < 24) {
|
||||
return this.hoursAvailable === 1
|
||||
? this.i18nService.t("sendExpiresInHoursSingle")
|
||||
: this.i18nService.t("sendExpiresInHours", this.hoursAvailable);
|
||||
}
|
||||
return this.daysAvailable === 1
|
||||
? this.i18nService.t("sendExpiresInDaysSingle")
|
||||
: this.i18nService.t("sendExpiresInDays", this.daysAvailable);
|
||||
}
|
||||
|
||||
getHoursAvailable(send: SendView): number {
|
||||
const now = new Date().getTime();
|
||||
return Math.max(0, Math.ceil((send.deletionDate.getTime() - now) / (1000 * 60 * 60 * 24)));
|
||||
return Math.max(0, Math.ceil((send.deletionDate.getTime() - now) / (1000 * 60 * 60)));
|
||||
}
|
||||
|
||||
async close() {
|
||||
|
|
Loading…
Reference in New Issue