You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2009/09/22 12:43:27 UTC
svn commit: r817585 - in /incubator/shindig/trunk/php/test:
gadgets/MakeRequestTest.php misc/sampleAtomFeed.xml
Author: chabotc
Date: Tue Sep 22 10:43:27 2009
New Revision: 817585
URL: http://svn.apache.org/viewvc?rev=817585&view=rev
Log:
SHINDIG-1172 by Arne Roomann-Kurrik - makeRequest unit tests
Added:
incubator/shindig/trunk/php/test/gadgets/MakeRequestTest.php
incubator/shindig/trunk/php/test/misc/sampleAtomFeed.xml
Added: incubator/shindig/trunk/php/test/gadgets/MakeRequestTest.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/test/gadgets/MakeRequestTest.php?rev=817585&view=auto
==============================================================================
--- incubator/shindig/trunk/php/test/gadgets/MakeRequestTest.php (added)
+++ incubator/shindig/trunk/php/test/gadgets/MakeRequestTest.php Tue Sep 22 10:43:27 2009
@@ -0,0 +1,494 @@
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides an implementation of RemoteContentFetcher which can be controlled
+ * by unit tests and does not actually make any external requests.
+ * RemoteContentRequest objects added to this class are added to an internal
+ * FIFO queue. Every time a request is sent to fetchRequest, the next
+ * RemoteContentRequest object in the queue is returned as a response.
+ * Requests sent to fetchRequest are also stored in a queue for later retrieval
+ * and examination.
+ */
+class MockMakeRequestFetcher extends RemoteContentFetcher {
+ private $responses;
+ private $requests;
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ $this->responses = array();
+ $this->requests = array();
+ }
+
+ /**
+ * Adds a response object to an internal queue of responses.
+ * @param RemoteContentRequest $response The response to return.
+ */
+ public function enqueueResponse(RemoteContentRequest $response) {
+ $this->responses[] = $response;
+ }
+
+ /**
+ * Returns a request object that was sent to fetchRequest. If multiple
+ * requests have been sent to fetchRequest, they are returned by this
+ * method in the order they were requested.
+ * @return RemoteContentRequest
+ */
+ public function dequeueRequest() {
+ return array_shift($this->requests);
+ }
+
+ /**
+ * Fakes a content request to a remote server.
+ * @param RemoteContentRequest $request The external request information.
+ * @return RemoteContentRequest The next response which was enqueued by
+ * calling enqueueResponse.
+ */
+ public function fetchRequest(RemoteContentRequest $request) {
+ $this->requests[] = $request;
+ return array_shift($this->responses);
+ }
+
+ /**
+ * Fakes multiple requests to a remote server. Calls fetchRequest for
+ * each request passed to this method.
+ * @param array $requests An array of RemoteContentRequests.
+ * @return An array of RemoteContentRequests corresponging to the responses
+ * returned for each of the request inputs.
+ */
+ public function multiFetchRequest(Array $requests) {
+ $responses = array();
+ foreach ($requests as $key => $request) {
+ $responses[$key] = $this->fetchRequest($request);
+ }
+ return $responses;
+ }
+}
+
+/**
+ * Unit tests for the MakeRequest class.
+ */
+class MakeRequestTest extends PHPUnit_Framework_TestCase {
+ private $fetcher;
+ private $makeRequest;
+ private $context;
+ private $response;
+
+ /**
+ * Prepares the environment before running a test.
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->fetcher = new MockMakeRequestFetcher();
+ $this->makeRequest = new MakeRequest($this->fetcher);
+ $this->context = new GadgetContext('GADGET');
+
+ $this->response = new RemoteContentRequest('http://www.example.com');
+ $this->response->setHttpCode(200);
+ $this->response->setResponseContent("Basic response");
+ }
+
+ /**
+ * Cleans up the environment after running a test.
+ */
+ protected function tearDown() {
+ parent::tearDown();
+ }
+
+ /**
+ * Executes a makeRequest call and returns the request object which would
+ * have been sent externally (as opposed to the response).
+ *
+ * @param MakeRequestOptions $params
+ * @param RemoteContentRequest $response The response to return for this
+ * request.
+ * @return RemoteContentRequest The request object.
+ */
+ protected function catchRequest(MakeRequestOptions $params, RemoteContentRequest $response) {
+ $this->fetcher->enqueueResponse($response);
+ $result = $this->makeRequest->fetch($this->context, $params);
+ return $this->fetcher->dequeueRequest();
+ }
+
+ /**
+ * Tests that makeRequest calls with an invalid url throw an exception.
+ */
+ public function testInvalidUrl() {
+ try {
+ $params = new MakeRequestOptions('invalidurl');
+ $this->makeRequest->fetch($params);
+ $this->fail("Calling makeRequest with an invalid url should throw an exception.");
+ } catch (Exception $ex) { }
+ }
+
+ /**
+ * Tests that normal requests specify a GET to the supplied URL.
+ */
+ public function testBasicRequest() {
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertContains($request->getUrl(), 'http://www.example.com');
+ $this->assertEquals('GET', $request->getMethod());
+ }
+
+ /**
+ * Tests that signed requests generate appropriate oauth_ and opensocial_
+ * parameters.
+ */
+ public function testSignedRequest() {
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 'domain', 'appUrl', '1', 'default');
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setAuthz('SIGNED')
+ ->setNoCache(true)
+ ->setSecurityTokenString(urlencode(base64_encode($token->toSerialForm())));
+
+ $request = $this->catchRequest($params, $this->response);
+
+ $this->assertContains('oauth_signature', $request->getUrl());
+ $this->assertContains('oauth_signature_method=RSA-SHA1', $request->getUrl());
+ $this->assertContains('opensocial_app_url=appUrl', $request->getUrl());
+ $this->assertContains('opensocial_viewer_id=viewer', $request->getUrl());
+ $this->assertContains('opensocial_owner_id=owner', $request->getUrl());
+ $this->assertEquals('GET', $request->getMethod());
+ }
+
+ /**
+ * Tests that setting "sign_viewer" = false does not include viewer
+ * information in the request.
+ */
+ public function testSignedNoViewerRequest() {
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 'domain', 'appUrl', '1', 'default');
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setAuthz('SIGNED')
+ ->setNoCache(true)
+ ->setSignViewer(false)
+ ->setSecurityTokenString(urlencode(base64_encode($token->toSerialForm())));
+
+ $request = $this->catchRequest($params, $this->response);
+
+ $this->assertContains('oauth_signature', $request->getUrl());
+ $this->assertNotContains('opensocial_viewer_id=viewer', $request->getUrl());
+ $this->assertContains('opensocial_owner_id=owner', $request->getUrl());
+ }
+
+ /**
+ * Tests that setting "format" = "FEED" parses an atom feed into a JSON
+ * structure.
+ */
+ public function testFeedRequest() {
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setResponseFormat('FEED')
+ ->setNoCache(true)
+ ->setNumEntries(2);
+
+ $sampleAtomPath = realpath(dirname(__FILE__) . "/../misc/sampleAtomFeed.xml");
+ $sampleAtom = file_get_contents($sampleAtomPath);
+ $this->response->setResponseContent($sampleAtom);
+ $this->fetcher->enqueueResponse($this->response);
+ $result = $this->makeRequest->fetch($this->context, $params);
+ $feedJson = json_decode($result->getResponseContent(), true);
+
+ $this->assertArrayHasKey('Entry', $feedJson);
+ $this->assertEquals(2, count($feedJson['Entry']));
+ $this->assertArrayHasKey('Title', $feedJson['Entry'][0]);
+ $this->assertEquals("Atom-Powered Robots Run Amok", $feedJson['Entry'][0]['Title']);
+ }
+
+ /**
+ * Tests that setting request headers are passed in the outgoing request.
+ */
+ public function testRequestHeaders(){
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setRequestHeaders(array(
+ "Content-Type" => "application/json",
+ "Accept-Language" => "en-us"
+ ));
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertTrue($request->hasHeaders());
+ $this->assertEquals('application/json', $request->getHeader('Content-Type'));
+ $this->assertEquals('en-us', $request->getHeader('Accept-Language'));
+ }
+
+ /**
+ * Tests that setting request headers in a form urlencoded way are passed in the outgoing request.
+ */
+ public function testFormEncodedRequestHeaders(){
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setFormEncodedRequestHeaders("Content-Type=application%2Fx-www-form-urlencoded&Accept-Language=en-us");
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertTrue($request->hasHeaders());
+ $this->assertEquals('application/x-www-form-urlencoded', $request->getHeader('Content-Type'));
+ }
+}
+
+<?php
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * Provides an implementation of RemoteContentFetcher which can be controlled
+ * by unit tests and does not actually make any external requests.
+ * RemoteContentRequest objects added to this class are added to an internal
+ * FIFO queue. Every time a request is sent to fetchRequest, the next
+ * RemoteContentRequest object in the queue is returned as a response.
+ * Requests sent to fetchRequest are also stored in a queue for later retrieval
+ * and examination.
+ */
+class MockMakeRequestFetcher extends RemoteContentFetcher {
+ private $responses;
+ private $requests;
+
+ /**
+ * Constructor.
+ */
+ public function __construct() {
+ $this->responses = array();
+ $this->requests = array();
+ }
+
+ /**
+ * Adds a response object to an internal queue of responses.
+ * @param RemoteContentRequest $response The response to return.
+ */
+ public function enqueueResponse(RemoteContentRequest $response) {
+ $this->responses[] = $response;
+ }
+
+ /**
+ * Returns a request object that was sent to fetchRequest. If multiple
+ * requests have been sent to fetchRequest, they are returned by this
+ * method in the order they were requested.
+ * @return RemoteContentRequest
+ */
+ public function dequeueRequest() {
+ return array_shift($this->requests);
+ }
+
+ /**
+ * Fakes a content request to a remote server.
+ * @param RemoteContentRequest $request The external request information.
+ * @return RemoteContentRequest The next response which was enqueued by
+ * calling enqueueResponse.
+ */
+ public function fetchRequest(RemoteContentRequest $request) {
+ $this->requests[] = $request;
+ return array_shift($this->responses);
+ }
+
+ /**
+ * Fakes multiple requests to a remote server. Calls fetchRequest for
+ * each request passed to this method.
+ * @param array $requests An array of RemoteContentRequests.
+ * @return An array of RemoteContentRequests corresponging to the responses
+ * returned for each of the request inputs.
+ */
+ public function multiFetchRequest(Array $requests) {
+ $responses = array();
+ foreach ($requests as $key => $request) {
+ $responses[$key] = $this->fetchRequest($request);
+ }
+ return $responses;
+ }
+}
+
+/**
+ * Unit tests for the MakeRequest class.
+ */
+class MakeRequestTest extends PHPUnit_Framework_TestCase {
+ private $fetcher;
+ private $makeRequest;
+
+ /**
+ * Prepares the environment before running a test.
+ */
+ protected function setUp() {
+ parent::setUp();
+ $this->fetcher = new MockMakeRequestFetcher();
+ $this->makeRequest = new MakeRequest($this->fetcher);
+ $this->context = new GadgetContext('GADGET');
+
+ $this->response = new RemoteContentRequest('http://www.example.com');
+ $this->response->setHttpCode(200);
+ $this->response->setResponseContent("Basic response");
+ }
+
+ /**
+ * Cleans up the environment after running a test.
+ */
+ protected function tearDown() {
+ parent::tearDown();
+ }
+
+ /**
+ * Executes a makeRequest call and returns the request object which would
+ * have been sent externally (as opposed to the response).
+ *
+ * @param MakeRequestOptions $params
+ * @param RemoteContentRequest $response The response to return for this
+ * request.
+ * @return RemoteContentRequest The request object.
+ */
+ protected function catchRequest(MakeRequestOptions $params, RemoteContentRequest $response) {
+ $this->fetcher->enqueueResponse($response);
+ $result = $this->makeRequest->fetch($this->context, $params);
+ return $this->fetcher->dequeueRequest();
+ }
+
+ /**
+ * Tests that makeRequest calls with an invalid url throw an exception.
+ */
+ public function testInvalidUrl() {
+ try {
+ $params = new MakeRequestOptions('invalidurl');
+ $this->makeRequest->fetch($params);
+ $this->fail("Calling makeRequest with an invalid url should throw an exception.");
+ } catch (Exception $ex) { }
+ }
+
+ /**
+ * Tests that normal requests specify a GET to the supplied URL.
+ */
+ public function testBasicRequest() {
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertContains($request->getUrl(), 'http://www.example.com');
+ $this->assertEquals('GET', $request->getMethod());
+ }
+
+ /**
+ * Tests that signed requests generate appropriate oauth_ and opensocial_
+ * parameters.
+ */
+ public function testSignedRequest() {
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 'domain', 'appUrl', '1', 'default');
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setAuthz('SIGNED')
+ ->setNoCache(true)
+ ->setSecurityTokenString(urlencode(base64_encode($token->toSerialForm())));
+
+ $request = $this->catchRequest($params, $this->response);
+
+ $this->assertContains('oauth_signature', $request->getUrl());
+ $this->assertContains('oauth_signature_method=RSA-SHA1', $request->getUrl());
+ $this->assertContains('opensocial_app_url=appUrl', $request->getUrl());
+ $this->assertContains('opensocial_viewer_id=viewer', $request->getUrl());
+ $this->assertContains('opensocial_owner_id=owner', $request->getUrl());
+ $this->assertEquals('GET', $request->getMethod());
+ }
+
+ /**
+ * Tests that setting "sign_viewer" = false does not include viewer
+ * information in the request.
+ */
+ public function testSignedNoViewerRequest() {
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app', 'domain', 'appUrl', '1', 'default');
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setAuthz('SIGNED')
+ ->setNoCache(true)
+ ->setSignViewer(false)
+ ->setSecurityTokenString(urlencode(base64_encode($token->toSerialForm())));
+
+ $request = $this->catchRequest($params, $this->response);
+
+ $this->assertContains('oauth_signature', $request->getUrl());
+ $this->assertNotContains('opensocial_viewer_id=viewer', $request->getUrl());
+ $this->assertContains('opensocial_owner_id=owner', $request->getUrl());
+ }
+
+ /**
+ * Tests that setting "format" = "FEED" parses an atom feed into a JSON
+ * structure.
+ */
+ public function testFeedRequest() {
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setResponseFormat('FEED')
+ ->setNoCache(true)
+ ->setNumEntries(2);
+
+ $sampleAtomPath = realpath(dirname(__FILE__) . "/../misc/sampleAtomFeed.xml");
+ $sampleAtom = file_get_contents($sampleAtomPath);
+ $this->response->setResponseContent($sampleAtom);
+ $this->fetcher->enqueueResponse($this->response);
+ $result = $this->makeRequest->fetch($this->context, $params);
+ $feedJson = json_decode($result->getResponseContent(), true);
+
+ $this->assertArrayHasKey('Entry', $feedJson);
+ $this->assertEquals(2, count($feedJson['Entry']));
+ $this->assertArrayHasKey('Title', $feedJson['Entry'][0]);
+ $this->assertEquals("Atom-Powered Robots Run Amok", $feedJson['Entry'][0]['Title']);
+ }
+
+ /**
+ * Tests that setting request headers are passed in the outgoing request.
+ */
+ public function testRequestHeaders(){
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setRequestHeaders(array(
+ "Content-Type" => "application/json",
+ "Accept-Language" => "en-us"
+ ));
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertTrue($request->hasHeaders());
+ $this->assertEquals('application/json', $request->getHeader('Content-Type'));
+ $this->assertEquals('en-us', $request->getHeader('Accept-Language'));
+ }
+
+ /**
+ * Tests that setting request headers in a form urlencoded way are passed in the outgoing request.
+ */
+ public function testFormEncodedRequestHeaders(){
+ $params = new MakeRequestOptions('http://www.example.com');
+ $params->setFormEncodedRequestHeaders("Content-Type=application%2Fx-www-form-urlencoded&Accept-Language=en-us");
+ $params->setNoCache(true);
+
+ $request = $this->catchRequest($params, $this->response);
+ $this->assertTrue($request->hasHeaders());
+ $this->assertEquals('application/x-www-form-urlencoded', $request->getHeader('Content-Type'));
+ }
+}
+
Added: incubator/shindig/trunk/php/test/misc/sampleAtomFeed.xml
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/test/misc/sampleAtomFeed.xml?rev=817585&view=auto
==============================================================================
--- incubator/shindig/trunk/php/test/misc/sampleAtomFeed.xml (added)
+++ incubator/shindig/trunk/php/test/misc/sampleAtomFeed.xml Tue Sep 22 10:43:27 2009
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>Example Feed</title>
+ <subtitle>A subtitle.</subtitle>
+ <link href="http://example.org/feed/" rel="self" />
+ <link href="http://example.org/" />
+ <id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
+ <updated>2009-01-03T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ <email>johndoe@example.com</email>
+ </author>
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/entry1" />
+ <id>urn:uuid:11111111-1111-1111-1111-111111111111</id>
+ <updated>2009-01-01T18:30:02Z</updated>
+ <summary>This is the first sample atom entry.</summary>
+ </entry>
+ <entry>
+ <title>Atom-Powered Robots Now OK</title>
+ <link href="http://example.org/entry2" />
+ <id>urn:uuid:22222222-2222-2222-2222-222222222222</id>
+ <updated>2009-01-02T18:30:02Z</updated>
+ <summary>This is the second sample atom entry.</summary>
+ </entry>
+ <entry>
+ <title>Atom Feed Samples Interesting, Scientists Say</title>
+ <link href="http://example.org/entry3" />
+ <id>urn:uuid:333333333-3333-3333-3333-333333333333</id>
+ <updated>2009-01-03T18:30:02Z</updated>
+ <summary>This is the third sample atom entry.</summary>
+ </entry>
+</feed>
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title>Example Feed</title>
+ <subtitle>A subtitle.</subtitle>
+ <link href="http://example.org/feed/" rel="self" />
+ <link href="http://example.org/" />
+ <id>urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6</id>
+ <updated>2009-01-03T18:30:02Z</updated>
+ <author>
+ <name>John Doe</name>
+ <email>johndoe@example.com</email>
+ </author>
+ <entry>
+ <title>Atom-Powered Robots Run Amok</title>
+ <link href="http://example.org/entry1" />
+ <id>urn:uuid:11111111-1111-1111-1111-111111111111</id>
+ <updated>2009-01-01T18:30:02Z</updated>
+ <summary>This is the first sample atom entry.</summary>
+ </entry>
+ <entry>
+ <title>Atom-Powered Robots Now OK</title>
+ <link href="http://example.org/entry2" />
+ <id>urn:uuid:22222222-2222-2222-2222-222222222222</id>
+ <updated>2009-01-02T18:30:02Z</updated>
+ <summary>This is the second sample atom entry.</summary>
+ </entry>
+ <entry>
+ <title>Atom Feed Samples Interesting, Scientists Say</title>
+ <link href="http://example.org/entry3" />
+ <id>urn:uuid:333333333-3333-3333-3333-333333333333</id>
+ <updated>2009-01-03T18:30:02Z</updated>
+ <summary>This is the third sample atom entry.</summary>
+ </entry>
+</feed>
\ No newline at end of file