<?php
App::uses('BemmelhorTestCase', 'TestSuite');
App::uses('UsersController', 'Controller');
App::uses('NodesController', 'Controller');

class TestUsersEventController extends UsersController {
}

class TestNodesEventController extends NodesController {
}

class BemmelhorEventsTest extends BemmelhorTestCase {

	public $fixtures = array(
		'app.setting',
		);

	public function setUp() {
		parent::setUp();
		BemmelhorPlugin::unload('Example');
		BemmelhorPlugin::load('Shops');
		BemmelhorEventManager::loadListeners();
		$request = $this->getMock('CakeRequest');
		$response = $this->getMock('CakeResponse');
		$this->Users = new TestUsersEventController($request, $response);
		$this->Nodes = new TestNodesEventController($request, $response);
	}

/**
 * tearDown
 *
 * @return void
 */
	public function tearDown() {
		parent::tearDown();
		BemmelhorPlugin::unload('Shops');
	}

/**
 * Indirectly test BemmelhorEventManager::detachPluginSubscribers()
 * triggerred by calling BemmelhorPlugin::unload(null)
 */
	public function testDetachPluginSubscribers() {
		$eventManager = BemmelhorEventManager::instance();
		$loaded = CakePlugin::loaded('Shops');
		$this->assertNotEmpty($loaded);

		$eventName = 'Controller.Users.activationFailure';
		$event = Bemmelhor::dispatchEvent($eventName, $this->Users);
		$this->assertTrue($event->result, sprintf('Event: %s', $eventName));

		BemmelhorPlugin::unload('Shops');

		$eventName = 'Controller.Users.activationFailure';
		$event = Bemmelhor::dispatchEvent($eventName, $this->Users);
		$this->assertNull($event->result, sprintf('Event: %s', $eventName));
	}

/**
 * testDispatchUsersEvents
 */
	public function testDispatchUsersEvents() {
		$eventNames = array(
			'Controller.Users.activationFailure',
			'Controller.Users.activationSuccessful',
			'Controller.Users.beforeAdminLogin',
			'Controller.Users.adminLoginFailure',
			'Controller.Users.adminLoginSuccessful',
			'Controller.Users.adminLogoutSuccessful',
			'Controller.Users.afterLogout',
			'Controller.Users.beforeLogin',
			'Controller.Users.beforeLogout',
			'Controller.Users.loginFailure',
			'Controller.Users.loginSuccessful',
			'Controller.Users.registrationFailure',
			'Controller.Users.registrationSuccessful',
		);
		$Auth = $this->getMock('AuthComponent', array(), array($this->Users->Components));
		$Auth->authenticate = array(
			'all' => array(
				'userModel' => 'User',
				'fields' => array('username' => 'username', 'password' => 'password'),
			),
		);
		$this->Users->Auth = $Auth;
		foreach ($eventNames as $name) {
			$event = Bemmelhor::dispatchEvent($name, $this->Users);
			$this->assertTrue($event->result, sprintf('Event: %s', $name));
			$this->assertInstanceOf('UsersController', $event->subject());
		}
	}

/**
 * testDispatchNodesEvents
 */
	public function testDispatchNodesEvents() {
		$eventNames = array(
			'Controller.Nodes.afterAdd',
			'Controller.Nodes.afterDelete',
			'Controller.Nodes.afterEdit',
			'Controller.Nodes.afterPromote',
			'Controller.Nodes.afterPublish',
			'Controller.Nodes.afterUnpromote',
			'Controller.Nodes.afterUnpublish',
			);
		foreach ($eventNames as $name) {
			$event = Bemmelhor::dispatchEvent($name, $this->Nodes);
			$this->assertTrue($event->result, sprintf('Event: %s', $name));
			$this->assertInstanceOf('NodesController', $event->subject());
		}
	}

/**
 * testDispatchHelperEvents
 */
	public function testDispatchHelperEvents() {
		$eventNames = array(
			'Helper.Layout.afterFilter',
			'Helper.Layout.beforeFilter',
			);
		App::uses('View', 'View');
		$View = new View();
		foreach ($eventNames as $name) {
			$event = Bemmelhor::dispatchEvent($name, $View);
			$this->assertTrue($event->result, sprintf('Event: %s', $name));
			$this->assertInstanceOf('View', $event->subject());
		}
	}

}
