diff --git a/apps/desktop/src/auth/delete-account.component.html b/apps/desktop/src/auth/delete-account.component.html
index 08448e2422d..f8cc671af82 100644
--- a/apps/desktop/src/auth/delete-account.component.html
+++ b/apps/desktop/src/auth/delete-account.component.html
@@ -6,7 +6,7 @@
{{ "deleteAccountWarning" | i18n }}
- @if (migrationMilestone3) {
+ @if (migrationMilestone4) {
{
+ let component: DeleteAccountComponent;
+ let i18nService: MockProxy;
+ let formBuilder: FormBuilder;
+ let accountApiService: MockProxy;
+ let toastService: MockProxy;
+ let configService: MockProxy;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+
+ i18nService = mock();
+ formBuilder = new FormBuilder();
+ accountApiService = mock();
+ toastService = mock();
+ configService = mock();
+
+ i18nService.t.mockImplementation((key: any) => key);
+
+ component = new DeleteAccountComponent(
+ i18nService,
+ formBuilder,
+ accountApiService,
+ toastService,
+ configService,
+ );
+ });
+
+ describe("submit", () => {
+ const mockVerification: VerificationWithSecret = {
+ type: 0,
+ secret: "masterPassword123",
+ };
+
+ beforeEach(() => {
+ component.deleteForm.patchValue({
+ verification: mockVerification,
+ });
+ });
+
+ describe("when feature flag is enabled", () => {
+ beforeEach(() => {
+ component["migrationMilestone4"] = true;
+ });
+
+ it("should delete account and show success toast on successful deletion", async () => {
+ accountApiService.deleteAccount.mockResolvedValue(undefined);
+
+ await component.submit();
+
+ expect(accountApiService.deleteAccount).toHaveBeenCalledWith(mockVerification);
+ expect(toastService.showToast).toHaveBeenCalledWith({
+ variant: "success",
+ title: "accountDeleted",
+ message: "accountDeletedDesc",
+ });
+ expect(component["invalidSecret"]).toBe(false);
+ });
+
+ it("should set invalidSecret to true when deletion fails", async () => {
+ accountApiService.deleteAccount.mockRejectedValue(new Error("Invalid credentials"));
+
+ await component.submit();
+
+ expect(accountApiService.deleteAccount).toHaveBeenCalledWith(mockVerification);
+ expect(toastService.showToast).not.toHaveBeenCalled();
+ expect(component["invalidSecret"]).toBe(true);
+ });
+
+ it("should reset invalidSecret to false before attempting deletion", async () => {
+ component["invalidSecret"] = true;
+ accountApiService.deleteAccount.mockResolvedValue(undefined);
+
+ await component.submit();
+
+ expect(component["invalidSecret"]).toBe(false);
+ });
+ });
+
+ describe("when feature flag is disabled", () => {
+ beforeEach(() => {
+ component["migrationMilestone4"] = false;
+ });
+
+ it("should delete account and show success toast on successful deletion", async () => {
+ accountApiService.deleteAccount.mockResolvedValue(undefined);
+
+ await component.submit();
+
+ expect(accountApiService.deleteAccount).toHaveBeenCalledWith(mockVerification);
+ expect(toastService.showToast).toHaveBeenCalledWith({
+ variant: "success",
+ title: "accountDeleted",
+ message: "accountDeletedDesc",
+ });
+ });
+
+ it("should not set invalidSecret when deletion fails", async () => {
+ const initialInvalidSecret = component["invalidSecret"];
+ accountApiService.deleteAccount.mockRejectedValue(new Error("Invalid credentials"));
+
+ await component.submit();
+
+ expect(accountApiService.deleteAccount).toHaveBeenCalledWith(mockVerification);
+ expect(toastService.showToast).not.toHaveBeenCalled();
+ expect(component["invalidSecret"]).toBe(initialInvalidSecret);
+ });
+ });
+ });
+});
diff --git a/apps/desktop/src/auth/delete-account.component.ts b/apps/desktop/src/auth/delete-account.component.ts
index b3bad0eba96..15c2b9d669d 100644
--- a/apps/desktop/src/auth/delete-account.component.ts
+++ b/apps/desktop/src/auth/delete-account.component.ts
@@ -50,9 +50,9 @@ export class DeleteAccountComponent implements OnInit {
protected invalidSecret = false;
/**
- * Feature flag for UI Migration Milestone 3
+ * Feature flag for UI Migration Milestone 4
*/
- protected migrationMilestone3 = false;
+ protected migrationMilestone4 = false;
constructor(
private i18nService: I18nService,
@@ -63,8 +63,8 @@ export class DeleteAccountComponent implements OnInit {
) {}
async ngOnInit() {
- this.migrationMilestone3 = await this.configService.getFeatureFlag(
- FeatureFlag.DesktopUiMigrationMilestone3,
+ this.migrationMilestone4 = await this.configService.getFeatureFlag(
+ FeatureFlag.DesktopUiMigrationMilestone4,
);
}
@@ -78,8 +78,8 @@ export class DeleteAccountComponent implements OnInit {
submit = async () => {
try {
- if (this.migrationMilestone3) {
- this.invalidSecret = false; // Reset error state before attempting
+ if (this.migrationMilestone4) {
+ this.invalidSecret = false;
}
const verification = this.deleteForm.get("verification").value;
await this.accountApiService.deleteAccount(verification);
@@ -89,7 +89,7 @@ export class DeleteAccountComponent implements OnInit {
message: this.i18nService.t("accountDeletedDesc"),
});
} catch {
- if (this.migrationMilestone3) {
+ if (this.migrationMilestone4) {
this.invalidSecret = true;
}
}
diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts
index f3afd03b975..5684f6e977a 100644
--- a/libs/common/src/enums/feature-flag.enum.ts
+++ b/libs/common/src/enums/feature-flag.enum.ts
@@ -77,8 +77,9 @@ export enum FeatureFlag {
/* Desktop */
DesktopUiMigrationMilestone1 = "desktop-ui-migration-milestone-1",
- DesktopUiMigrationMilestone3 = "desktop-ui-migration-milestone-3",
DesktopUiMigrationMilestone2 = "desktop-ui-migration-milestone-2",
+ DesktopUiMigrationMilestone3 = "desktop-ui-migration-milestone-3",
+ DesktopUiMigrationMilestone4 = "desktop-ui-migration-milestone-4",
/* UIF */
RouterFocusManagement = "router-focus-management",
@@ -168,8 +169,9 @@ export const DefaultFeatureFlagValue = {
/* Desktop */
[FeatureFlag.DesktopUiMigrationMilestone1]: FALSE,
- [FeatureFlag.DesktopUiMigrationMilestone3]: FALSE,
[FeatureFlag.DesktopUiMigrationMilestone2]: FALSE,
+ [FeatureFlag.DesktopUiMigrationMilestone3]: FALSE,
+ [FeatureFlag.DesktopUiMigrationMilestone4]: FALSE,
/* UIF */
[FeatureFlag.RouterFocusManagement]: FALSE,
@@ -186,12 +188,6 @@ export function getFeatureFlagValue(
serverConfig: ServerConfig | null,
flag: Flag,
) {
- if (flag === FeatureFlag.DesktopUiMigrationMilestone1) {
- return true;
- }
- if (flag === FeatureFlag.DesktopUiMigrationMilestone3) {
- return true;
- }
if (serverConfig?.featureStates == null || serverConfig.featureStates[flag] == null) {
return DefaultFeatureFlagValue[flag];
}