feat(core): import_lastpass parser — happy-path Login
Pins the parse_lastpass_csv signature and ImportWarning shape. A single LastPass row with name/url/username/password round-trips to a Login item with a freshly-minted ID. Header validation rejects shape mismatches with a clear message. TOTP, grouping, fav, SecureNote rows, and error paths land in Tasks 3-6. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
46
crates/relicario-core/tests/import_lastpass.rs
Normal file
46
crates/relicario-core/tests/import_lastpass.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
//! LastPass CSV importer — parser coverage.
|
||||
|
||||
use relicario_core::import_lastpass::{parse_lastpass_csv, ImportWarning};
|
||||
use relicario_core::ItemCore;
|
||||
|
||||
const HEADER: &str = "url,username,password,totp,extra,name,grouping,fav";
|
||||
|
||||
#[test]
|
||||
fn single_login_row_round_trips() {
|
||||
let csv = format!(
|
||||
"{HEADER}\n\
|
||||
https://github.com/login,alice,hunter2,,,GitHub,,",
|
||||
);
|
||||
let (items, warnings) = parse_lastpass_csv(csv.as_bytes()).unwrap();
|
||||
assert_eq!(items.len(), 1, "one item expected");
|
||||
assert!(warnings.is_empty(), "no warnings expected");
|
||||
|
||||
let item = &items[0];
|
||||
assert_eq!(item.title, "GitHub");
|
||||
assert!(!item.favorite);
|
||||
assert!(item.group.is_none());
|
||||
match &item.core {
|
||||
ItemCore::Login(l) => {
|
||||
assert_eq!(l.username.as_deref(), Some("alice"));
|
||||
assert_eq!(l.password.as_deref().map(String::as_str), Some("hunter2"));
|
||||
assert_eq!(l.url.as_ref().map(|u| u.as_str()), Some("https://github.com/login"));
|
||||
assert!(l.totp.is_none());
|
||||
}
|
||||
other => panic!("expected Login, got {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn item_id_is_freshly_minted() {
|
||||
// Decision D12: title collisions don't dedupe; each row gets a fresh ID.
|
||||
let csv = format!("{HEADER}\nhttps://x,u,p,,,Same,,\nhttps://x,u,p,,,Same,,");
|
||||
let (items, _) = parse_lastpass_csv(csv.as_bytes()).unwrap();
|
||||
assert_eq!(items.len(), 2);
|
||||
assert_ne!(items[0].id, items[1].id, "IDs must be unique even for identical names");
|
||||
}
|
||||
|
||||
// Assertion helper used by later tests.
|
||||
#[allow(dead_code)]
|
||||
fn first_warning_message(warnings: &[ImportWarning]) -> String {
|
||||
warnings.first().expect("expected at least one warning").message.clone()
|
||||
}
|
||||
Reference in New Issue
Block a user