99from  graphene .relay  import  Node 
1010from  graphene_django  import  DjangoObjectType 
1111from  graphene_django .utils  import  DJANGO_FILTER_INSTALLED 
12+ from  graphene_django .filter  import  ArrayFilter , ListFilter 
1213
1314from  ...compat  import  ArrayField 
1415
2728STORE  =  {"events" : []}
2829
2930
30- @pytest .fixture  
31- def  Event ():
32-     class  Event (models .Model ):
33-         name  =  models .CharField (max_length = 50 )
34-         tags  =  ArrayField (models .CharField (max_length = 50 ))
35- 
36-     return  Event 
31+ class  Event (models .Model ):
32+     name  =  models .CharField (max_length = 50 )
33+     tags  =  ArrayField (models .CharField (max_length = 50 ))
34+     tag_ids  =  ArrayField (models .IntegerField ())
35+     random_field  =  ArrayField (models .BooleanField ())
3736
3837
3938@pytest .fixture  
40- def  EventFilterSet (Event ):
41- 
42-     from  django .contrib .postgres .forms  import  SimpleArrayField 
43- 
44-     class  ArrayFilter (filters .Filter ):
45-         base_field_class  =  SimpleArrayField 
46- 
39+ def  EventFilterSet ():
4740    class  EventFilterSet (FilterSet ):
4841        class  Meta :
4942            model  =  Event 
5043            fields  =  {
51-                 "name" : ["exact" ],
44+                 "name" : ["exact" ,  "contains" ],
5245            }
5346
47+         # Those are actually usable with our Query fixture bellow 
5448        tags__contains  =  ArrayFilter (field_name = "tags" , lookup_expr = "contains" )
5549        tags__overlap  =  ArrayFilter (field_name = "tags" , lookup_expr = "overlap" )
50+         tags  =  ArrayFilter (field_name = "tags" , lookup_expr = "exact" )
51+ 
52+         # Those are actually not usable and only to check type declarations 
53+         tags_ids__contains  =  ArrayFilter (field_name = "tag_ids" , lookup_expr = "contains" )
54+         tags_ids__overlap  =  ArrayFilter (field_name = "tag_ids" , lookup_expr = "overlap" )
55+         tags_ids  =  ArrayFilter (field_name = "tag_ids" , lookup_expr = "exact" )
56+         random_field__contains  =  ArrayFilter (
57+             field_name = "random_field" , lookup_expr = "contains" 
58+         )
59+         random_field__overlap  =  ArrayFilter (
60+             field_name = "random_field" , lookup_expr = "overlap" 
61+         )
62+         random_field  =  ArrayFilter (field_name = "random_field" , lookup_expr = "exact" )
5663
5764    return  EventFilterSet 
5865
5966
6067@pytest .fixture  
61- def  EventType (Event ,  EventFilterSet ):
68+ def  EventType (EventFilterSet ):
6269    class  EventType (DjangoObjectType ):
6370        class  Meta :
6471            model  =  Event 
6572            interfaces  =  (Node ,)
73+             fields  =  "__all__" 
6674            filterset_class  =  EventFilterSet 
6775
6876    return  EventType 
6977
7078
7179@pytest .fixture  
72- def  Query (Event , EventType ):
80+ def  Query (EventType ):
81+     """ 
82+     Note that we have to use a custom resolver to replicate the arrayfield filter behavior as 
83+     we are running unit tests in sqlite which does not have ArrayFields. 
84+     """ 
85+ 
7386    class  Query (graphene .ObjectType ):
7487        events  =  DjangoFilterConnectionField (EventType )
7588
@@ -79,6 +92,7 @@ def resolve_events(self, info, **kwargs):
7992                Event (name = "Live Show" , tags = ["concert" , "music" , "rock" ],),
8093                Event (name = "Musical" , tags = ["movie" , "music" ],),
8194                Event (name = "Ballet" , tags = ["concert" , "dance" ],),
95+                 Event (name = "Speech" , tags = [],),
8296            ]
8397
8498            STORE ["events" ] =  events 
@@ -105,6 +119,13 @@ def filter_events(**kwargs):
105119                            STORE ["events" ],
106120                        )
107121                    )
122+                 if  "tags__exact"  in  kwargs :
123+                     STORE ["events" ] =  list (
124+                         filter (
125+                             lambda  e : set (kwargs ["tags__exact" ]) ==  set (e .tags ),
126+                             STORE ["events" ],
127+                         )
128+                     )
108129
109130            def  mock_queryset_filter (* args , ** kwargs ):
110131                filter_events (** kwargs )
@@ -121,7 +142,9 @@ def mock_queryset_count(*args, **kwargs):
121142            m_queryset .filter .side_effect  =  mock_queryset_filter 
122143            m_queryset .none .side_effect  =  mock_queryset_none 
123144            m_queryset .count .side_effect  =  mock_queryset_count 
124-             m_queryset .__getitem__ .side_effect  =  STORE ["events" ].__getitem__ 
145+             m_queryset .__getitem__ .side_effect  =  lambda  index : STORE [
146+                 "events" 
147+             ].__getitem__ (index )
125148
126149            return  m_queryset 
127150
0 commit comments