<?php
namespace apache\shindig\test\gadgets;
use apache\shindig\gadgets\MakeRequest;
use apache\shindig\gadgets\GadgetContext;
use apache\shindig\common\RemoteContentRequest;
use apache\shindig\gadgets\MakeRequestOptions;
use apache\shindig\common\RemoteContentFetcher;
use apache\shindig\common\sample\BasicSecurityToken;

/**
 * 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() {
    $_SERVER["HTTP_HOST"] = 'localhost';
    date_default_timezone_set('GMT');
    $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(urldecode($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(urldecode($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 invalid request headers are not passed in the outgoing
   * request.
   */
  public function testInvalidRequestHeaders(){
    $params = new MakeRequestOptions('http://www.example.com');
    $params->setRequestHeaders(array(
      "Content-Type" => "application/json",
      "Accept-Language" => "en-us",
      "Host" => "http://www.evil.com",
      "host" => "http://www.evil.com",
      "HOST" => "http://www.evil.com",
      "Accept" => "blah",
      "Accept-Encoding" => "blah"
    ));
    $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'));

    $this->assertNull($request->getHeader('Host'));
    $this->assertNull($request->getHeader('Accept'));
    $this->assertNull($request->getHeader('Accept-Encoding'));
  }

  /**
   * 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'));
  }

  public function testResponseHeaders() {
    $params = new MakeRequestOptions('http://www.example.com');
    $params->setNoCache(true);

    $headers = array(
      'Content-Type' => 'text/plain'
    );
    $this->response->setResponseHeaders($headers);
    $this->fetcher->enqueueResponse($this->response);

    $result = $this->makeRequest->fetch($this->context, $params);
    $response_headers = $result->getResponseHeaders();

    $this->assertArrayHasKey('Content-Type', $response_headers);
    $this->assertEquals('text/plain', $response_headers['Content-Type']);
  }

  public function testCleanResponseHeaders() {
    $response_headers = array(
      'Content-Type' => 'text/plain',
      'Set-Cookie' => 'blah',
      'set-cookie' => 'blah',
      'SET-COOKIE' => 'blah',
      'sEt-cOoKiE' => 'blah',
      'Accept-Ranges' => 'blah',
      'Vary' => 'blah',
      'Expires' => 'blah',
      'Date' => 'blah',
      'Pragma' => 'blah',
      'Cache-Control' => 'blah',
      'Transfer-Encoding' => 'blah',
      'WWW-Authenticate' => 'blah'
    );
    
    $cleaned_headers = $this->makeRequest->cleanResponseHeaders($response_headers);

    $this->assertArrayHasKey('Content-Type', $cleaned_headers);
    $this->assertEquals('text/plain', $cleaned_headers['Content-Type']);
    $this->assertArrayNotHasKey('Set-Cookie', $cleaned_headers);
    $this->assertArrayNotHasKey('set-cookie', $cleaned_headers);
    $this->assertArrayNotHasKey('SET-COOKIE', $cleaned_headers);
    $this->assertArrayNotHasKey('sEt-cOoKiE', $cleaned_headers);
    $this->assertArrayNotHasKey('Accept-Ranges', $cleaned_headers);
    $this->assertArrayNotHasKey('Vary', $cleaned_headers);
    $this->assertArrayNotHasKey('Expires', $cleaned_headers);
    $this->assertArrayNotHasKey('Date', $cleaned_headers);
    $this->assertArrayNotHasKey('Pragma', $cleaned_headers);
    $this->assertArrayNotHasKey('Cache-Control', $cleaned_headers);
    $this->assertArrayNotHasKey('Transfer-Encoding', $cleaned_headers);
    $this->assertArrayNotHasKey('WWW-Authenticate', $cleaned_headers);
  }
}

