@@ -552,6 +552,9 @@ impl Type {
552552 restricted_expr : BorrowedRestrictedExpr < ' _ > ,
553553 extensions : & Extensions < ' _ > ,
554554 ) -> Result < bool , ExtensionFunctionLookupError > {
555+ if restricted_expr. as_unknown ( ) . is_some ( ) {
556+ return Ok ( true ) ;
557+ }
555558 match self {
556559 Type :: Never => Ok ( false ) , // no expr has type Never
557560 Type :: Primitive {
@@ -1742,6 +1745,7 @@ pub enum Primitive {
17421745mod test {
17431746 use super :: * ;
17441747 use crate :: { json_schema, ActionBehavior } ;
1748+ use cedar_policy_core:: ast:: Context ;
17451749 use cool_asserts:: assert_matches;
17461750
17471751 impl Type {
@@ -2520,6 +2524,193 @@ mod test {
25202524 . expect ( "Expected valid schema" )
25212525 }
25222526
2527+ #[ test]
2528+ #[ cfg( feature = "partial-eval" ) ]
2529+ fn test_typecheck_partial_value_with_unknown ( ) {
2530+ let context = Context :: from_json_value ( serde_json:: json!( {
2531+ "a" : {
2532+ "__extn" : {
2533+ "fn" : "unknown" ,
2534+ "arg" : "test_arg"
2535+ }
2536+ } ,
2537+ } ) )
2538+ . unwrap ( ) ;
2539+
2540+ let typeValidator = Type :: record_with_attributes (
2541+ [
2542+ (
2543+ "a" . into ( ) ,
2544+ AttributeType :: optional_attribute ( Type :: primitive_boolean ( ) ) ,
2545+ ) ,
2546+ (
2547+ "b" . into ( ) ,
2548+ AttributeType :: optional_attribute ( Type :: primitive_boolean ( ) ) ,
2549+ ) ,
2550+ (
2551+ "c" . into ( ) ,
2552+ AttributeType :: optional_attribute ( Type :: primitive_boolean ( ) ) ,
2553+ ) ,
2554+ ] ,
2555+ OpenTag :: ClosedAttributes ,
2556+ ) ;
2557+
2558+ let result = typeValidator
2559+ . typecheck_partial_value ( & context. clone ( ) . into ( ) , Extensions :: all_available ( ) ) ;
2560+ assert_eq ! ( result. unwrap( ) , true ) ;
2561+ }
2562+
2563+ #[ test]
2564+ #[ cfg( feature = "partial-eval" ) ]
2565+ fn test_typecheck_partial_value_with_embedded_unknown ( ) {
2566+ let context = Context :: from_json_value ( serde_json:: json!( {
2567+ "a" : {
2568+ "b" : {
2569+ "__extn" : {
2570+ "fn" : "unknown" ,
2571+ "arg" : "test_arg"
2572+ }
2573+ }
2574+ } ,
2575+ } ) )
2576+ . unwrap ( ) ;
2577+
2578+ let embedded_attributes = Type :: record_with_attributes (
2579+ [
2580+ (
2581+ "b" . into ( ) ,
2582+ AttributeType :: optional_attribute ( Type :: primitive_boolean ( ) ) ,
2583+ ) ,
2584+ (
2585+ "c" . into ( ) ,
2586+ AttributeType :: optional_attribute ( Type :: primitive_boolean ( ) ) ,
2587+ ) ,
2588+ ] ,
2589+ OpenTag :: ClosedAttributes ,
2590+ ) ;
2591+
2592+ let typeValidator = Type :: record_with_attributes (
2593+ [ (
2594+ "a" . into ( ) ,
2595+ AttributeType :: optional_attribute ( embedded_attributes) ,
2596+ ) ] ,
2597+ OpenTag :: ClosedAttributes ,
2598+ ) ;
2599+
2600+ let result = typeValidator
2601+ . typecheck_partial_value ( & context. clone ( ) . into ( ) , Extensions :: all_available ( ) ) ;
2602+
2603+ // c is optional attribute it is not required to provide it.
2604+ assert_eq ! ( result. unwrap( ) , true ) ;
2605+ }
2606+
2607+ #[ test]
2608+ #[ cfg( feature = "partial-eval" ) ]
2609+ fn test_typecheck_partial_value_with_unknown1 ( ) {
2610+ let context = Context :: from_json_value ( serde_json:: json!( {
2611+ "foo" : 1 ,
2612+ "bar" : {
2613+ "__extn" : {
2614+ "fn" : "unknown" ,
2615+ "arg" : "test_arg"
2616+ }
2617+ } ,
2618+ } ) )
2619+ . unwrap ( ) ;
2620+
2621+ let typeValidator = Type :: record_with_attributes (
2622+ [
2623+ (
2624+ "foo" . into ( ) ,
2625+ AttributeType :: required_attribute ( Type :: primitive_long ( ) ) ,
2626+ ) ,
2627+ (
2628+ "bar" . into ( ) ,
2629+ AttributeType :: required_attribute ( Type :: primitive_string ( ) ) ,
2630+ ) ,
2631+ ] ,
2632+ OpenTag :: ClosedAttributes ,
2633+ ) ;
2634+
2635+ let result = typeValidator
2636+ . typecheck_partial_value ( & context. clone ( ) . into ( ) , Extensions :: all_available ( ) ) ;
2637+ //success both foo and bar are provided
2638+ assert_eq ! ( result. unwrap( ) , true ) ;
2639+ }
2640+
2641+ #[ test]
2642+ #[ cfg( feature = "partial-eval" ) ]
2643+ fn test_typecheck_partial_value_with_unknown2 ( ) {
2644+ let context = Context :: from_json_value ( serde_json:: json!( {
2645+ "bar" : {
2646+ "__extn" : {
2647+ "fn" : "unknown" ,
2648+ "arg" : "test_arg"
2649+ }
2650+ } ,
2651+ "foo" : 1 ,
2652+ } ) )
2653+ . unwrap ( ) ;
2654+
2655+ let typeValidator = Type :: record_with_attributes (
2656+ [
2657+ (
2658+ "foo" . into ( ) ,
2659+ AttributeType :: required_attribute ( Type :: primitive_string ( ) ) ,
2660+ ) ,
2661+ (
2662+ "bar" . into ( ) ,
2663+ AttributeType :: required_attribute ( Type :: primitive_string ( ) ) ,
2664+ ) ,
2665+ ] ,
2666+ OpenTag :: ClosedAttributes ,
2667+ ) ;
2668+
2669+ let result = typeValidator
2670+ . typecheck_partial_value ( & context. clone ( ) . into ( ) , Extensions :: all_available ( ) ) ;
2671+ //fail foo is string in schema not long
2672+ assert_eq ! ( result. unwrap( ) , false ) ;
2673+ }
2674+
2675+ #[ test]
2676+ #[ cfg( feature = "partial-eval" ) ]
2677+ fn test_typecheck_partial_value_with_unknown3 ( ) {
2678+ let context = Context :: from_json_value ( serde_json:: json!( {
2679+ "bar" : {
2680+ "__extn" : {
2681+ "fn" : "unknown" ,
2682+ "arg" : "test_arg"
2683+ }
2684+ } ,
2685+ "foo" : 1 ,
2686+ } ) )
2687+ . unwrap ( ) ;
2688+
2689+ let typeValidator = Type :: record_with_attributes (
2690+ [
2691+ (
2692+ "foo" . into ( ) ,
2693+ AttributeType :: required_attribute ( Type :: primitive_long ( ) ) ,
2694+ ) ,
2695+ (
2696+ "bar" . into ( ) ,
2697+ AttributeType :: required_attribute ( Type :: primitive_string ( ) ) ,
2698+ ) ,
2699+ (
2700+ "baz" . into ( ) ,
2701+ AttributeType :: required_attribute ( Type :: primitive_string ( ) ) ,
2702+ ) ,
2703+ ] ,
2704+ OpenTag :: ClosedAttributes ,
2705+ ) ;
2706+
2707+ let result = typeValidator
2708+ . typecheck_partial_value ( & context. clone ( ) . into ( ) , Extensions :: all_available ( ) ) ;
2709+
2710+ //fail baz is required in the schema
2711+ assert_eq ! ( result. unwrap( ) , false ) ;
2712+ }
2713+
25232714 /// Test cases with entity type Action are interesting because Action
25242715 /// does not need to be declared in the entity type list.
25252716 #[ test]
0 commit comments