public function testShouldProperlySetHeadersWithPreExistingValues() { $dummyResponse = new WikiaResponse("tmp"); $dummyResponse->setHeader(CrossOriginResourceSharingHeaderHelper::ALLOW_ORIGIN_HEADER_NAME, "t,m,p"); $cors = new CrossOriginResourceSharingHeaderHelper(); $cors->setAllowOrigin(["a", "b", "t"])->setHeaders($dummyResponse); $headers = $dummyResponse->getHeader(CrossOriginResourceSharingHeaderHelper::ALLOW_ORIGIN_HEADER_NAME); $this->assertEquals($headers[0]['value'], 'a,b,t,t,m,p'); }
public function testViewDefaultRender() { $this->object->setView(F::build('WikiaView')); $this->object->setFormat('raw'); $output = $this->object->getView()->render($this->object); $this->assertStringStartsWith('<pre>', $output); }
/** * This method sets all configured CORS related headers * * @param WikiaResponse $response response object to set headers to * @param bool $mergeExisting */ public function setHeaders(WikiaResponse $response, $mergeExisting = true) { foreach ($this->allowValues as $headerName => $values) { if (!empty($values)) { $valuesToSet = $values; $headers = $response->getHeader($headerName); if (!empty($headers) && $mergeExisting) { $response->removeHeader($headerName); foreach ($headers as $header) { $valuesToSet = array_merge($valuesToSet, explode(self::HEADER_DELIMETER, $header['value'])); } } $response->setHeader($headerName, implode(self::HEADER_DELIMETER, $valuesToSet)); } } return $this; }
/** * @dataProvider cachingHeadersProvider */ public function testCachingHeaders($varnishTTL, $clientTTL, $cachingPolicy, $expectedValue, $passExpectedValue) { $this->object->setCachePolicy($cachingPolicy); $this->object->setCacheValidity($varnishTTL, $clientTTL); $cacheControlValue = $this->object->getHeader('Cache-Control')[0]['value']; $passCacheControlValue = $this->object->getHeader('X-Pass-Cache-Control')[0]['value']; $this->assertEquals($expectedValue, $cacheControlValue, 'Cache-Control header should match the expected value'); $this->assertEquals($passExpectedValue, $passCacheControlValue, 'X-Pass-Cache-Control header should match the expected value'); }
/** * dispatch the request * * @param WikiaApp $app * @param WikiaRequest $request * @throws WikiaException * @throws Exception * @throws WikiaHttpException * @throws WikiaDispatchedException * @return WikiaResponse */ public function dispatch(WikiaApp $app, WikiaRequest $request) { wfProfileIn(__METHOD__); global $wgAutoloadClasses; if (empty($wgAutoloadClasses)) { wfProfileOut(__METHOD__); throw new WikiaException("wgAutoloadClasses is empty, cannot dispatch Request"); } $format = $request->getVal('format', WikiaResponse::FORMAT_HTML); $response = new WikiaResponse($format, $request); $controller = null; $profilename = 'unset'; // Main dispatch is a loop because Controllers can forward to each other // Error condition is also handled via forwarding to the error controller do { // First time through the loop we skip this section // If we got through the dispatch loop and have a nextCall, then call it. // Request and Response are re-used, Response data can be optionally reset if ($controller && $controller->hasNext()) { $nextCall = $controller->getNext(); $request->setVal('controller', $nextCall['controller']); $request->setVal('method', $nextCall['method']); if ($nextCall['reset']) { $response->resetData(); } } $profilename = null; try { // Determine the "base" name for the controller, stripping off Controller/Service/Module $controllerName = $app->getBaseName($request->getVal('controller')); if (empty($controllerName)) { throw new WikiaException("Controller parameter missing or invalid: {$controllerName}"); } // Service classes must be dispatched by full name otherwise we look for a controller. if ($app->isService($request->getVal('controller'))) { $controllerClassName = $app->getServiceClassName($controllerName); } else { $controllerClassName = $app->getControllerClassName($controllerName); } if (empty($wgAutoloadClasses[$controllerClassName])) { throw new ControllerNotFoundException($controllerName); } // Determine the final name for the controller and method based on any routing rules $callNext = $this->applyRouting($app, $response, $controllerClassName, $request->getVal('method', self::DEFAULT_METHOD_NAME)); $controllerClassName = $response->getControllerName(); // might have been changed $controllerName = $app->getBaseName($controllerClassName); // chop off Service/Controller $method = $response->getMethodName(); // might have been changed $profilename = __METHOD__ . " ({$controllerClassName}_{$method})"; wfProfileIn($profilename); $controller = new $controllerClassName(); /* @var $controller WikiaController */ $response->setTemplateEngine($controllerClassName::DEFAULT_TEMPLATE_ENGINE); if ($callNext) { list($nextController, $nextMethod, $resetData) = explode("::", $callNext); $controller->forward($nextController, $nextMethod, $resetData); } // map X to executeX method names for things that used to be modules if (!method_exists($controller, $method)) { $method = ucfirst($method); $hookMethod = $method; // the original module hook naming scheme does not use the "Execute" part // This will throw an exception if the template is missing // Refactor the offending class to not use executeXYZ methods or set format in request params // Warning: this means you can't use the new Dispatcher routing to switch templates in modules if ($format == WikiaResponse::FORMAT_HTML) { try { $response->getView()->setTemplate($controllerName, $method); } catch (WikiaException $e) { throw new MethodNotFoundException("{$controllerClassName}::{$method}"); } } $method = "execute{$method}"; $params = $request->getParams(); // old modules expect params in a different place } else { $hookMethod = $method; $params = array(); } if (!$request->isInternal() && !$controller->allowsExternalRequests() || in_array($method, array('allowsExternalRequests', 'getRequest', 'setRequest', 'getResponse', 'setResponse', 'getApp', 'setApp', 'init')) || !method_exists($controller, $method) || !is_callable(array($controller, $method))) { throw new MethodNotFoundException("{$controllerClassName}::{$method}"); } if (!$request->isInternal()) { $this->testIfUserHasPermissionsOrThrow($app, $controller, $method); } // Initialize the RequestContext object if it is not already set // SpecialPageController context is already set by SpecialPageFactory::execute by the time it gets here if ($controller->getContext() === null) { $controller->setContext(RequestContext::getMain()); } // If a SpecialPageController is dispatching a request to itself, preserve the original request context // TODO: come up with a better fix for this (it's because of the setInstance call in WikiaSpecialPageController) $originalRequest = $controller->getRequest(); $originalResponse = $controller->getResponse(); $controller->setRequest($request); $controller->setResponse($response); $controller->setApp($app); $controller->init(); if (method_exists($controller, 'preventBlockedUsage') && $controller->preventBlockedUsage($controller->getContext()->getUser(), $method)) { $result = false; } elseif (method_exists($controller, 'userAllowedRequirementCheck') && $controller->userAllowedRequirementCheck($controller->getContext()->getUser(), $method)) { $result = false; } else { // Actually call the controller::method! $result = $controller->{$method}($params); } if ($result === false) { // skip template rendering when false returned $controller->skipRendering(); } // Preserve original request (this is for SpecialPageControllers) if ($originalRequest != null) { $controller->setRequest($originalRequest); } if ($originalResponse != null) { $controller->setResponse($originalResponse); } // keep the AfterExecute hooks for now, refactor later using "after" dispatching $app->runHook("{$controllerName}{$hookMethod}AfterExecute", array(&$controller, &$params)); wfProfileOut($profilename); } catch (WikiaHttpException $e) { if ($request->isInternal()) { //if it is internal call rethrow it so we can apply normal handling wfProfileOut(__METHOD__); throw $e; } else { wfProfileOut($profilename); $response->setException($e); $response->setFormat('json'); $response->setCode($e->getCode()); $response->setVal('error', get_class($e)); $details = $e->getDetails(); if (!empty($details)) { $response->setVal('message', $details); } } } catch (Exception $e) { if ($profilename) { wfProfileOut($profilename); } $response->setException($e); Wikia::log(__METHOD__, $e->getMessage()); // if we catch an exception, forward to the WikiaError controller unless we are already dispatching Error if (empty($controllerClassName) || $controllerClassName != 'WikiaErrorController') { $controller = new WikiaErrorController(); $controller->forward('WikiaError', 'error', false); // keep params for error controller $response->getView()->setTemplatePath(null); // response is re-used so skip the original template } } } while ($controller && $controller->hasNext()); if ($request->isInternal() && $response->hasException() && $request->getExceptionMode() !== WikiaRequest::EXCEPTION_MODE_RETURN) { Wikia::logBacktrace(__METHOD__ . '::exception'); wfProfileOut(__METHOD__); switch ($request->getExceptionMode()) { case WikiaRequest::EXCEPTION_MODE_THROW: throw $response->getException(); // case WikiaRequest::EXCEPTION_MODE_WRAP_AND_THROW: // case WikiaRequest::EXCEPTION_MODE_WRAP_AND_THROW: default: throw new WikiaDispatchedException("Internal Throw ({$response->getException()->getMessage()})", $response->getException()); } } wfProfileOut(__METHOD__); return $response; }
protected function renderInvalid() { $output = $this->response->getData(); $output += array('exception' => array('message' => "Invalid Format, defaulting to JSON", 'code' => WikiaResponse::RESPONSE_CODE_ERROR)); return json_encode($output); }
/** * After the forms is sent to the proper Email Controller, inspect the result. * If it's "ok", add a confirmation banner notification to indicate success. Otherwise * add an error banner notification and output the error from the Email Controller. * @param \WikiaResponse $result */ private function addBannerNotification($result) { $responseData = $result->getData(); if ($responseData['result'] == 'ok') { \BannerNotificationsController::addConfirmation("Successfully sent email!", \BannerNotificationsController::CONFIRMATION_CONFIRM); } else { \BannerNotificationsController::addConfirmation("Errors: " . $responseData['msg'], \BannerNotificationsController::CONFIRMATION_ERROR); } }
protected function assertSuccessfulEmail(WikiaResponse $resp = null) { if (empty($resp)) { throw new RequestException("Got empty response from the {$this->type} email controller"); } $data = $resp->getData(); if (empty($data['result']) || $data['result'] != 'ok') { throw new RequestException("Failed to send email:\n" . print_r($data, true)); } }
/** * @dataProvider testRenderingFormatsDataProvider */ public function testRenderingFormats($format, $responseValueName, $responseValueData, $expectedResult) { $response = new WikiaResponse($format); $response->setVal($responseValueName, $responseValueData); $this->object->setResponse($response); if ($format == WikiaResponse::FORMAT_HTML) { $this->mockAutoloadedController('Test'); $this->object->setTemplate('Test', 'formatHTML'); } $this->assertEquals($expectedResult, $this->object->render()); $this->unmockAutoloadedController('Test'); }