diff --git a/dnas/plenty/zomes/coordinator/households/src/household_to_requestors.rs b/dnas/plenty/zomes/coordinator/households/src/household_to_requestors.rs index fb8639d..81d1db2 100644 --- a/dnas/plenty/zomes/coordinator/households/src/household_to_requestors.rs +++ b/dnas/plenty/zomes/coordinator/households/src/household_to_requestors.rs @@ -1,6 +1,7 @@ +use crate::household_to_members::{add_member_for_household, AddMemberForHouseholdInput}; use hdk::prelude::*; use households_integrity::*; -use crate::household_to_members::{add_member_for_household, AddMemberForHouseholdInput}; + fn get_join_request_household_and_requestor( join_request_create_link_hash: ActionHash, ) -> ExternResult<(ActionHash, AgentPubKey)> { @@ -8,40 +9,28 @@ fn get_join_request_household_and_requestor( return Err(wasm_error!(WasmErrorInner::Guest("NOT_FOUND".into()))); }; let Action::CreateLink(create_link) = record.action().clone() else { - return Err( - wasm_error!( - WasmErrorInner::Guest("The given action hash does not correspond to a CreateLink action" - .into()) - ), - ); + return Err(wasm_error!(WasmErrorInner::Guest( + "The given action hash does not correspond to a CreateLink action".into() + ))); }; let household_hash = create_link .base_address .into_action_hash() - .ok_or( - wasm_error!( - WasmErrorInner::Guest("The join request does not have an ActionHash as its base address" - .into()) - ), - )?; + .ok_or(wasm_error!(WasmErrorInner::Guest( + "The join request does not have an ActionHash as its base address".into() + )))?; let requestor = create_link .target_address .into_agent_pub_key() - .ok_or( - wasm_error!( - WasmErrorInner::Guest("The join request does not have an AgentPubKey as its target address" - .into()) - ), - )?; + .ok_or(wasm_error!(WasmErrorInner::Guest( + "The join request does not have an AgentPubKey as its target address".into() + )))?; Ok((household_hash, requestor)) } #[hdk_extern] -pub fn accept_join_request( - join_request_create_link_hash: ActionHash, -) -> ExternResult<()> { - let (household_hash, requestor) = get_join_request_household_and_requestor( - join_request_create_link_hash, - )?; +pub fn accept_join_request(join_request_create_link_hash: ActionHash) -> ExternResult<()> { + let (household_hash, requestor) = + get_join_request_household_and_requestor(join_request_create_link_hash)?; remove_requestor_for_household(RemoveRequestorForHouseholdInput { household_hash: household_hash.clone(), requestor: requestor.clone(), @@ -52,22 +41,44 @@ pub fn accept_join_request( })?; Ok(()) } + #[hdk_extern] -pub fn request_to_join_household( - household_hash: ActionHash, -) -> ExternResult { +pub fn cancel_join_request(household_hash: ActionHash) -> ExternResult<()> { + remove_requestor_for_household(RemoveRequestorForHouseholdInput { + household_hash, + requestor: agent_info()?.agent_latest_pubkey, + })?; + Ok(()) +} + +#[hdk_extern] +pub fn request_to_join_household(household_hash: ActionHash) -> ExternResult { let my_pub_key = agent_info()?.agent_latest_pubkey; - create_link(household_hash, my_pub_key, LinkTypes::HouseholdToRequestors, ()) + create_link( + my_pub_key.clone(), + household_hash.clone(), + LinkTypes::RequestorToHouseholds, + (), + )?; + create_link( + household_hash, + my_pub_key, + LinkTypes::HouseholdToRequestors, + (), + ) } #[hdk_extern] -pub fn get_requestors_for_household( - household_hash: ActionHash, -) -> ExternResult> { +pub fn get_requestors_for_household(household_hash: ActionHash) -> ExternResult> { get_links( - GetLinksInputBuilder::try_new(household_hash, LinkTypes::HouseholdToRequestors)? - .build(), + GetLinksInputBuilder::try_new(household_hash, LinkTypes::HouseholdToRequestors)?.build(), ) } + +#[hdk_extern] +pub fn get_join_household_requests_for_agent(agent: AgentPubKey) -> ExternResult> { + get_links(GetLinksInputBuilder::try_new(agent, LinkTypes::RequestorToHouseholds)?.build()) +} + #[hdk_extern] pub fn get_deleted_requestors_for_household( household_hash: ActionHash, @@ -78,13 +89,11 @@ pub fn get_deleted_requestors_for_household( None, GetOptions::default(), )?; - Ok( - details - .into_inner() - .into_iter() - .filter(|(_link, deletes)| deletes.len() > 0) - .collect(), - ) + Ok(details + .into_inner() + .into_iter() + .filter(|(_link, deletes)| deletes.len() > 0) + .collect()) } #[derive(Serialize, Deserialize, Debug)] pub struct RemoveRequestorForHouseholdInput { @@ -92,41 +101,51 @@ pub struct RemoveRequestorForHouseholdInput { pub requestor: AgentPubKey, } #[hdk_extern] -pub fn reject_join_request( - join_request_create_link_hash: ActionHash, -) -> ExternResult<()> { - let (household_hash, requestor) = get_join_request_household_and_requestor( - join_request_create_link_hash, - )?; +pub fn reject_join_request(join_request_create_link_hash: ActionHash) -> ExternResult<()> { + let (household_hash, requestor) = + get_join_request_household_and_requestor(join_request_create_link_hash)?; remove_requestor_for_household(RemoveRequestorForHouseholdInput { household_hash, requestor, })?; Ok(()) } -fn remove_requestor_for_household( - input: RemoveRequestorForHouseholdInput, -) -> ExternResult<()> { + +fn remove_requestor_for_household(input: RemoveRequestorForHouseholdInput) -> ExternResult<()> { let links = get_links( GetLinksInputBuilder::try_new( - input.household_hash.clone(), - LinkTypes::HouseholdToRequestors, - )? - .build(), + input.household_hash.clone(), + LinkTypes::HouseholdToRequestors, + )? + .build(), )?; for link in links { if link .target .into_agent_pub_key() - .ok_or( - wasm_error!( - WasmErrorInner::Guest(String::from("No agent pub key associated with link")) - ), - )? + .ok_or(wasm_error!(WasmErrorInner::Guest(String::from( + "No agent pub key associated with link" + ))))? .eq(&input.requestor) { delete_link(link.create_link_hash)?; } } + let links = get_links( + GetLinksInputBuilder::try_new(input.requestor.clone(), LinkTypes::RequestorToHouseholds)? + .build(), + )?; + for link in links { + if link + .target + .into_action_hash() + .ok_or(wasm_error!(WasmErrorInner::Guest(String::from( + "No household associated RequestorToHouseholds link" + ))))? + .eq(&input.household_hash) + { + delete_link(link.create_link_hash)?; + } + } Ok(()) } diff --git a/dnas/plenty/zomes/coordinator/households/tests/member_to_households.rs b/dnas/plenty/zomes/coordinator/households/tests/member_to_households.rs index 2efa079..c275634 100644 --- a/dnas/plenty/zomes/coordinator/households/tests/member_to_households.rs +++ b/dnas/plenty/zomes/coordinator/households/tests/member_to_households.rs @@ -2,11 +2,9 @@ #![allow(unused_variables)] #![allow(unused_imports)] -use std::time::Duration; use hdk::prelude::*; use holochain::{conductor::config::ConductorConfig, sweettest::*}; - -use households::member_to_households::AddHouseholdForMemberInput; +use std::time::Duration; mod common; @@ -15,9 +13,9 @@ use common::{create_household, sample_household_1}; #[tokio::test(flavor = "multi_thread")] async fn link_a_member_to_a_household() { // Use prebuilt dna file - let dna_path = std::env::current_dir() - .unwrap() - .join(std::env::var("DNA_PATH").expect("DNA_PATH not set, must be run using nix flake check")); + let dna_path = std::env::current_dir().unwrap().join( + std::env::var("DNA_PATH").expect("DNA_PATH not set, must be run using nix flake check"), + ); let dna = SweetDnaFile::from_bundle(&dna_path).await.unwrap(); // Set up conductors @@ -26,37 +24,48 @@ async fn link_a_member_to_a_household() { conductors.exchange_peer_info().await; let ((alice,), (bobbo,)) = apps.into_tuples(); - + let alice_zome = alice.zome("households"); let bob_zome = bobbo.zome("households"); let base_address = alice.agent_pubkey().clone(); - let target_record = create_household(&conductors[0], &alice_zome, sample_household_1(&conductors[0], &alice_zome).await).await; + let target_record = create_household( + &conductors[0], + &alice_zome, + sample_household_1(&conductors[0], &alice_zome).await, + ) + .await; let target_address = target_record.signed_action.hashed.hash.clone(); // Bob gets the links, should be empty let links_output: Vec = conductors[1] - .call(&bob_zome, "get_households_for_member", base_address.clone()).await; + .call(&bob_zome, "get_households_for_member", base_address.clone()) + .await; assert_eq!(links_output.len(), 0); // Alice creates a link from Member to Household let _result: () = conductors[0] - .call(&alice_zome, "add_household_for_member", AddHouseholdForMemberInput { - base_member: base_address.clone(), - target_household_hash: target_address.clone() - }).await; - + .call( + &alice_zome, + "add_member_for_household", + AddMemberForHouseholdInput { + member: base_address.clone(), + household_hash: target_address.clone(), + }, + ) + .await; + await_consistency(Duration::from_secs(30), [&alice, &bobbo]) .await .expect("Timed out waiting for consistency"); // Bob gets the links again let links_output: Vec = conductors[1] - .call(&bob_zome, "get_households_for_member", base_address.clone()).await; + .call(&bob_zome, "get_households_for_member", base_address.clone()) + .await; assert_eq!(links_output.len(), 1); - assert_eq!(AnyLinkableHash::from(target_address.clone()), links_output[0].target); - - + assert_eq!( + AnyLinkableHash::from(target_address.clone()), + links_output[0].target + ); } - -