use linked types from the cipher prototype (#10167)
- When adding a new cipher the cipher view isn't defined yet
This commit is contained in:
parent
457c0795be
commit
019c5d6677
|
@ -6,13 +6,19 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
|
|||
import { By } from "@angular/platform-browser";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { CipherType, FieldType, LoginLinkedId } from "@bitwarden/common/vault/enums";
|
||||
import {
|
||||
CardLinkedId,
|
||||
CipherType,
|
||||
FieldType,
|
||||
IdentityLinkedId,
|
||||
LoginLinkedId,
|
||||
} from "@bitwarden/common/vault/enums";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
|
||||
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
import { BitPasswordInputToggleDirective } from "../../../../../components/src/form-field/password-input-toggle.directive";
|
||||
import { CipherFormConfig } from "../../abstractions/cipher-form-config.service";
|
||||
import { CipherFormContainer } from "../../cipher-form-container";
|
||||
|
||||
import { CustomField, CustomFieldsComponent } from "./custom-fields.component";
|
||||
|
@ -25,8 +31,6 @@ const mockFieldViews = [
|
|||
] as FieldView[];
|
||||
|
||||
let originalCipherView: CipherView | null = new CipherView();
|
||||
originalCipherView.type = CipherType.Login;
|
||||
originalCipherView.login = new LoginView();
|
||||
|
||||
describe("CustomFieldsComponent", () => {
|
||||
let component: CustomFieldsComponent;
|
||||
|
@ -34,14 +38,14 @@ describe("CustomFieldsComponent", () => {
|
|||
let open: jest.Mock;
|
||||
let announce: jest.Mock;
|
||||
let patchCipher: jest.Mock;
|
||||
let config: CipherFormConfig;
|
||||
|
||||
beforeEach(async () => {
|
||||
open = jest.fn();
|
||||
announce = jest.fn().mockResolvedValue(null);
|
||||
patchCipher = jest.fn();
|
||||
originalCipherView = new CipherView();
|
||||
originalCipherView.type = CipherType.Login;
|
||||
originalCipherView.login = new LoginView();
|
||||
config = {} as CipherFormConfig;
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [CustomFieldsComponent],
|
||||
|
@ -52,7 +56,7 @@ describe("CustomFieldsComponent", () => {
|
|||
},
|
||||
{
|
||||
provide: CipherFormContainer,
|
||||
useValue: { patchCipher, originalCipherView, registerChildForm: jest.fn(), config: {} },
|
||||
useValue: { patchCipher, originalCipherView, registerChildForm: jest.fn(), config },
|
||||
},
|
||||
{
|
||||
provide: LiveAnnouncer,
|
||||
|
@ -73,20 +77,6 @@ describe("CustomFieldsComponent", () => {
|
|||
});
|
||||
|
||||
describe("initializing", () => {
|
||||
it("populates linkedFieldOptions", () => {
|
||||
originalCipherView.login.linkedFieldOptions = new Map([
|
||||
[1, { i18nKey: "one-i18", propertyKey: "one" }],
|
||||
[2, { i18nKey: "two-i18", propertyKey: "two" }],
|
||||
]);
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.linkedFieldOptions).toEqual([
|
||||
{ value: 1, name: "one-i18" },
|
||||
{ value: 2, name: "two-i18" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("populates customFieldsForm", () => {
|
||||
originalCipherView.fields = mockFieldViews;
|
||||
|
||||
|
@ -130,6 +120,50 @@ describe("CustomFieldsComponent", () => {
|
|||
|
||||
expect(button.nativeElement.disabled).toBe(true);
|
||||
});
|
||||
|
||||
describe("linkedFieldOptions", () => {
|
||||
/** Retrieve the numerical values of an enum object */
|
||||
const getEnumValues = (enumType: object) =>
|
||||
Object.values(enumType).filter((v) => typeof v === "number");
|
||||
|
||||
it("populates for login ciphers", () => {
|
||||
config.cipherType = CipherType.Login;
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.linkedFieldOptions.map((o) => o.value)).toEqual(
|
||||
expect.arrayContaining(getEnumValues(LoginLinkedId)),
|
||||
);
|
||||
});
|
||||
|
||||
it("populates for card ciphers", () => {
|
||||
config.cipherType = CipherType.Card;
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.linkedFieldOptions.map((o) => o.value)).toEqual(
|
||||
expect.arrayContaining(getEnumValues(CardLinkedId)),
|
||||
);
|
||||
});
|
||||
|
||||
it("populates for identity ciphers", () => {
|
||||
config.cipherType = CipherType.Identity;
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.linkedFieldOptions.map((o) => o.value)).toEqual(
|
||||
expect.arrayContaining(getEnumValues(IdentityLinkedId)),
|
||||
);
|
||||
});
|
||||
|
||||
it("sets an empty array for note ciphers", () => {
|
||||
config.cipherType = CipherType.SecureNote;
|
||||
|
||||
component.ngOnInit();
|
||||
|
||||
expect(component.linkedFieldOptions).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("adding new field", () => {
|
||||
|
|
|
@ -21,8 +21,11 @@ import { Subject, switchMap, take } from "rxjs";
|
|||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { FieldType, LinkedIdType } from "@bitwarden/common/vault/enums";
|
||||
import { CipherType, FieldType, LinkedIdType } from "@bitwarden/common/vault/enums";
|
||||
import { CardView } from "@bitwarden/common/vault/models/view/card.view";
|
||||
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
|
||||
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";
|
||||
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
|
||||
import {
|
||||
DialogService,
|
||||
SectionComponent,
|
||||
|
@ -131,10 +134,9 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
const linkedFieldsOptionsForCipher = this.getLinkedFieldsOptionsForCipher();
|
||||
// Populate options for linked custom fields
|
||||
this.linkedFieldOptions = Array.from(
|
||||
this.cipherFormContainer.originalCipherView?.linkedFieldOptions?.entries() ?? [],
|
||||
)
|
||||
this.linkedFieldOptions = Array.from(linkedFieldsOptionsForCipher?.entries() ?? [])
|
||||
.map(([id, linkedFieldOption]) => ({
|
||||
name: this.i18nService.t(linkedFieldOption.i18nKey),
|
||||
value: id,
|
||||
|
@ -303,6 +305,24 @@ export class CustomFieldsComponent implements OnInit, AfterViewInit {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the linked field options for the current cipher type
|
||||
*
|
||||
* Note: Note ciphers do not have linked fields
|
||||
*/
|
||||
private getLinkedFieldsOptionsForCipher() {
|
||||
switch (this.cipherFormContainer.config.cipherType) {
|
||||
case CipherType.Login:
|
||||
return LoginView.prototype.linkedFieldOptions;
|
||||
case CipherType.Card:
|
||||
return CardView.prototype.linkedFieldOptions;
|
||||
case CipherType.Identity:
|
||||
return IdentityView.prototype.linkedFieldOptions;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Create `FieldView` from the form objects and update the cipher */
|
||||
private updateCipher(fields: CustomField[]) {
|
||||
const newFields = fields.map((field: CustomField) => {
|
||||
|
|
Loading…
Reference in New Issue