diff --git a/ResearchKit/Common/ORKResultPredicate.h b/ResearchKit/Common/ORKResultPredicate.h index dbc43a5b..b4c7b325 100644 --- a/ResearchKit/Common/ORKResultPredicate.h +++ b/ResearchKit/Common/ORKResultPredicate.h @@ -514,6 +514,19 @@ within the specified `NSTimeInterval` values. minimumExpectedAnswerDate:(nullable NSDate *)minimumExpectedAnswerDate maximumExpectedAnswerDate:(nullable NSDate *)maximumExpectedAnswerDate; +/** + Returns a predicate matching a result of type `ORKConsentSignatureResult` whose `consented` value + matches the specified boolean value. + + @param resultSelector The result selector object which specifies the question result + you are interested in. + @param didConsent Whether the user consented to the `ORKConsentReviewStep` + + @return A result predicate. + */ ++ (NSPredicate *)predicateForConsentWithResultSelector:(ORKResultSelector *)resultSelector + didConsent:(BOOL)didConsent; + @end NS_ASSUME_NONNULL_END diff --git a/ResearchKit/Common/ORKResultPredicate.m b/ResearchKit/Common/ORKResultPredicate.m index 72b9b0fe..ac2f4a66 100644 --- a/ResearchKit/Common/ORKResultPredicate.m +++ b/ResearchKit/Common/ORKResultPredicate.m @@ -448,4 +448,10 @@ NSString *const ORKResultPredicateTaskIdentifierVariableName = @"ORK_TASK_IDENTI subPredicateFormatArgumentArray:subPredicateFormatArgumentArray]; } ++ (NSPredicate *)predicateForConsentWithResultSelector:(ORKResultSelector *)resultSelector didConsent:(BOOL)didConsent { + return [self predicateMatchingResultSelector:resultSelector + subPredicateFormatArray:@[ @"consented == %@" ] + subPredicateFormatArgumentArray:@[ @(didConsent) ]]; +} + @end diff --git a/ResearchKitTests/ORKTaskTests.m b/ResearchKitTests/ORKTaskTests.m index 1d50b148..bf444288 100644 --- a/ResearchKitTests/ORKTaskTests.m +++ b/ResearchKitTests/ORKTaskTests.m @@ -584,6 +584,9 @@ BOOL (^testStepBeforeStep)(ORKNavigableOrderedTask *, ORKTaskResult *, ORKStep * XCTAssertTrue(testStepAfterStep(skipTask, taskResult, severityStep, nil)); } +ORKDefineStringKey(SignConsentStepIdentifier); +ORKDefineStringKey(SignatureIdentifier); + ORKDefineStringKey(ScaleStepIdentifier); ORKDefineStringKey(ContinuousScaleStepIdentifier); static const NSInteger IntegerValue = 6; @@ -653,6 +656,12 @@ static ORKStepResult *(^getStepResult)(NSString *, Class, ORKQuestionType, id) = return stepResult; }; +static ORKStepResult *(^getConsentStepResult)(NSString *, NSString *, BOOL) = ^ORKStepResult *(NSString *stepIdentifier, NSString *signatureIdentifier, BOOL consented) { + ORKConsentSignatureResult *consentSignatureResult = [[ORKConsentSignatureResult alloc] initWithIdentifier:signatureIdentifier]; + consentSignatureResult.consented = consented; + return [[ORKStepResult alloc] initWithStepIdentifier:stepIdentifier results:@[consentSignatureResult]]; +}; + - (ORKTaskResult *)getGeneralTaskResultTree { NSMutableArray *stepResults = [NSMutableArray new]; @@ -687,6 +696,19 @@ static ORKStepResult *(^getStepResult)(NSString *, Class, ORKQuestionType, id) = return taskResult; } +- (ORKTaskResult *)getTaskResultTreeWithConsent:(BOOL)consented { + NSMutableArray *stepResults = [NSMutableArray new]; + + [stepResults addObject:getConsentStepResult(SignConsentStepIdentifier, SignatureIdentifier, consented)]; + + ORKTaskResult *taskResult = [[ORKTaskResult alloc] initWithTaskIdentifier:OrderedTaskIdentifier + taskRunUUID:[NSUUID UUID] + outputDirectory:[NSURL fileURLWithPath:NSTemporaryDirectory()]]; + taskResult.results = stepResults; + + return taskResult; +} + - (ORKTaskResult *)getSmallTaskResultTreeWithIsAdditionalTask:(BOOL)isAdditionalTask { NSMutableArray *stepResults = [NSMutableArray new]; @@ -1334,6 +1356,28 @@ static ORKStepResult *(^getStepResult)(NSString *, Class, ORKQuestionType, id) = XCTAssertFalse([[ORKResultPredicate predicateForNilQuestionResultWithResultSelector:resultSelector] evaluateWithObject:taskResults substitutionVariables:substitutionVariables]); } +- (void)testConsentPredicate { + ORKResultSelector *resultSelector = [[ORKResultSelector alloc] initWithTaskIdentifier:OrderedTaskIdentifier + stepIdentifier:SignConsentStepIdentifier + resultIdentifier:SignatureIdentifier]; + { + ORKTaskResult *consentedTaskResult = [self getTaskResultTreeWithConsent:YES]; + XCTAssertTrue([[ORKResultPredicate predicateForConsentWithResultSelector:resultSelector + didConsent:YES] evaluateWithObject:@[consentedTaskResult] substitutionVariables:nil]); + XCTAssertFalse([[ORKResultPredicate predicateForConsentWithResultSelector:resultSelector + didConsent:NO] evaluateWithObject:@[consentedTaskResult] substitutionVariables:nil]); + } + + { + ORKTaskResult *didNotConsentTaskResult = [self getTaskResultTreeWithConsent:NO]; + + XCTAssertTrue([[ORKResultPredicate predicateForConsentWithResultSelector:resultSelector + didConsent:NO] evaluateWithObject:@[didNotConsentTaskResult] substitutionVariables:nil]); + XCTAssertFalse([[ORKResultPredicate predicateForConsentWithResultSelector:resultSelector + didConsent:YES] evaluateWithObject:@[didNotConsentTaskResult] substitutionVariables:nil]); + } +} + - (void)testResultPredicates { ORKTaskResult *taskResult = [self getGeneralTaskResultTree]; NSArray *taskResults = @[ taskResult ];