in components/places/src/db/schema.rs [426:629]
fn test_bookmark_check_constraints() {
let conn = PlacesDb::open_in_memory(ConnectionType::ReadWrite).expect("no memory db");
conn.execute_batch(
"INSERT INTO moz_places(id, guid, url, frecency)
VALUES(1, 'page_guid___', 'https://example.com', -1);",
)
.expect("should insert page");
// type==BOOKMARK but null fk
{
let e = conn
.execute_cached(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified, guid)
VALUES
(NULL, 1, 0, 0, 1, 1, 'fake_guid___')",
[],
)
.expect_err("should fail to insert bookmark with NULL fk");
assert!(
e.to_string().contains("insert: type=1; fk NULL"),
"Expected error, got: {:?}",
e,
);
conn.execute_batch(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified,
guid)
VALUES
(1, 1, (SELECT id FROM moz_bookmarks WHERE guid = 'root________'), 0, 1, 1,
'bmk_guid____')",
)
.expect("should insert bookmark");
let e = conn
.execute(
"UPDATE moz_bookmarks SET
fk = NULL
WHERE guid = 'bmk_guid____'",
[],
)
.expect_err("should fail to update bookmark with NULL fk");
assert!(
e.to_string().contains("update: type=1; fk NULL"),
"Expected error, got: {:?}",
e,
);
}
// type!=BOOKMARK and non-null fk
{
let e = conn
.execute_cached(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified, guid)
VALUES
(1, 2, 0, 0, 1, 1, 'fake_guid___')",
[],
)
.expect_err("should fail to insert folder with non-NULL fk");
assert!(
e.to_string().contains("insert: type=2; fk NOT NULL"),
"Expected error, got: {:?}",
e,
);
conn.execute_batch(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified,
guid)
VALUES
(NULL, 2, (SELECT id FROM moz_bookmarks WHERE guid = 'root________'), 1, 1, 1,
'folder_guid_')",
)
.expect("should insert folder");
let e = conn
.execute(
"UPDATE moz_bookmarks SET
fk = 1
WHERE guid = 'folder_guid_'",
[],
)
.expect_err("should fail to update folder with non-NULL fk");
assert!(
e.to_string().contains("update: type=2; fk NOT NULL"),
"Expected error, got: {:?}",
e,
);
}
// null parent for item other than the root
{
let e = conn
.execute_cached(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified, guid)
VALUES
(NULL, 2, NULL, 0, 1, 1, 'fake_guid___')",
[],
)
.expect_err("should fail to insert item with NULL parent");
assert!(
e.to_string().contains("insert: item without parent"),
"Expected error, got: {:?}",
e,
);
let e = conn
.execute_cached(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified, guid)
VALUES
(NULL, 2, -1, 0, 1, 1, 'fake_guid___')",
[],
)
.expect_err("should fail to insert item with nonexistent parent");
assert!(
e.to_string().contains("insert: item without parent"),
"Expected error, got: {:?}",
e,
);
let e = conn
.execute(
"UPDATE moz_bookmarks SET
parent = NULL
WHERE guid = 'folder_guid_'",
[],
)
.expect_err("should fail to update folder with NULL parent");
assert!(
e.to_string().contains("update: item without parent"),
"Expected error, got: {:?}",
e,
);
// Bug 1941655 - we only guard against NULL parents, not missing ones.
/*
let e = conn
.execute(
"UPDATE moz_bookmarks SET
parent = -1
WHERE guid = 'folder_guid_'",
[],
)
.expect_err("should fail to update folder with nonexistent parent");
assert!(
e.to_string().contains("update: item without parent"),
"Expected error, got: {:?}",
e,
);
*/
}
// Invalid length guid
{
let e = conn
.execute_cached(
"INSERT INTO moz_bookmarks
(fk, type, parent, position, dateAdded, lastModified, guid)
VALUES
(NULL, 2, 0, 0, 1, 1, 'fake_guid')",
[],
)
.expect_err("should fail");
assert!(
e.to_string().contains("insert: len(guid)=9"),
"Expected error, got: {:?}",
e,
);
let e = conn
.execute(
"UPDATE moz_bookmarks SET
guid = 'fake_guid'
WHERE guid = 'bmk_guid____'",
[],
)
.expect_err("should fail to update bookmark with invalid guid");
assert!(
e.to_string().contains("update: len(guid)=9"),
"Expected error, got: {:?}",
e,
);
}
// Changing the type of an existing item.
{
let e = conn
.execute(
"UPDATE moz_bookmarks SET
type = 3
WHERE guid = 'folder_guid_'",
[],
)
.expect_err("should fail to update type of bookmark");
assert!(
e.to_string().contains("update: old type=2; new=3"),
"Expected error, got: {:?}",
e,
);
}
}