1212namespace Overblog \GraphQLBundle \Tests \Resolver ;
1313
1414use Overblog \GraphQLBundle \ExpressionLanguage \ExpressionLanguage ;
15+ use Overblog \GraphQLBundle \Relay \Connection \Output \ConnectionBuilder ;
1516use Overblog \GraphQLBundle \Resolver \ConfigResolver ;
17+ use Overblog \GraphQLBundle \Tests \DIContainerMockTrait ;
18+ use Symfony \Component \ExpressionLanguage \Expression ;
1619
1720class ConfigResolverTest extends \PHPUnit_Framework_TestCase
1821{
22+ use DIContainerMockTrait;
23+
1924 /** @var ConfigResolver */
20- private static $ configResolver ;
25+ private $ configResolver ;
2126
2227 public function setUp ()
2328 {
24- $ container = $ this ->getMockBuilder ('Symfony\Component\DependencyInjection\Container ' )
25- ->getMock ();
29+ $ container = $ this ->getDIContainerMock ();
2630 $ container
2731 ->method ('get ' )
2832 ->will ($ this ->returnValue (new \stdClass ()));
@@ -51,7 +55,7 @@ public function setUp()
5155 ->method ('resolve ' )
5256 ->will ($ this ->returnValue (new \stdClass ()));
5357
54- self :: $ configResolver = new ConfigResolver (
58+ $ this -> configResolver = new ConfigResolver (
5559 $ typeResolver ,
5660 $ fieldResolver ,
5761 $ argResolver ,
@@ -66,12 +70,12 @@ public function setUp()
6670 */
6771 public function testConfigNotArrayOrImplementArrayAccess ()
6872 {
69- self :: $ configResolver ->resolve ('Not Array ' );
73+ $ this -> configResolver ->resolve ('Not Array ' );
7074 }
7175
7276 public function testResolveValues ()
7377 {
74- $ config = self :: $ configResolver ->resolve (
78+ $ config = $ this -> configResolver ->resolve (
7579 [
7680 'values ' => [
7781 'test ' => ['value ' => 'my test value ' ],
@@ -91,4 +95,106 @@ public function testResolveValues()
9195
9296 $ this ->assertEquals ($ expected , $ config );
9397 }
98+
99+ /**
100+ * @expectedException \Overblog\GraphQLBundle\Error\UserError
101+ * @expectedExceptionMessage Access denied to this field
102+ */
103+ public function testResolveAccessAndWrapResolveCallbackWithScalarValueAndAccessDenied ()
104+ {
105+ $ callback = $ this ->invokeResolveAccessAndWrapResolveCallback (false );
106+ $ callback ('toto ' );
107+ }
108+
109+ /**
110+ * @expectedException \Overblog\GraphQLBundle\Error\UserError
111+ * @expectedExceptionMessage Access denied to this field
112+ */
113+ public function testResolveAccessAndWrapResolveCallbackWithScalarValueAndExpressionEvalThrowingException ()
114+ {
115+ $ callback = $ this ->invokeResolveAccessAndWrapResolveCallback ('@=oups ' );
116+ $ callback ('titi ' );
117+ }
118+
119+ public function testResolveAccessAndWrapResolveCallbackWithScalarValueAndAccessDeniedGranted ()
120+ {
121+ $ callback = $ this ->invokeResolveAccessAndWrapResolveCallback (true );
122+ $ this ->assertEquals ('toto ' , $ callback ('toto ' ));
123+ }
124+
125+ public function testResolveAccessAndWrapResolveCallbackWithArrayAndAccessDeniedToEveryItemStartingByTo ()
126+ {
127+ $ callback = $ this ->invokeResolveAccessAndWrapResolveCallback ('@=not(object matches "/^to.*/i") ' );
128+ $ this ->assertEquals (
129+ [
130+ 'tata ' ,
131+ 'titi ' ,
132+ 'tata ' ,
133+ ],
134+ $ callback (
135+ [
136+ 'tata ' ,
137+ 'titi ' ,
138+ 'tata ' ,
139+ 'toto ' ,
140+ 'tota ' ,
141+ ]
142+ )
143+ );
144+ }
145+
146+ public function testResolveAccessAndWrapResolveCallbackWithRelayConnectionAndAccessGrantedToEveryNodeStartingByTo ()
147+ {
148+ $ callback = $ this ->invokeResolveAccessAndWrapResolveCallback ('@=object matches "/^to.*/i" ' );
149+ $ this ->assertEquals (
150+ ConnectionBuilder::connectionFromArray (['toto ' , 'toti ' , null , null , null ]),
151+ $ callback (
152+ ConnectionBuilder::connectionFromArray (['toto ' , 'toti ' , 'coco ' , 'foo ' , 'bar ' ])
153+ )
154+ );
155+ }
156+
157+ /**
158+ * @param bool|string $hasAccess
159+ * @param callable|null $callback
160+ *
161+ * @return callback
162+ */
163+ private function invokeResolveAccessAndWrapResolveCallback ($ hasAccess , callable $ callback = null )
164+ {
165+ if (null === $ callback ) {
166+ $ callback = function ($ value ) {
167+ return $ value ;
168+ };
169+ }
170+
171+ return $ this ->invokeMethod (
172+ $ this ->configResolver ,
173+ 'resolveAccessAndWrapResolveCallback ' ,
174+ [
175+ $ hasAccess ,
176+ $ callback ,
177+ ]
178+ );
179+ }
180+
181+ /**
182+ * Call protected/private method of a class.
183+ *
184+ * @see https://jtreminio.com/2013/03/unit-testing-tutorial-part-3-testing-protected-private-methods-coverage-reports-and-crap/
185+ *
186+ * @param object $object Instantiated object that we will run method on.
187+ * @param string $methodName Method name to call
188+ * @param array $parameters Array of parameters to pass into method.
189+ *
190+ * @return mixed Method return.
191+ */
192+ private function invokeMethod ($ object , $ methodName , array $ parameters = [])
193+ {
194+ $ reflection = new \ReflectionClass (get_class ($ object ));
195+ $ method = $ reflection ->getMethod ($ methodName );
196+ $ method ->setAccessible (true );
197+
198+ return $ method ->invokeArgs ($ object , $ parameters );
199+ }
94200}
0 commit comments