use bft_json_crdt::json_crdt::BaseCrdt;
use bft_json_crdt::keypair::make_keypair;
use bft_json_crdt::op::ROOT_ID;
use side_node::crdt::TransactionList;

// case 1 - send valid updates
#[test]
fn test_valid_updates() {
    // Insert to crdt.doc on local node, test applying the same operation to a remote node
    // and check that the view is the same
    let keypair1 = make_keypair();
    let mut crdt1 = BaseCrdt::<TransactionList>::new(&keypair1);

    let val_a = side_node::utils::fake_generic_transaction_json(String::from("a"));
    let val_b = side_node::utils::fake_generic_transaction_json(String::from("b"));
    let val_c = side_node::utils::fake_generic_transaction_json(String::from("c"));

    let _a = crdt1
        .doc
        .list
        .insert(ROOT_ID, val_a.clone())
        .sign(&keypair1);
    let _b = crdt1
        .doc
        .list
        .insert(_a.id(), val_b.clone())
        .sign(&keypair1);
    let _c = crdt1
        .doc
        .list
        .insert(_b.id(), val_c.clone())
        .sign(&keypair1);

    let keypair2 = make_keypair();
    let mut crdt2 = BaseCrdt::<TransactionList>::new(&keypair2);
    crdt2.apply(_a.clone());
    crdt2.apply(_b);
    crdt2.apply(_c.clone());

    assert_eq!(
        crdt2.doc.list.view(),
        crdt1.doc.list.view(),
        "views should be equal"
    );

    crdt2.apply(_a.clone());
    crdt2.apply(_a);

    assert_eq!(
        crdt1.doc.list.view(),
        crdt2.doc.list.view(),
        "views are still equal after repeated applies"
    );
}
