1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-15 15:53:27 +00:00

[PM-15483] PasswordXP-CSV-Importer: Add support for German and Dutch headers (#12216)

* Add tests to verify importing German and Dutch headers work

* Add method to translate the headers from (German/Dutch into English) while the CSV data is being parsed

* Report "importFormatError" when header translation did not work, instead of a generic undefined error (startsWith)

* Move passwordxp-csv-importer into a dedicated folder

* Introduce files with the language header translations

---------

Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
Daniel James Smith
2024-12-17 20:51:58 +01:00
committed by GitHub
parent d1fe72a4ab
commit e2e9a7c345
7 changed files with 117 additions and 39 deletions

View File

@@ -3,10 +3,46 @@ import { CipherType } from "@bitwarden/common/vault/enums";
import { PasswordXPCsvImporter } from "../src/importers";
import { ImportResult } from "../src/models/import-result";
import { dutchHeaders } from "./test-data/passwordxp-csv/dutch-headers";
import { germanHeaders } from "./test-data/passwordxp-csv/german-headers";
import { noFolder } from "./test-data/passwordxp-csv/no-folder.csv";
import { withFolders } from "./test-data/passwordxp-csv/passwordxp-with-folders.csv";
import { withoutFolders } from "./test-data/passwordxp-csv/passwordxp-without-folders.csv";
async function importLoginWithCustomFields(importer: PasswordXPCsvImporter, csvData: string) {
const result: ImportResult = await importer.parse(csvData);
expect(result.success).toBe(true);
const cipher = result.ciphers.shift();
expect(cipher.type).toBe(CipherType.Login);
expect(cipher.name).toBe("Title2");
expect(cipher.notes).toBe("Test Notes");
expect(cipher.login.username).toBe("Username2");
expect(cipher.login.password).toBe("12345678");
expect(cipher.login.uris[0].uri).toBe("http://URL2.com");
expect(cipher.fields.length).toBe(5);
let field = cipher.fields.shift();
expect(field.name).toBe("Account");
expect(field.value).toBe("Account2");
field = cipher.fields.shift();
expect(field.name).toBe("Modified");
expect(field.value).toBe("27-3-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Created");
expect(field.value).toBe("27-3-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Expire on");
expect(field.value).toBe("27-5-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Modified by");
expect(field.value).toBe("someone");
}
describe("PasswordXPCsvImporter", () => {
let importer: PasswordXPCsvImporter;
@@ -20,6 +56,12 @@ describe("PasswordXPCsvImporter", () => {
expect(result.success).toBe(false);
});
it("should return success false if CSV headers did not get translated", async () => {
const data = germanHeaders.replace("Titel;", "UnknownTitle;");
const result: ImportResult = await importer.parse(data);
expect(result.success).toBe(false);
});
it("should skip rows starting with >>>", async () => {
const result: ImportResult = await importer.parse(noFolder);
expect(result.success).toBe(true);
@@ -61,38 +103,16 @@ describe("PasswordXPCsvImporter", () => {
expect(cipher.login.uris[0].uri).toBe("http://test");
});
it("should parse CSV data and import unmapped columns as custom fields", async () => {
const result: ImportResult = await importer.parse(withoutFolders);
expect(result.success).toBe(true);
it("should parse CSV data with English headers and import unmapped columns as custom fields", async () => {
await importLoginWithCustomFields(importer, withoutFolders);
});
const cipher = result.ciphers.shift();
expect(cipher.type).toBe(CipherType.Login);
expect(cipher.name).toBe("Title2");
expect(cipher.notes).toBe("Test Notes");
expect(cipher.login.username).toBe("Username2");
expect(cipher.login.password).toBe("12345678");
expect(cipher.login.uris[0].uri).toBe("http://URL2.com");
it("should parse CSV data with German headers and import unmapped columns as custom fields", async () => {
await importLoginWithCustomFields(importer, germanHeaders);
});
expect(cipher.fields.length).toBe(5);
let field = cipher.fields.shift();
expect(field.name).toBe("Account");
expect(field.value).toBe("Account2");
field = cipher.fields.shift();
expect(field.name).toBe("Modified");
expect(field.value).toBe("27-3-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Created");
expect(field.value).toBe("27-3-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Expire on");
expect(field.value).toBe("27-5-2024 08:11:21");
field = cipher.fields.shift();
expect(field.name).toBe("Modified by");
expect(field.value).toBe("someone");
it("should parse CSV data with Dutch headers and import unmapped columns as custom fields", async () => {
await importLoginWithCustomFields(importer, dutchHeaders);
});
it("should parse CSV data with folders and assign items to them", async () => {