Skip to content

Commit

Permalink
Merge pull request #21 from h-be/version-0-5-2-updates
Browse files Browse the repository at this point in the history
Version 0 5 2 updates
  • Loading branch information
Connoropolous authored Aug 23, 2021
2 parents 7cb2e77 + 1bef307 commit b2f21db
Show file tree
Hide file tree
Showing 174 changed files with 5,074 additions and 3,219 deletions.
5 changes: 5 additions & 0 deletions dna/zomes/projects/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rust-analyzer.cargo.features": [
"mock"
]
}
53 changes: 33 additions & 20 deletions dna/zomes/projects/src/project/edge/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,35 @@ fn validate_create_entry_edge(validate_data: ValidateData) -> ExternResult<Valid

// parent goal, and child goal, must be determined to exist to pass validation
if let Header::Create(_) = validate_data.element.header() {
Ok(
// parent goal
match confirm_resolved_dependency::<Goal>(proposed_edge.parent_address.0.into())? {
ValidateCallbackResult::Valid => {
// child goal
confirm_resolved_dependency::<Goal>(proposed_edge.child_address.0.into())?
let parent_res = confirm_resolved_dependency::<Goal>(proposed_edge.parent_address.0.into())?;
let child_res = confirm_resolved_dependency::<Goal>(proposed_edge.child_address.0.into())?;
match (parent_res, child_res) {
(ValidateCallbackResult::Valid, ValidateCallbackResult::Valid) => {
Ok(ValidateCallbackResult::Valid)
}
(
ValidateCallbackResult::UnresolvedDependencies(parent_dep),
ValidateCallbackResult::UnresolvedDependencies(child_dep),
) => Ok(ValidateCallbackResult::UnresolvedDependencies(vec![
parent_dep.first().unwrap().to_owned(),
child_dep.first().unwrap().to_owned(),
])),
(ValidateCallbackResult::UnresolvedDependencies(parent_dep), _) => {
Ok(ValidateCallbackResult::UnresolvedDependencies(parent_dep))
}
(_, ValidateCallbackResult::UnresolvedDependencies(child_dep)) => {
Ok(ValidateCallbackResult::UnresolvedDependencies(child_dep))
}
validate_callback_results => {
if let ValidateCallbackResult::Invalid(e) = validate_callback_results.0 {
// parent was invalid
Ok(ValidateCallbackResult::Invalid(e))
} else {
// child was invalid
Ok(validate_callback_results.1)
}
// we want to forward the validate_callback_result
// back to Holochain since it contains a specific UnresolvedDependencies response
// including the missing Hashes
validate_callback_result => validate_callback_result,
},
)
}
}
}
// Holochain sent the wrong header!
else {
Expand Down Expand Up @@ -112,25 +128,22 @@ pub mod tests {
edge.child_address = goal_child_wrapped_header_hash.clone();
*validate_data.element.as_entry_mut() = ElementEntry::Present(edge.clone().try_into().unwrap());

// act as if the parent_address Goal were missing, could not be resolved
// act as if the parent_address and child_address Goals were missing, could not be resolved
let mut mock_hdk = MockHdkT::new();
mock_hdk
.expect_get()
.with(mockall::predicate::eq(GetInput::new(
goal_parent_wrapped_header_hash.clone().0.into(),
GetOptions::content(),
)))
.times(1)
.times(2)
.return_const(Ok(None));

set_hdk(mock_hdk);

// we should see that the ValidateCallbackResult is that there are UnresolvedDependencies
// equal to the Hash of the parent Goal address
// equal to the Hashes of the parent Goal address and the child Goal address
assert_eq!(
super::validate_create_entry_edge(validate_data.clone()),
Ok(ValidateCallbackResult::UnresolvedDependencies(vec![
goal_parent_wrapped_header_hash.clone().0.into()
goal_parent_wrapped_header_hash.clone().0.into(),
goal_child_wrapped_header_hash.clone().0.into()
])),
);

Expand Down
2 changes: 1 addition & 1 deletion dna/zomes/projects/src/project/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub enum Error {
#[error("Element with invalid header")]
WrongHeader,

#[error("Element is missing its Entry")]
#[error("Element missing its Entry")]
EntryMissing,

#[error("Only one of this entry type should exist and an existing one was found")]
Expand Down
24 changes: 21 additions & 3 deletions dna/zomes/projects/src/project/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ pub(crate) mod fixtures {
use crate::project::{
edge::crud::Edge, entry_point::crud::EntryPoint, goal::crud::TimeFrame,
goal_comment::crud::GoalComment, goal_member::crud::GoalMember, goal_vote::crud::GoalVote,
member::entry::Member, project_meta::crud::ProjectMeta,
member::entry::Member, project_meta::crud::{ProjectMeta, PriorityMode},
};
use ::fixt::prelude::*;
use dna_help::{WrappedAgentPubKey, WrappedHeaderHash};
use hdk::prelude::*;

// why can't I put this one in dna_help crate?
fixturator!(
WrappedHeaderHash;
constructor fn new(HeaderHash);
Expand Down Expand Up @@ -53,15 +52,21 @@ pub(crate) mod fixtures {

fixturator!(
ProjectMeta;
constructor fn new(WrappedAgentPubKey, f64, String, OptionString, String, bool);
constructor fn new(WrappedAgentPubKey, f64, String, OptionString, String, bool, PriorityMode, VecWrappedHeaderHash);
);

type VecWrappedHeaderHash = Vec<WrappedHeaderHash>;
type OptionWrappedAgentPubKey = Option<WrappedAgentPubKey>;
type OptionString = Option<String>;
type Optionf64 = Option<f64>;
type OptionVecString = Option<Vec<String>>;
type OptionTimeFrame = Option<TimeFrame>;

fixturator!(
PriorityMode;
unit variants [ Universal Vote ] empty Universal;
);

fixturator!(
TimeFrame;
constructor fn new(f64, f64);
Expand All @@ -77,6 +82,19 @@ pub(crate) mod fixtures {
unit variants [Root Trunk Branch Leaf NoHierarchy ] empty NoHierarchy;
);

fixturator!(
VecWrappedHeaderHash;
curve Empty {
Vec::new()
};
curve Unpredictable {
vec![WrappedHeaderHashFixturator::new(Unpredictable).next().unwrap()]
};
curve Predictable {
vec![WrappedHeaderHashFixturator::new(Predictable).next().unwrap()]
};
);

fixturator!(
OptionWrappedAgentPubKey;
curve Empty {
Expand Down
54 changes: 48 additions & 6 deletions dna/zomes/projects/src/project/goal/crud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Goal {
}

#[derive(Debug, Serialize, Deserialize, SerializedBytes, Clone, PartialEq)]
pub struct UIEnum(String);
pub struct UIEnum(pub String);

#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
#[serde(from = "UIEnum")]
Expand Down Expand Up @@ -163,10 +163,45 @@ crud!(
convert_to_receiver_signal
);



#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
#[serde(from = "UIEnum")]
#[serde(into = "UIEnum")]
pub enum RelationInput {
ExistingGoalAsChild,
ExistingGoalAsParent
}
impl From<UIEnum> for RelationInput {
fn from(ui_enum: UIEnum) -> Self {
match ui_enum.0.as_str() {
"ExistingGoalAsChild" => Self::ExistingGoalAsChild,
"ExistingGoalAsParent" => Self::ExistingGoalAsParent,
_ => Self::ExistingGoalAsChild,
}
}
}
impl From<RelationInput> for UIEnum {
fn from(relation_input: RelationInput) -> Self {
Self(relation_input.to_string())
}
}
impl fmt::Display for RelationInput {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}

#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
pub struct LinkedGoalDetails {
goal_address: WrappedHeaderHash,
relation: RelationInput
}

#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
pub struct CreateGoalWithEdgeInput {
entry: Goal,
maybe_parent_address: Option<WrappedHeaderHash>,
maybe_linked_goal: Option<LinkedGoalDetails>,
}

#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
Expand All @@ -189,11 +224,18 @@ pub fn create_goal_with_edge(
) -> ExternResult<CreateGoalWithEdgeOutput> {
// false to say don't send a signal
let wire_entry: GoalWireEntry = inner_create_goal(input.entry.clone(), false)?;
let maybe_edge: Option<EdgeWireEntry> = match input.maybe_parent_address {
Some(header_hash) => {
let new_goal_address = wire_entry.address.clone();
let maybe_edge: Option<EdgeWireEntry> = match input.maybe_linked_goal {
Some(linked_goal_details) => {
let (parent_address, child_address) = match linked_goal_details.relation {
// new goal becomes parent
RelationInput::ExistingGoalAsChild => (new_goal_address, linked_goal_details.goal_address),
// new goal becomes child
RelationInput::ExistingGoalAsParent => (linked_goal_details.goal_address, new_goal_address)
};
let edge = Edge {
parent_address: header_hash,
child_address: wire_entry.address.clone(),
parent_address,
child_address,
randomizer: sys_time()?.as_secs_f64(),
is_imported: false
};
Expand Down
16 changes: 8 additions & 8 deletions dna/zomes/projects/src/project/goal/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ fn validate_update_entry_goal(validate_data: ValidateData) -> ExternResult<Valid
// `user_hash` still matches that original author
if let Header::Update(header) = validate_data.element.header() {
match resolve_dependency::<Goal>(header.original_header_address.clone().into())? {
Ok(ResolvedDependency(el, _)) => {
Ok(ResolvedDependency(_el, goal)) => {
// the final return value
// if this passes, all have passed

// here we are checking to make sure that
// this user is not suggesting that someone other than
// the original author of the original goal WAS the original
validate_value_matches_original_author(&proposed_entry.user_hash.0, &el)
validate_value_matches_original_author(&proposed_entry.user_hash.0, &goal.user_hash.0)
}
// the unresolved dependency case
// the unresolved dependency case and invalid case
Err(validate_callback_result) => validate_callback_result,
}
} else {
Expand Down Expand Up @@ -206,7 +206,7 @@ pub mod tests {
// to know this, we need to resolve that dependency
goal.user_edit_hash = Some(WrappedAgentPubKey::new(
update_header.author.as_hash().clone(),
));
));
// update the goal value in the validate_data
*validate_data.element.as_entry_mut() = ElementEntry::Present(goal.clone().try_into().unwrap());

Expand Down Expand Up @@ -266,15 +266,15 @@ pub mod tests {
// SUCCESS case
// the element exists and deserializes
// user_edit_hash is Some(the author)
// original_header_address exists, and the author
// of that original header
// original_header_address exists, and the value
// `user_hash` of the original Goal
// is equal to the new `user_hash` value
// -> good to go
// we should see that the ValidateCallbackResult
// is finally valid

// set the user_hash on the goal equal to the "original header author address"
goal.user_hash = WrappedAgentPubKey::new(original_goal_element.header().author().clone());
// set the user_hash on the goal equal to the original goals user_hash property
goal.user_hash = original_goal.user_hash.clone();
*validate_data.element.as_entry_mut() = ElementEntry::Present(goal.clone().try_into().unwrap());

let mut mock_hdk = MockHdkT::new();
Expand Down
33 changes: 16 additions & 17 deletions dna/zomes/projects/src/project/goal_comment/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,16 @@ fn validate_update_entry_goal_comment(
match resolve_dependency::<GoalComment>(
header.original_header_address.clone().into(),
)? {
Ok(ResolvedDependency(el, _)) => {
Ok(ResolvedDependency(_el, goal_comment)) => {
// the final return value
// if this passes, all have passed

// here we are checking to make sure that
// only original author can make this update
validate_value_matches_original_author_for_edit(&header.author, &el)
validate_value_matches_original_author_for_edit(
&header.author,
&goal_comment.agent_address.0,
)
}
// the unresolved dependency case
Err(validate_callback_result) => validate_callback_result,
Expand Down Expand Up @@ -183,7 +186,7 @@ pub mod tests {
// the parent goal is found/exists
// agent_address refers to the agent committing
// -> good to go

// make the agent_address valid by making it equal the
// AgentPubKey of the agent committing
goal_comment.agent_address = WrappedAgentPubKey::new(create_header.author.as_hash().clone());
Expand Down Expand Up @@ -285,8 +288,8 @@ pub mod tests {
let original_goal_comment = fixt!(GoalComment);
// but due to being random, it will have a different author
// than our Update header
let mut goal_comment_element = fixt!(Element);
*goal_comment_element.as_entry_mut() =
let mut original_goal_comment_element = fixt!(Element);
*original_goal_comment_element.as_entry_mut() =
ElementEntry::Present(original_goal_comment.clone().try_into().unwrap());

let mut mock_hdk = MockHdkT::new();
Expand All @@ -298,7 +301,7 @@ pub mod tests {
GetOptions::content(),
)))
.times(1)
.return_const(Ok(Some(goal_comment_element.clone())));
.return_const(Ok(Some(original_goal_comment_element.clone())));

set_hdk(mock_hdk);

Expand All @@ -313,16 +316,12 @@ pub mod tests {
// the original GoalComment header and entry exist
// and the author of the update matches the original author
// -> good to go
let original_goal_comment = fixt!(GoalComment);
let mut goal_comment_element = fixt!(Element);
let mut original_create_header = fixt!(Create);
// make the authors equal
original_create_header = Create {
author: update_header.author.as_hash().clone(),
..original_create_header
};
*goal_comment_element.as_header_mut() = Header::Create(original_create_header.clone());
*goal_comment_element.as_entry_mut() =
let mut original_goal_comment = fixt!(GoalComment);
let mut original_goal_comment_element = fixt!(Element);
// make the author equal to the current `user_hash` value
// on the Goal in validate_data
original_goal_comment.agent_address = WrappedAgentPubKey::new(update_header.author.as_hash().clone());
*original_goal_comment_element.as_entry_mut() =
ElementEntry::Present(original_goal_comment.clone().try_into().unwrap());

let mut mock_hdk = MockHdkT::new();
Expand All @@ -334,7 +333,7 @@ pub mod tests {
GetOptions::content(),
)))
.times(1)
.return_const(Ok(Some(goal_comment_element.clone())));
.return_const(Ok(Some(original_goal_comment_element.clone())));

set_hdk(mock_hdk);

Expand Down
Loading

0 comments on commit b2f21db

Please sign in to comment.