lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

error_paths.rs (32769B)


      1 use radroots_replica_db::ReplicaSql;
      2 use radroots_replica_db_schema::farm::{
      3     IFarmCreate, IFarmDelete, IFarmFindMany, IFarmFindOne, IFarmUpdate,
      4 };
      5 use radroots_replica_db_schema::farm_gcs_location::{
      6     IFarmGcsLocationCreate, IFarmGcsLocationDelete, IFarmGcsLocationFindMany,
      7     IFarmGcsLocationFindOne, IFarmGcsLocationUpdate,
      8 };
      9 use radroots_replica_db_schema::farm_member::{
     10     IFarmMemberCreate, IFarmMemberDelete, IFarmMemberFindMany, IFarmMemberFindOne,
     11     IFarmMemberUpdate,
     12 };
     13 use radroots_replica_db_schema::farm_member_claim::{
     14     IFarmMemberClaimCreate, IFarmMemberClaimDelete, IFarmMemberClaimFindMany,
     15     IFarmMemberClaimFindOne, IFarmMemberClaimUpdate,
     16 };
     17 use radroots_replica_db_schema::farm_tag::{
     18     IFarmTagCreate, IFarmTagDelete, IFarmTagFindMany, IFarmTagFindOne, IFarmTagUpdate,
     19 };
     20 use radroots_replica_db_schema::gcs_location::{
     21     IGcsLocationCreate, IGcsLocationDelete, IGcsLocationFindMany, IGcsLocationFindOne,
     22     IGcsLocationUpdate,
     23 };
     24 use radroots_replica_db_schema::log_error::{
     25     ILogErrorCreate, ILogErrorDelete, ILogErrorFindMany, ILogErrorFindOne, ILogErrorUpdate,
     26 };
     27 use radroots_replica_db_schema::media_image::{
     28     IMediaImageCreate, IMediaImageDelete, IMediaImageFindMany, IMediaImageFindOne,
     29     IMediaImageUpdate,
     30 };
     31 use radroots_replica_db_schema::nostr_event_head::{
     32     INostrEventHeadCreate, INostrEventHeadDelete, INostrEventHeadFindMany, INostrEventHeadFindOne,
     33     INostrEventHeadUpdate,
     34 };
     35 use radroots_replica_db_schema::nostr_profile::{
     36     INostrProfileCreate, INostrProfileDelete, INostrProfileFindMany, INostrProfileFindOne,
     37     INostrProfileUpdate,
     38 };
     39 use radroots_replica_db_schema::nostr_profile_relay::INostrProfileRelayRelation;
     40 use radroots_replica_db_schema::nostr_relay::{
     41     INostrRelayCreate, INostrRelayDelete, INostrRelayFindMany, INostrRelayFindOne,
     42     INostrRelayUpdate,
     43 };
     44 use radroots_replica_db_schema::plot::{
     45     IPlotCreate, IPlotDelete, IPlotFindMany, IPlotFindOne, IPlotUpdate,
     46 };
     47 use radroots_replica_db_schema::plot_gcs_location::{
     48     IPlotGcsLocationCreate, IPlotGcsLocationDelete, IPlotGcsLocationFindMany,
     49     IPlotGcsLocationFindOne, IPlotGcsLocationUpdate,
     50 };
     51 use radroots_replica_db_schema::plot_tag::{
     52     IPlotTagCreate, IPlotTagDelete, IPlotTagFindMany, IPlotTagFindOne, IPlotTagUpdate,
     53 };
     54 use radroots_replica_db_schema::trade_product::{
     55     ITradeProductCreate, ITradeProductDelete, ITradeProductFindMany, ITradeProductFindOne,
     56     ITradeProductUpdate,
     57 };
     58 use radroots_replica_db_schema::trade_product_location::ITradeProductLocationRelation;
     59 use radroots_replica_db_schema::trade_product_media::ITradeProductMediaRelation;
     60 use radroots_sql_core::{SqlError, SqlExecutor, SqliteExecutor};
     61 use radroots_types::types::IError;
     62 use serde::de::DeserializeOwned;
     63 use serde_json::json;
     64 
     65 fn parse_json<T: DeserializeOwned>(value: serde_json::Value) -> T {
     66     serde_json::from_value(value).expect("valid test payload")
     67 }
     68 
     69 fn hex64(ch: char) -> String {
     70     std::iter::repeat_n(ch, 64).collect()
     71 }
     72 
     73 fn open_db() -> ReplicaSql<SqliteExecutor> {
     74     let exec = SqliteExecutor::open_memory().expect("open sqlite memory");
     75     let db = ReplicaSql::new(exec);
     76     db.migrate_up().expect("migrate up");
     77     db
     78 }
     79 
     80 fn drop_table(db: &ReplicaSql<SqliteExecutor>, table_name: &str) {
     81     let sql = format!("DROP TABLE {table_name};");
     82     db.executor().exec(&sql, "[]").expect("drop table");
     83 }
     84 
     85 fn assert_invalid_query<T>(result: Result<T, IError<SqlError>>) {
     86     let err = match result {
     87         Ok(_) => panic!("invalid query expected"),
     88         Err(err) => err,
     89     };
     90     assert!(matches!(err.err, SqlError::InvalidQuery(_)));
     91 }
     92 
     93 fn assert_not_found<T>(result: Result<T, IError<SqlError>>) {
     94     let err = match result {
     95         Ok(_) => panic!("not found expected"),
     96         Err(err) => err,
     97     };
     98     assert!(matches!(err.err, SqlError::NotFound(_)));
     99 }
    100 
    101 #[test]
    102 fn gcs_location_error_paths_cover_regions() {
    103     let db = open_db();
    104 
    105     let update_missing: IGcsLocationUpdate = parse_json(json!({
    106         "on": { "d_tag": "missing-gcs" },
    107         "fields": { "label": "x" }
    108     }));
    109     assert_not_found(db.gcs_location_update(&update_missing));
    110 
    111     let delete_missing_on: IGcsLocationDelete = parse_json(json!({
    112         "on": { "d_tag": "missing-gcs" }
    113     }));
    114     assert_not_found(db.gcs_location_delete(&delete_missing_on));
    115 
    116     let delete_missing_rel: IGcsLocationDelete = parse_json(json!({
    117         "rel": { "off_plot": { "id": "missing-plot" } }
    118     }));
    119     assert_not_found(db.gcs_location_delete(&delete_missing_rel));
    120 
    121     drop_table(&db, "gcs_location");
    122 
    123     let create_opts: IGcsLocationCreate = parse_json(json!({
    124         "d_tag": "gcs-a",
    125         "lat": 59.33,
    126         "lng": 18.06,
    127         "geohash": "u6sce4f",
    128         "point": "POINT(18.06 59.33)",
    129         "polygon": "POLYGON((18.06 59.33,18.07 59.33,18.07 59.34,18.06 59.34,18.06 59.33))"
    130     }));
    131     assert_invalid_query(db.gcs_location_create(&create_opts));
    132 
    133     let find_many_filter: IGcsLocationFindMany = parse_json(json!({
    134         "filter": { "id": "id-1" }
    135     }));
    136     assert_invalid_query(db.gcs_location_find_many(&find_many_filter));
    137 
    138     let find_many_rel: IGcsLocationFindMany = parse_json(json!({
    139         "rel": { "on_farm": { "id": "farm-1" } }
    140     }));
    141     assert_invalid_query(db.gcs_location_find_many(&find_many_rel));
    142 
    143     let find_one_on: IGcsLocationFindOne = parse_json(json!({
    144         "on": { "id": "id-1" }
    145     }));
    146     assert_invalid_query(db.gcs_location_find_one(&find_one_on));
    147 
    148     let find_one_rel: IGcsLocationFindOne = parse_json(json!({
    149         "rel": { "off_trade_product": { "id": "tp-1" } }
    150     }));
    151     assert_invalid_query(db.gcs_location_find_one(&find_one_rel));
    152 
    153     let update_id: IGcsLocationUpdate = parse_json(json!({
    154         "on": { "id": "id-1" },
    155         "fields": { "label": "x" }
    156     }));
    157     assert_invalid_query(db.gcs_location_update(&update_id));
    158 
    159     let delete_id: IGcsLocationDelete = parse_json(json!({
    160         "on": { "id": "id-1" }
    161     }));
    162     assert_invalid_query(db.gcs_location_delete(&delete_id));
    163 
    164     let delete_rel: IGcsLocationDelete = parse_json(json!({
    165         "rel": { "on_plot": { "id": "plot-1" } }
    166     }));
    167     assert_invalid_query(db.gcs_location_delete(&delete_rel));
    168 }
    169 
    170 #[test]
    171 fn media_image_error_paths_cover_regions() {
    172     let db = open_db();
    173 
    174     let update_missing: IMediaImageUpdate = parse_json(json!({
    175         "on": { "file_path": "/missing.jpg" },
    176         "fields": { "label": "x" }
    177     }));
    178     assert_not_found(db.media_image_update(&update_missing));
    179 
    180     let delete_missing_on: IMediaImageDelete = parse_json(json!({
    181         "on": { "file_path": "/missing.jpg" }
    182     }));
    183     assert_not_found(db.media_image_delete(&delete_missing_on));
    184 
    185     let delete_missing_rel: IMediaImageDelete = parse_json(json!({
    186         "rel": { "off_trade_product": { "id": "missing-tp" } }
    187     }));
    188     assert_not_found(db.media_image_delete(&delete_missing_rel));
    189 
    190     drop_table(&db, "media_image");
    191 
    192     let create_opts: IMediaImageCreate = parse_json(json!({
    193         "file_path": "/img/a.jpg",
    194         "mime_type": "image/jpeg",
    195         "res_base": "https://cdn.example.com",
    196         "res_path": "img/a.jpg"
    197     }));
    198     assert_invalid_query(db.media_image_create(&create_opts));
    199 
    200     let find_many_filter: IMediaImageFindMany = parse_json(json!({
    201         "filter": { "id": "id-1" }
    202     }));
    203     assert_invalid_query(db.media_image_find_many(&find_many_filter));
    204 
    205     let find_many_rel: IMediaImageFindMany = parse_json(json!({
    206         "rel": { "on_trade_product": { "id": "tp-1" } }
    207     }));
    208     assert_invalid_query(db.media_image_find_many(&find_many_rel));
    209 
    210     let find_one_on: IMediaImageFindOne = parse_json(json!({
    211         "on": { "id": "id-1" }
    212     }));
    213     assert_invalid_query(db.media_image_find_one(&find_one_on));
    214 
    215     let find_one_rel: IMediaImageFindOne = parse_json(json!({
    216         "rel": { "off_trade_product": { "id": "tp-1" } }
    217     }));
    218     assert_invalid_query(db.media_image_find_one(&find_one_rel));
    219 
    220     let update_id: IMediaImageUpdate = parse_json(json!({
    221         "on": { "id": "id-1" },
    222         "fields": { "label": "x" }
    223     }));
    224     assert_invalid_query(db.media_image_update(&update_id));
    225 
    226     let delete_id: IMediaImageDelete = parse_json(json!({
    227         "on": { "id": "id-1" }
    228     }));
    229     assert_invalid_query(db.media_image_delete(&delete_id));
    230 
    231     let delete_rel: IMediaImageDelete = parse_json(json!({
    232         "rel": { "on_trade_product": { "id": "tp-1" } }
    233     }));
    234     assert_invalid_query(db.media_image_delete(&delete_rel));
    235 }
    236 
    237 #[test]
    238 fn nostr_profile_error_paths_cover_regions() {
    239     let db = open_db();
    240 
    241     let update_missing: INostrProfileUpdate = parse_json(json!({
    242         "on": { "public_key": hex64('a') },
    243         "fields": { "name": "x" }
    244     }));
    245     assert_not_found(db.nostr_profile_update(&update_missing));
    246 
    247     let delete_missing_on: INostrProfileDelete = parse_json(json!({
    248         "on": { "public_key": hex64('a') }
    249     }));
    250     assert_not_found(db.nostr_profile_delete(&delete_missing_on));
    251 
    252     let delete_missing_rel: INostrProfileDelete = parse_json(json!({
    253         "rel": { "off_relay": { "id": "missing-relay" } }
    254     }));
    255     assert_not_found(db.nostr_profile_delete(&delete_missing_rel));
    256 
    257     drop_table(&db, "nostr_profile");
    258 
    259     let create_opts: INostrProfileCreate = parse_json(json!({
    260         "public_key": hex64('d'),
    261         "profile_type": "farm",
    262         "name": "profile a"
    263     }));
    264     assert_invalid_query(db.nostr_profile_create(&create_opts));
    265 
    266     let find_many_filter: INostrProfileFindMany = parse_json(json!({
    267         "filter": { "id": "id-1" }
    268     }));
    269     assert_invalid_query(db.nostr_profile_find_many(&find_many_filter));
    270 
    271     let find_many_rel: INostrProfileFindMany = parse_json(json!({
    272         "rel": { "on_relay": { "id": "relay-1" } }
    273     }));
    274     assert_invalid_query(db.nostr_profile_find_many(&find_many_rel));
    275 
    276     let find_one_on: INostrProfileFindOne = parse_json(json!({
    277         "on": { "id": "id-1" }
    278     }));
    279     assert_invalid_query(db.nostr_profile_find_one(&find_one_on));
    280 
    281     let find_one_rel: INostrProfileFindOne = parse_json(json!({
    282         "rel": { "off_relay": { "id": "relay-1" } }
    283     }));
    284     assert_invalid_query(db.nostr_profile_find_one(&find_one_rel));
    285 
    286     let update_id: INostrProfileUpdate = parse_json(json!({
    287         "on": { "id": "id-1" },
    288         "fields": { "name": "x" }
    289     }));
    290     assert_invalid_query(db.nostr_profile_update(&update_id));
    291 
    292     let delete_id: INostrProfileDelete = parse_json(json!({
    293         "on": { "id": "id-1" }
    294     }));
    295     assert_invalid_query(db.nostr_profile_delete(&delete_id));
    296 
    297     let delete_rel: INostrProfileDelete = parse_json(json!({
    298         "rel": { "on_relay": { "id": "relay-1" } }
    299     }));
    300     assert_invalid_query(db.nostr_profile_delete(&delete_rel));
    301 }
    302 
    303 #[test]
    304 fn nostr_relay_error_paths_cover_regions() {
    305     let db = open_db();
    306 
    307     let update_missing: INostrRelayUpdate = parse_json(json!({
    308         "on": { "url": "wss://missing.example.com" },
    309         "fields": { "name": "x" }
    310     }));
    311     assert_not_found(db.nostr_relay_update(&update_missing));
    312 
    313     let delete_missing_on: INostrRelayDelete = parse_json(json!({
    314         "on": { "url": "wss://missing.example.com" }
    315     }));
    316     assert_not_found(db.nostr_relay_delete(&delete_missing_on));
    317 
    318     let delete_missing_rel: INostrRelayDelete = parse_json(json!({
    319         "rel": { "off_profile": { "public_key": hex64('b') } }
    320     }));
    321     assert_not_found(db.nostr_relay_delete(&delete_missing_rel));
    322 
    323     drop_table(&db, "nostr_relay");
    324 
    325     let create_opts: INostrRelayCreate = parse_json(json!({
    326         "url": "wss://relay.example.com"
    327     }));
    328     assert_invalid_query(db.nostr_relay_create(&create_opts));
    329 
    330     let find_many_filter: INostrRelayFindMany = parse_json(json!({
    331         "filter": { "id": "id-1" }
    332     }));
    333     assert_invalid_query(db.nostr_relay_find_many(&find_many_filter));
    334 
    335     let find_many_rel: INostrRelayFindMany = parse_json(json!({
    336         "rel": { "on_profile": { "public_key": hex64('d') } }
    337     }));
    338     assert_invalid_query(db.nostr_relay_find_many(&find_many_rel));
    339 
    340     let find_one_on: INostrRelayFindOne = parse_json(json!({
    341         "on": { "id": "id-1" }
    342     }));
    343     assert_invalid_query(db.nostr_relay_find_one(&find_one_on));
    344 
    345     let find_one_rel: INostrRelayFindOne = parse_json(json!({
    346         "rel": { "off_profile": { "public_key": hex64('d') } }
    347     }));
    348     assert_invalid_query(db.nostr_relay_find_one(&find_one_rel));
    349 
    350     let update_id: INostrRelayUpdate = parse_json(json!({
    351         "on": { "id": "id-1" },
    352         "fields": { "name": "x" }
    353     }));
    354     assert_invalid_query(db.nostr_relay_update(&update_id));
    355 
    356     let delete_id: INostrRelayDelete = parse_json(json!({
    357         "on": { "id": "id-1" }
    358     }));
    359     assert_invalid_query(db.nostr_relay_delete(&delete_id));
    360 
    361     let delete_rel: INostrRelayDelete = parse_json(json!({
    362         "rel": { "on_profile": { "public_key": hex64('d') } }
    363     }));
    364     assert_invalid_query(db.nostr_relay_delete(&delete_rel));
    365 }
    366 
    367 #[test]
    368 fn farm_error_paths_cover_regions() {
    369     let db = open_db();
    370 
    371     let update_missing: IFarmUpdate = parse_json(json!({
    372         "on": { "d_tag": "missing-farm" },
    373         "fields": { "name": "farm x" }
    374     }));
    375     assert_not_found(db.farm_update(&update_missing));
    376 
    377     let update_missing_id: IFarmUpdate = parse_json(json!({
    378         "on": { "id": "missing-id" },
    379         "fields": { "name": "farm y" }
    380     }));
    381     assert_not_found(db.farm_update(&update_missing_id));
    382 
    383     let delete_missing_on: IFarmDelete = parse_json(json!({
    384         "on": { "d_tag": "missing-farm" }
    385     }));
    386     assert_not_found(db.farm_delete(&delete_missing_on));
    387 
    388     drop_table(&db, "farm");
    389 
    390     let create_opts: IFarmCreate = parse_json(json!({
    391         "d_tag": "farm-a",
    392         "pubkey": hex64('a'),
    393         "name": "farm a"
    394     }));
    395     assert_invalid_query(db.farm_create(&create_opts));
    396 
    397     let find_many_filter: IFarmFindMany = parse_json(json!({
    398         "filter": { "id": "id-1" }
    399     }));
    400     assert_invalid_query(db.farm_find_many(&find_many_filter));
    401 
    402     let find_one_on: IFarmFindOne = parse_json(json!({
    403         "on": { "id": "id-1" }
    404     }));
    405     assert_invalid_query(db.farm_find_one(&find_one_on));
    406 
    407     let update_id: IFarmUpdate = parse_json(json!({
    408         "on": { "id": "id-1" },
    409         "fields": { "name": "farm z" }
    410     }));
    411     assert_invalid_query(db.farm_update(&update_id));
    412 
    413     let delete_id: IFarmDelete = parse_json(json!({
    414         "on": { "id": "id-1" }
    415     }));
    416     assert_invalid_query(db.farm_delete(&delete_id));
    417 }
    418 
    419 #[test]
    420 fn plot_error_paths_cover_regions() {
    421     let db = open_db();
    422 
    423     let update_missing: IPlotUpdate = parse_json(json!({
    424         "on": { "d_tag": "missing-plot" },
    425         "fields": { "name": "plot x" }
    426     }));
    427     assert_not_found(db.plot_update(&update_missing));
    428 
    429     let update_missing_id: IPlotUpdate = parse_json(json!({
    430         "on": { "id": "missing-id" },
    431         "fields": { "name": "plot y" }
    432     }));
    433     assert_not_found(db.plot_update(&update_missing_id));
    434 
    435     let delete_missing_on: IPlotDelete = parse_json(json!({
    436         "on": { "d_tag": "missing-plot" }
    437     }));
    438     assert_not_found(db.plot_delete(&delete_missing_on));
    439 
    440     drop_table(&db, "plot");
    441 
    442     let create_opts: IPlotCreate = parse_json(json!({
    443         "d_tag": "plot-a",
    444         "farm_id": "farm-1",
    445         "name": "plot a"
    446     }));
    447     assert_invalid_query(db.plot_create(&create_opts));
    448 
    449     let find_many_filter: IPlotFindMany = parse_json(json!({
    450         "filter": { "id": "id-1" }
    451     }));
    452     assert_invalid_query(db.plot_find_many(&find_many_filter));
    453 
    454     let find_one_on: IPlotFindOne = parse_json(json!({
    455         "on": { "id": "id-1" }
    456     }));
    457     assert_invalid_query(db.plot_find_one(&find_one_on));
    458 
    459     let update_id: IPlotUpdate = parse_json(json!({
    460         "on": { "id": "id-1" },
    461         "fields": { "name": "plot z" }
    462     }));
    463     assert_invalid_query(db.plot_update(&update_id));
    464 
    465     let delete_id: IPlotDelete = parse_json(json!({
    466         "on": { "id": "id-1" }
    467     }));
    468     assert_invalid_query(db.plot_delete(&delete_id));
    469 }
    470 
    471 #[test]
    472 fn farm_gcs_location_error_paths_cover_regions() {
    473     let db = open_db();
    474 
    475     let update_missing: IFarmGcsLocationUpdate = parse_json(json!({
    476         "on": { "farm_id": "farm-1" },
    477         "fields": { "role": "x" }
    478     }));
    479     assert_not_found(db.farm_gcs_location_update(&update_missing));
    480 
    481     let update_missing_id: IFarmGcsLocationUpdate = parse_json(json!({
    482         "on": { "id": "missing-id" },
    483         "fields": { "role": "y" }
    484     }));
    485     assert_not_found(db.farm_gcs_location_update(&update_missing_id));
    486 
    487     let delete_missing_on: IFarmGcsLocationDelete = parse_json(json!({
    488         "on": { "farm_id": "farm-1" }
    489     }));
    490     assert_not_found(db.farm_gcs_location_delete(&delete_missing_on));
    491 
    492     drop_table(&db, "farm_gcs_location");
    493 
    494     let create_opts: IFarmGcsLocationCreate = parse_json(json!({
    495         "farm_id": "farm-1",
    496         "gcs_location_id": "gcs-1",
    497         "role": "primary"
    498     }));
    499     assert_invalid_query(db.farm_gcs_location_create(&create_opts));
    500 
    501     let find_many_filter: IFarmGcsLocationFindMany = parse_json(json!({
    502         "filter": { "id": "id-1" }
    503     }));
    504     assert_invalid_query(db.farm_gcs_location_find_many(&find_many_filter));
    505 
    506     let find_one_on: IFarmGcsLocationFindOne = parse_json(json!({
    507         "on": { "id": "id-1" }
    508     }));
    509     assert_invalid_query(db.farm_gcs_location_find_one(&find_one_on));
    510 
    511     let update_id: IFarmGcsLocationUpdate = parse_json(json!({
    512         "on": { "id": "id-1" },
    513         "fields": { "role": "z" }
    514     }));
    515     assert_invalid_query(db.farm_gcs_location_update(&update_id));
    516 
    517     let delete_id: IFarmGcsLocationDelete = parse_json(json!({
    518         "on": { "id": "id-1" }
    519     }));
    520     assert_invalid_query(db.farm_gcs_location_delete(&delete_id));
    521 }
    522 
    523 #[test]
    524 fn plot_gcs_location_error_paths_cover_regions() {
    525     let db = open_db();
    526 
    527     let update_missing: IPlotGcsLocationUpdate = parse_json(json!({
    528         "on": { "plot_id": "plot-1" },
    529         "fields": { "role": "x" }
    530     }));
    531     assert_not_found(db.plot_gcs_location_update(&update_missing));
    532 
    533     let update_missing_id: IPlotGcsLocationUpdate = parse_json(json!({
    534         "on": { "id": "missing-id" },
    535         "fields": { "role": "y" }
    536     }));
    537     assert_not_found(db.plot_gcs_location_update(&update_missing_id));
    538 
    539     let delete_missing_on: IPlotGcsLocationDelete = parse_json(json!({
    540         "on": { "plot_id": "plot-1" }
    541     }));
    542     assert_not_found(db.plot_gcs_location_delete(&delete_missing_on));
    543 
    544     drop_table(&db, "plot_gcs_location");
    545 
    546     let create_opts: IPlotGcsLocationCreate = parse_json(json!({
    547         "plot_id": "plot-1",
    548         "gcs_location_id": "gcs-1",
    549         "role": "primary"
    550     }));
    551     assert_invalid_query(db.plot_gcs_location_create(&create_opts));
    552 
    553     let find_many_filter: IPlotGcsLocationFindMany = parse_json(json!({
    554         "filter": { "id": "id-1" }
    555     }));
    556     assert_invalid_query(db.plot_gcs_location_find_many(&find_many_filter));
    557 
    558     let find_one_on: IPlotGcsLocationFindOne = parse_json(json!({
    559         "on": { "id": "id-1" }
    560     }));
    561     assert_invalid_query(db.plot_gcs_location_find_one(&find_one_on));
    562 
    563     let update_id: IPlotGcsLocationUpdate = parse_json(json!({
    564         "on": { "id": "id-1" },
    565         "fields": { "role": "z" }
    566     }));
    567     assert_invalid_query(db.plot_gcs_location_update(&update_id));
    568 
    569     let delete_id: IPlotGcsLocationDelete = parse_json(json!({
    570         "on": { "id": "id-1" }
    571     }));
    572     assert_invalid_query(db.plot_gcs_location_delete(&delete_id));
    573 }
    574 
    575 #[test]
    576 fn farm_tag_error_paths_cover_regions() {
    577     let db = open_db();
    578 
    579     let update_missing: IFarmTagUpdate = parse_json(json!({
    580         "on": { "farm_id": "farm-1" },
    581         "fields": { "tag": "x" }
    582     }));
    583     assert_not_found(db.farm_tag_update(&update_missing));
    584 
    585     let update_missing_id: IFarmTagUpdate = parse_json(json!({
    586         "on": { "id": "missing-id" },
    587         "fields": { "tag": "y" }
    588     }));
    589     assert_not_found(db.farm_tag_update(&update_missing_id));
    590 
    591     let delete_missing_on: IFarmTagDelete = parse_json(json!({
    592         "on": { "farm_id": "farm-1" }
    593     }));
    594     assert_not_found(db.farm_tag_delete(&delete_missing_on));
    595 
    596     drop_table(&db, "farm_tag");
    597 
    598     let create_opts: IFarmTagCreate = parse_json(json!({
    599         "farm_id": "farm-1",
    600         "tag": "organic"
    601     }));
    602     assert_invalid_query(db.farm_tag_create(&create_opts));
    603 
    604     let find_many_filter: IFarmTagFindMany = parse_json(json!({
    605         "filter": { "id": "id-1" }
    606     }));
    607     assert_invalid_query(db.farm_tag_find_many(&find_many_filter));
    608 
    609     let find_one_on: IFarmTagFindOne = parse_json(json!({
    610         "on": { "id": "id-1" }
    611     }));
    612     assert_invalid_query(db.farm_tag_find_one(&find_one_on));
    613 
    614     let update_id: IFarmTagUpdate = parse_json(json!({
    615         "on": { "id": "id-1" },
    616         "fields": { "tag": "z" }
    617     }));
    618     assert_invalid_query(db.farm_tag_update(&update_id));
    619 
    620     let delete_id: IFarmTagDelete = parse_json(json!({
    621         "on": { "id": "id-1" }
    622     }));
    623     assert_invalid_query(db.farm_tag_delete(&delete_id));
    624 }
    625 
    626 #[test]
    627 fn plot_tag_error_paths_cover_regions() {
    628     let db = open_db();
    629 
    630     let update_missing: IPlotTagUpdate = parse_json(json!({
    631         "on": { "plot_id": "plot-1" },
    632         "fields": { "tag": "x" }
    633     }));
    634     assert_not_found(db.plot_tag_update(&update_missing));
    635 
    636     let update_missing_id: IPlotTagUpdate = parse_json(json!({
    637         "on": { "id": "missing-id" },
    638         "fields": { "tag": "y" }
    639     }));
    640     assert_not_found(db.plot_tag_update(&update_missing_id));
    641 
    642     let delete_missing_on: IPlotTagDelete = parse_json(json!({
    643         "on": { "plot_id": "plot-1" }
    644     }));
    645     assert_not_found(db.plot_tag_delete(&delete_missing_on));
    646 
    647     drop_table(&db, "plot_tag");
    648 
    649     let create_opts: IPlotTagCreate = parse_json(json!({
    650         "plot_id": "plot-1",
    651         "tag": "north"
    652     }));
    653     assert_invalid_query(db.plot_tag_create(&create_opts));
    654 
    655     let find_many_filter: IPlotTagFindMany = parse_json(json!({
    656         "filter": { "id": "id-1" }
    657     }));
    658     assert_invalid_query(db.plot_tag_find_many(&find_many_filter));
    659 
    660     let find_one_on: IPlotTagFindOne = parse_json(json!({
    661         "on": { "id": "id-1" }
    662     }));
    663     assert_invalid_query(db.plot_tag_find_one(&find_one_on));
    664 
    665     let update_id: IPlotTagUpdate = parse_json(json!({
    666         "on": { "id": "id-1" },
    667         "fields": { "tag": "z" }
    668     }));
    669     assert_invalid_query(db.plot_tag_update(&update_id));
    670 
    671     let delete_id: IPlotTagDelete = parse_json(json!({
    672         "on": { "id": "id-1" }
    673     }));
    674     assert_invalid_query(db.plot_tag_delete(&delete_id));
    675 }
    676 
    677 #[test]
    678 fn farm_member_error_paths_cover_regions() {
    679     let db = open_db();
    680 
    681     let update_missing: IFarmMemberUpdate = parse_json(json!({
    682         "on": { "member_pubkey": hex64('a') },
    683         "fields": { "role": "x" }
    684     }));
    685     assert_not_found(db.farm_member_update(&update_missing));
    686 
    687     let update_missing_id: IFarmMemberUpdate = parse_json(json!({
    688         "on": { "id": "missing-id" },
    689         "fields": { "role": "y" }
    690     }));
    691     assert_not_found(db.farm_member_update(&update_missing_id));
    692 
    693     let delete_missing_on: IFarmMemberDelete = parse_json(json!({
    694         "on": { "member_pubkey": hex64('a') }
    695     }));
    696     assert_not_found(db.farm_member_delete(&delete_missing_on));
    697 
    698     drop_table(&db, "farm_member");
    699 
    700     let create_opts: IFarmMemberCreate = parse_json(json!({
    701         "farm_id": "farm-1",
    702         "member_pubkey": hex64('a'),
    703         "role": "owner"
    704     }));
    705     assert_invalid_query(db.farm_member_create(&create_opts));
    706 
    707     let find_many_filter: IFarmMemberFindMany = parse_json(json!({
    708         "filter": { "id": "id-1" }
    709     }));
    710     assert_invalid_query(db.farm_member_find_many(&find_many_filter));
    711 
    712     let find_one_on: IFarmMemberFindOne = parse_json(json!({
    713         "on": { "id": "id-1" }
    714     }));
    715     assert_invalid_query(db.farm_member_find_one(&find_one_on));
    716 
    717     let update_id: IFarmMemberUpdate = parse_json(json!({
    718         "on": { "id": "id-1" },
    719         "fields": { "role": "z" }
    720     }));
    721     assert_invalid_query(db.farm_member_update(&update_id));
    722 
    723     let delete_id: IFarmMemberDelete = parse_json(json!({
    724         "on": { "id": "id-1" }
    725     }));
    726     assert_invalid_query(db.farm_member_delete(&delete_id));
    727 }
    728 
    729 #[test]
    730 fn farm_member_claim_error_paths_cover_regions() {
    731     let db = open_db();
    732 
    733     let update_missing: IFarmMemberClaimUpdate = parse_json(json!({
    734         "on": { "member_pubkey": hex64('a') },
    735         "fields": { "farm_pubkey": hex64('b') }
    736     }));
    737     assert_not_found(db.farm_member_claim_update(&update_missing));
    738 
    739     let update_missing_id: IFarmMemberClaimUpdate = parse_json(json!({
    740         "on": { "id": "missing-id" },
    741         "fields": { "farm_pubkey": hex64('c') }
    742     }));
    743     assert_not_found(db.farm_member_claim_update(&update_missing_id));
    744 
    745     let delete_missing_on: IFarmMemberClaimDelete = parse_json(json!({
    746         "on": { "member_pubkey": hex64('a') }
    747     }));
    748     assert_not_found(db.farm_member_claim_delete(&delete_missing_on));
    749 
    750     drop_table(&db, "farm_member_claim");
    751 
    752     let create_opts: IFarmMemberClaimCreate = parse_json(json!({
    753         "member_pubkey": hex64('a'),
    754         "farm_pubkey": hex64('b')
    755     }));
    756     assert_invalid_query(db.farm_member_claim_create(&create_opts));
    757 
    758     let find_many_filter: IFarmMemberClaimFindMany = parse_json(json!({
    759         "filter": { "id": "id-1" }
    760     }));
    761     assert_invalid_query(db.farm_member_claim_find_many(&find_many_filter));
    762 
    763     let find_one_on: IFarmMemberClaimFindOne = parse_json(json!({
    764         "on": { "id": "id-1" }
    765     }));
    766     assert_invalid_query(db.farm_member_claim_find_one(&find_one_on));
    767 
    768     let update_id: IFarmMemberClaimUpdate = parse_json(json!({
    769         "on": { "id": "id-1" },
    770         "fields": { "farm_pubkey": hex64('c') }
    771     }));
    772     assert_invalid_query(db.farm_member_claim_update(&update_id));
    773 
    774     let delete_id: IFarmMemberClaimDelete = parse_json(json!({
    775         "on": { "id": "id-1" }
    776     }));
    777     assert_invalid_query(db.farm_member_claim_delete(&delete_id));
    778 }
    779 
    780 #[test]
    781 fn log_error_error_paths_cover_regions() {
    782     let db = open_db();
    783 
    784     let update_missing: ILogErrorUpdate = parse_json(json!({
    785         "on": { "nostr_pubkey": hex64('a') },
    786         "fields": { "message": "x" }
    787     }));
    788     assert_not_found(db.log_error_update(&update_missing));
    789 
    790     let update_missing_id: ILogErrorUpdate = parse_json(json!({
    791         "on": { "id": "missing-id" },
    792         "fields": { "message": "y" }
    793     }));
    794     assert_not_found(db.log_error_update(&update_missing_id));
    795 
    796     let delete_missing_on: ILogErrorDelete = parse_json(json!({
    797         "on": { "nostr_pubkey": hex64('a') }
    798     }));
    799     assert_not_found(db.log_error_delete(&delete_missing_on));
    800 
    801     drop_table(&db, "log_error");
    802 
    803     let create_opts: ILogErrorCreate = parse_json(json!({
    804         "error": "panic",
    805         "message": "boom",
    806         "app_system": "studio",
    807         "app_version": "1.0.0",
    808         "nostr_pubkey": hex64('a')
    809     }));
    810     assert_invalid_query(db.log_error_create(&create_opts));
    811 
    812     let find_many_filter: ILogErrorFindMany = parse_json(json!({
    813         "filter": { "id": "id-1" }
    814     }));
    815     assert_invalid_query(db.log_error_find_many(&find_many_filter));
    816 
    817     let find_one_on: ILogErrorFindOne = parse_json(json!({
    818         "on": { "id": "id-1" }
    819     }));
    820     assert_invalid_query(db.log_error_find_one(&find_one_on));
    821 
    822     let update_id: ILogErrorUpdate = parse_json(json!({
    823         "on": { "id": "id-1" },
    824         "fields": { "message": "z" }
    825     }));
    826     assert_invalid_query(db.log_error_update(&update_id));
    827 
    828     let delete_id: ILogErrorDelete = parse_json(json!({
    829         "on": { "id": "id-1" }
    830     }));
    831     assert_invalid_query(db.log_error_delete(&delete_id));
    832 }
    833 
    834 #[test]
    835 fn nostr_event_head_error_paths_cover_regions() {
    836     let db = open_db();
    837 
    838     let update_missing: INostrEventHeadUpdate = parse_json(json!({
    839         "on": { "key": "state-a" },
    840         "fields": { "content_hash": "hash-x" }
    841     }));
    842     assert_not_found(db.nostr_event_head_update(&update_missing));
    843 
    844     let update_missing_id: INostrEventHeadUpdate = parse_json(json!({
    845         "on": { "id": "missing-id" },
    846         "fields": { "content_hash": "hash-y" }
    847     }));
    848     assert_not_found(db.nostr_event_head_update(&update_missing_id));
    849 
    850     let delete_missing_on: INostrEventHeadDelete = parse_json(json!({
    851         "on": { "key": "state-a" }
    852     }));
    853     assert_not_found(db.nostr_event_head_delete(&delete_missing_on));
    854 
    855     drop_table(&db, "nostr_event_head");
    856 
    857     let create_opts: INostrEventHeadCreate = parse_json(json!({
    858         "key": "state-a",
    859         "kind": 30023,
    860         "pubkey": hex64('a'),
    861         "d_tag": "listing-a",
    862         "last_event_id": hex64('b'),
    863         "last_created_at": 1,
    864         "content_hash": "hash-a"
    865     }));
    866     assert_invalid_query(db.nostr_event_head_create(&create_opts));
    867 
    868     let find_many_filter: INostrEventHeadFindMany = parse_json(json!({
    869         "filter": { "id": "id-1" }
    870     }));
    871     assert_invalid_query(db.nostr_event_head_find_many(&find_many_filter));
    872 
    873     let find_one_on: INostrEventHeadFindOne = parse_json(json!({
    874         "on": { "id": "id-1" }
    875     }));
    876     assert_invalid_query(db.nostr_event_head_find_one(&find_one_on));
    877 
    878     let update_id: INostrEventHeadUpdate = parse_json(json!({
    879         "on": { "id": "id-1" },
    880         "fields": { "content_hash": "hash-z" }
    881     }));
    882     assert_invalid_query(db.nostr_event_head_update(&update_id));
    883 
    884     let delete_id: INostrEventHeadDelete = parse_json(json!({
    885         "on": { "id": "id-1" }
    886     }));
    887     assert_invalid_query(db.nostr_event_head_delete(&delete_id));
    888 }
    889 
    890 #[test]
    891 fn trade_product_error_paths_cover_regions() {
    892     let db = open_db();
    893 
    894     let update_missing: ITradeProductUpdate = parse_json(json!({
    895         "on": { "id": "missing-id" },
    896         "fields": { "title": "x" }
    897     }));
    898     assert_not_found(db.trade_product_update(&update_missing));
    899 
    900     let delete_missing_on: ITradeProductDelete = parse_json(json!({
    901         "on": { "id": "missing-id" }
    902     }));
    903     assert_not_found(db.trade_product_delete(&delete_missing_on));
    904 
    905     drop_table(&db, "trade_product");
    906 
    907     let create_opts: ITradeProductCreate = parse_json(json!({
    908         "key": "product-a",
    909         "category": "coffee",
    910         "title": "coffee a",
    911         "summary": "summary",
    912         "process": "washed",
    913         "lot": "lot-a",
    914         "profile": "floral",
    915         "year": 2024,
    916         "qty_amt": 100,
    917         "qty_amt_exact": "100",
    918         "qty_unit": "kg",
    919         "price_amt": 7.5,
    920         "price_amt_exact": "7.5",
    921         "price_currency": "USD",
    922         "price_qty_amt": 1,
    923         "price_qty_amt_exact": "1",
    924         "price_qty_unit": "kg"
    925     }));
    926     assert_invalid_query(db.trade_product_create(&create_opts));
    927 
    928     let find_many_filter: ITradeProductFindMany = parse_json(json!({
    929         "filter": { "id": "id-1" }
    930     }));
    931     assert_invalid_query(db.trade_product_find_many(&find_many_filter));
    932 
    933     let find_one_on: ITradeProductFindOne = parse_json(json!({
    934         "on": { "id": "id-1" }
    935     }));
    936     assert_invalid_query(db.trade_product_find_one(&find_one_on));
    937 
    938     let update_id: ITradeProductUpdate = parse_json(json!({
    939         "on": { "id": "id-1" },
    940         "fields": { "title": "z" }
    941     }));
    942     assert_invalid_query(db.trade_product_update(&update_id));
    943 
    944     let delete_id: ITradeProductDelete = parse_json(json!({
    945         "on": { "id": "id-1" }
    946     }));
    947     assert_invalid_query(db.trade_product_delete(&delete_id));
    948 }
    949 
    950 #[test]
    951 fn relation_set_unset_error_paths_cover_regions() {
    952     let db = open_db();
    953 
    954     drop_table(&db, "nostr_profile_relay");
    955     let profile_relay_rel: INostrProfileRelayRelation = parse_json(json!({
    956         "nostr_profile": { "id": "profile-1" },
    957         "nostr_relay": { "id": "relay-1" }
    958     }));
    959     assert_invalid_query(db.nostr_profile_relay_set(&profile_relay_rel));
    960     assert_invalid_query(db.nostr_profile_relay_unset(&profile_relay_rel));
    961 
    962     drop_table(&db, "trade_product_location");
    963     let product_location_rel: ITradeProductLocationRelation = parse_json(json!({
    964         "trade_product": { "id": "product-1" },
    965         "gcs_location": { "id": "gcs-1" }
    966     }));
    967     assert_invalid_query(db.trade_product_location_set(&product_location_rel));
    968     assert_invalid_query(db.trade_product_location_unset(&product_location_rel));
    969 
    970     drop_table(&db, "trade_product_media");
    971     let product_media_rel: ITradeProductMediaRelation = parse_json(json!({
    972         "trade_product": { "id": "product-1" },
    973         "media_image": { "id": "media-1" }
    974     }));
    975     assert_invalid_query(db.trade_product_media_set(&product_media_rel));
    976     assert_invalid_query(db.trade_product_media_unset(&product_media_rel));
    977 }