mirror of
https://github.com/bitwarden/browser.git
synced 2024-10-14 06:48:18 +02:00
[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!",
|
"message": "Send created successfully!",
|
||||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
"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.",
|
"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.",
|
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
>
|
>
|
||||||
<bit-icon [icon]="sendCreatedIcon"></bit-icon>
|
<bit-icon [icon]="sendCreatedIcon"></bit-icon>
|
||||||
<h3 class="tw-font-semibold">{{ "createdSendSuccessfully" | i18n }}</h3>
|
<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()">
|
<button bitButton type="button" buttonType="primary" (click)="copyLink()">
|
||||||
<b>{{ "copyLink" | i18n }}</b>
|
<b>{{ "copyLink" | i18n }}</b>
|
||||||
</button>
|
</button>
|
||||||
|
@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
|
|||||||
import { ActivatedRoute, Router, RouterLink } from "@angular/router";
|
import { ActivatedRoute, Router, RouterLink } from "@angular/router";
|
||||||
import { RouterTestingModule } from "@angular/router/testing";
|
import { RouterTestingModule } from "@angular/router/testing";
|
||||||
import { MockProxy, mock } from "jest-mock-extended";
|
import { MockProxy, mock } from "jest-mock-extended";
|
||||||
import { of } from "rxjs";
|
import { BehaviorSubject, of } from "rxjs";
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
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 { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service";
|
||||||
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
|
||||||
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
|
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 { PopOutComponent } from "../../../../platform/popup/components/pop-out.component";
|
||||||
import { PopupFooterComponent } from "../../../../platform/popup/layout/popup-footer.component";
|
import { PopupFooterComponent } from "../../../../platform/popup/layout/popup-footer.component";
|
||||||
@ -26,7 +26,6 @@ import { SendCreatedComponent } from "./send-created.component";
|
|||||||
describe("SendCreatedComponent", () => {
|
describe("SendCreatedComponent", () => {
|
||||||
let component: SendCreatedComponent;
|
let component: SendCreatedComponent;
|
||||||
let fixture: ComponentFixture<SendCreatedComponent>;
|
let fixture: ComponentFixture<SendCreatedComponent>;
|
||||||
let i18nService: MockProxy<I18nService>;
|
|
||||||
let platformUtilsService: MockProxy<PlatformUtilsService>;
|
let platformUtilsService: MockProxy<PlatformUtilsService>;
|
||||||
let sendService: MockProxy<SendService>;
|
let sendService: MockProxy<SendService>;
|
||||||
let toastService: MockProxy<ToastService>;
|
let toastService: MockProxy<ToastService>;
|
||||||
@ -36,17 +35,10 @@ describe("SendCreatedComponent", () => {
|
|||||||
let router: MockProxy<Router>;
|
let router: MockProxy<Router>;
|
||||||
|
|
||||||
const sendId = "test-send-id";
|
const sendId = "test-send-id";
|
||||||
const deletionDate = new Date();
|
let sendView: SendView;
|
||||||
deletionDate.setDate(deletionDate.getDate() + 7);
|
let sendViewsSubject: BehaviorSubject<SendView[]>;
|
||||||
const sendView: SendView = {
|
|
||||||
id: sendId,
|
|
||||||
deletionDate,
|
|
||||||
accessId: "abc",
|
|
||||||
urlB64Key: "123",
|
|
||||||
} as SendView;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
i18nService = mock<I18nService>();
|
|
||||||
platformUtilsService = mock<PlatformUtilsService>();
|
platformUtilsService = mock<PlatformUtilsService>();
|
||||||
sendService = mock<SendService>();
|
sendService = mock<SendService>();
|
||||||
toastService = mock<ToastService>();
|
toastService = mock<ToastService>();
|
||||||
@ -54,6 +46,17 @@ describe("SendCreatedComponent", () => {
|
|||||||
activatedRoute = mock<ActivatedRoute>();
|
activatedRoute = mock<ActivatedRoute>();
|
||||||
environmentService = mock<EnvironmentService>();
|
environmentService = mock<EnvironmentService>();
|
||||||
router = mock<Router>();
|
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$", {
|
Object.defineProperty(environmentService, "environment$", {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get: () => of(new SelfHostedEnvironment({ webVault: "https://example.com" })),
|
get: () => of(new SelfHostedEnvironment({ webVault: "https://example.com" })),
|
||||||
@ -65,8 +68,6 @@ describe("SendCreatedComponent", () => {
|
|||||||
},
|
},
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
sendService.sendViews$ = of([sendView]);
|
|
||||||
|
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@ -82,7 +83,25 @@ describe("SendCreatedComponent", () => {
|
|||||||
SendCreatedComponent,
|
SendCreatedComponent,
|
||||||
],
|
],
|
||||||
providers: [
|
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: PlatformUtilsService, useValue: platformUtilsService },
|
||||||
{ provide: SendService, useValue: sendService },
|
{ provide: SendService, useValue: sendService },
|
||||||
{ provide: ToastService, useValue: toastService },
|
{ provide: ToastService, useValue: toastService },
|
||||||
@ -94,40 +113,73 @@ describe("SendCreatedComponent", () => {
|
|||||||
{ provide: Router, useValue: router },
|
{ provide: Router, useValue: router },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(SendCreatedComponent);
|
fixture = TestBed.createComponent(SendCreatedComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create", () => {
|
it("should create", () => {
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should initialize send and daysAvailable", () => {
|
it("should initialize send, daysAvailable, and hoursAvailable", () => {
|
||||||
fixture.detectChanges();
|
|
||||||
expect(component["send"]).toBe(sendView);
|
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 () => {
|
it("should navigate back to send list on close", async () => {
|
||||||
fixture.detectChanges();
|
|
||||||
await component.close();
|
await component.close();
|
||||||
expect(router.navigate).toHaveBeenCalledWith(["/tabs/send"]);
|
expect(router.navigate).toHaveBeenCalledWith(["/tabs/send"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getDaysAvailable", () => {
|
describe("getHoursAvailable", () => {
|
||||||
it("returns the correct number of days", () => {
|
it("returns the correct number of hours", () => {
|
||||||
|
sendView.deletionDate.setDate(sendView.deletionDate.getDate() + 7);
|
||||||
|
sendViewsSubject.next([sendView]);
|
||||||
fixture.detectChanges();
|
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", () => {
|
describe("copyLink", () => {
|
||||||
it("should copy link and show toast", async () => {
|
it("should copy link and show toast", async () => {
|
||||||
fixture.detectChanges();
|
|
||||||
const link = "https://example.com/#/send/abc/123";
|
const link = "https://example.com/#/send/abc/123";
|
||||||
|
|
||||||
await component.copyLink();
|
await component.copyLink();
|
||||||
@ -136,7 +188,7 @@ describe("SendCreatedComponent", () => {
|
|||||||
expect(toastService.showToast).toHaveBeenCalledWith({
|
expect(toastService.showToast).toHaveBeenCalledWith({
|
||||||
variant: "success",
|
variant: "success",
|
||||||
title: null,
|
title: null,
|
||||||
message: i18nService.t("sendLinkCopied"),
|
message: "sendLinkCopied",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -39,6 +39,7 @@ export class SendCreatedComponent {
|
|||||||
protected sendCreatedIcon = SendCreatedIcon;
|
protected sendCreatedIcon = SendCreatedIcon;
|
||||||
protected send: SendView;
|
protected send: SendView;
|
||||||
protected daysAvailable = 0;
|
protected daysAvailable = 0;
|
||||||
|
protected hoursAvailable = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
@ -54,14 +55,26 @@ export class SendCreatedComponent {
|
|||||||
this.sendService.sendViews$.pipe(takeUntilDestroyed()).subscribe((sendViews) => {
|
this.sendService.sendViews$.pipe(takeUntilDestroyed()).subscribe((sendViews) => {
|
||||||
this.send = sendViews.find((s) => s.id === sendId);
|
this.send = sendViews.find((s) => s.id === sendId);
|
||||||
if (this.send) {
|
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();
|
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() {
|
async close() {
|
||||||
|
Loading…
Reference in New Issue
Block a user