mirror of
https://github.com/bitwarden/browser
synced 2025-12-23 11:43:46 +00:00
[PM-22693] Firefox - After creating a new item, the View Item screen is blank (#15868)
* Updated get cipher data to retrieve data from observable * Fixed tests
This commit is contained in:
@@ -78,14 +78,14 @@ describe("ViewV2Component", () => {
|
||||
const accountService: FakeAccountService = mockAccountServiceWith(mockUserId);
|
||||
|
||||
const mockCipherService = {
|
||||
get: jest.fn().mockResolvedValue({ decrypt: jest.fn().mockResolvedValue(mockCipher) }),
|
||||
cipherViews$: jest.fn().mockImplementation((userId) => of([mockCipher])),
|
||||
getKeyForCipherKeyDecryption: jest.fn().mockResolvedValue({}),
|
||||
deleteWithServer: jest.fn().mockResolvedValue(undefined),
|
||||
softDeleteWithServer: jest.fn().mockResolvedValue(undefined),
|
||||
decrypt: jest.fn().mockResolvedValue(mockCipher),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
mockCipherService.cipherViews$.mockClear();
|
||||
mockCipherService.deleteWithServer.mockClear();
|
||||
mockCipherService.softDeleteWithServer.mockClear();
|
||||
mockNavigate.mockClear();
|
||||
@@ -162,7 +162,7 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(mockCipherService.get).toHaveBeenCalledWith("122-333-444", mockUserId);
|
||||
expect(mockCipherService.cipherViews$).toHaveBeenCalledWith(mockUserId);
|
||||
expect(component.cipher).toEqual(mockCipher);
|
||||
}));
|
||||
|
||||
@@ -210,7 +210,7 @@ describe("ViewV2Component", () => {
|
||||
}));
|
||||
|
||||
it('invokes `doAutofill` when action="AUTOFILL_ID"', fakeAsync(() => {
|
||||
params$.next({ action: AUTOFILL_ID });
|
||||
params$.next({ action: AUTOFILL_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
@@ -218,7 +218,7 @@ describe("ViewV2Component", () => {
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-username"', fakeAsync(() => {
|
||||
params$.next({ action: COPY_USERNAME_ID });
|
||||
params$.next({ action: COPY_USERNAME_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
@@ -226,7 +226,7 @@ describe("ViewV2Component", () => {
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-password"', fakeAsync(() => {
|
||||
params$.next({ action: COPY_PASSWORD_ID });
|
||||
params$.next({ action: COPY_PASSWORD_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
@@ -234,7 +234,7 @@ describe("ViewV2Component", () => {
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-totp"', fakeAsync(() => {
|
||||
params$.next({ action: COPY_VERIFICATION_CODE_ID });
|
||||
params$.next({ action: COPY_VERIFICATION_CODE_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
@@ -243,11 +243,13 @@ describe("ViewV2Component", () => {
|
||||
|
||||
it("does not set the cipher until reprompt is complete", fakeAsync(() => {
|
||||
let promptPromise: (val?: unknown) => void;
|
||||
mockCipherService.decrypt.mockImplementationOnce(() =>
|
||||
Promise.resolve({
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
}),
|
||||
mockCipherService.cipherViews$.mockImplementationOnce((userId) =>
|
||||
of([
|
||||
{
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
},
|
||||
]),
|
||||
);
|
||||
doAutofill.mockImplementationOnce(() => {
|
||||
return new Promise((resolve) => {
|
||||
@@ -256,7 +258,7 @@ describe("ViewV2Component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
params$.next({ action: AUTOFILL_ID });
|
||||
params$.next({ action: AUTOFILL_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Flush all pending actions
|
||||
|
||||
@@ -271,11 +273,13 @@ describe("ViewV2Component", () => {
|
||||
|
||||
it("does not set the cipher at all if doAutofill fails and reprompt is active", fakeAsync(() => {
|
||||
let promptPromise: (val?: unknown) => void;
|
||||
mockCipherService.decrypt.mockImplementationOnce(() =>
|
||||
Promise.resolve({
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
}),
|
||||
mockCipherService.cipherViews$.mockImplementationOnce((userId) =>
|
||||
of([
|
||||
{
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
},
|
||||
]),
|
||||
);
|
||||
doAutofill.mockImplementationOnce(() => {
|
||||
return new Promise((resolve) => {
|
||||
@@ -284,7 +288,7 @@ describe("ViewV2Component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
params$.next({ action: AUTOFILL_ID });
|
||||
params$.next({ action: AUTOFILL_ID, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Flush all pending actions
|
||||
|
||||
@@ -301,11 +305,13 @@ describe("ViewV2Component", () => {
|
||||
"does not set cipher when copy fails for %s",
|
||||
fakeAsync((action: string) => {
|
||||
let promptPromise: (val?: unknown) => void;
|
||||
mockCipherService.decrypt.mockImplementationOnce(() =>
|
||||
Promise.resolve({
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
}),
|
||||
mockCipherService.cipherViews$.mockImplementationOnce((userId) =>
|
||||
of([
|
||||
{
|
||||
...mockCipher,
|
||||
reprompt: CipherRepromptType.Password,
|
||||
},
|
||||
]),
|
||||
);
|
||||
copy.mockImplementationOnce(() => {
|
||||
return new Promise((resolve) => {
|
||||
@@ -314,7 +320,7 @@ describe("ViewV2Component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
params$.next({ action });
|
||||
params$.next({ action, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Flush all pending actions
|
||||
|
||||
@@ -336,7 +342,7 @@ describe("ViewV2Component", () => {
|
||||
.spyOn(BrowserApi, "focusTab")
|
||||
.mockImplementation(() => Promise.resolve());
|
||||
|
||||
params$.next({ action: AUTOFILL_ID, senderTabId: 99 });
|
||||
params$.next({ action: AUTOFILL_ID, senderTabId: 99, cipherId: mockCipher.id });
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Component } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { firstValueFrom, Observable, switchMap, of } from "rxjs";
|
||||
import { firstValueFrom, Observable, switchMap, of, map } from "rxjs";
|
||||
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
@@ -209,8 +209,12 @@ export class ViewV2Component {
|
||||
}
|
||||
|
||||
async getCipherData(id: string, userId: UserId) {
|
||||
const cipher = await this.cipherService.get(id, userId);
|
||||
return await this.cipherService.decrypt(cipher, userId);
|
||||
return await firstValueFrom(
|
||||
this.cipherService.cipherViews$(userId).pipe(
|
||||
filterOutNullish(),
|
||||
map((ciphers) => ciphers.find((c) => c.id === id)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async editCipher() {
|
||||
|
||||
Reference in New Issue
Block a user