Skip to content

Commit

Permalink
Join households WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
guillemcordoba committed Apr 16, 2024
1 parent 27bb453 commit 8334945
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,47 +1,36 @@
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)> {
let Some(record) = get(join_request_create_link_hash, GetOptions::default())? else {
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(),
Expand All @@ -52,22 +41,44 @@ pub fn accept_join_request(
})?;
Ok(())
}

#[hdk_extern]
pub fn request_to_join_household(
household_hash: ActionHash,
) -> ExternResult<ActionHash> {
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<ActionHash> {
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<Vec<Link>> {
pub fn get_requestors_for_household(household_hash: ActionHash) -> ExternResult<Vec<Link>> {
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<Vec<Link>> {
get_links(GetLinksInputBuilder::try_new(agent, LinkTypes::RequestorToHouseholds)?.build())
}

#[hdk_extern]
pub fn get_deleted_requestors_for_household(
household_hash: ActionHash,
Expand All @@ -78,55 +89,63 @@ 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 {
pub household_hash: ActionHash,
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(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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<Link> = 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<Link> = 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
);
}


0 comments on commit 8334945

Please sign in to comment.