fn test_bookmark_check_constraints()

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,
            );
        }
    }