<?php
/**
 * Wiaas_Delivery_Process_Test
 *
 * @package Wiaas
 */

class Wiaas_Delivery_Process_Test extends Wiaas_Unit_Test_Case {

	var $process_form, $step_form, $process_form_instance, $process_step, $process_form_workflow_api;

	function setUp() {
		parent::setUp();

		$this->process_form = GFFormsModel::search_forms(
			'DELIVERY PROCESS: Normal Delivery',
			true)[0];

		$this->step_form = GFFormsModel::search_forms(
			'DELIVERY ACTION TYPE: Manual',
			true)[0];

		$process_form_instance_id = GFAPI::add_entry(array(
			'form_id' => $this->process_form->id,
		));

		$this->process_form_instance = GFAPI::get_entry($process_form_instance_id);

		$this->process_form_workflow_api = new Gravity_Flow_API( $this->process_form->id );
	}

	/**
	 * @covers Wiaas_Delivery_Process::create_delivery_process_for_order
	 */
	function test_delivery_process_for_order_created() {
		$order = wc_create_order();
		$order_id = $order->get_id();

		Wiaas_Delivery_Process::create_delivery_process_for_order($order_id);

		$order_process_id = absint(get_post_meta($order_id, 'wiaas_delivery_process_id'));
		$order_process_instance_id = absint(get_post_meta($order_id, 'wiaas_delivery_process_entry_id'));

		# check field populated
		$this->assertGreaterThan(0, $order_process_id);
		$this->assertGreaterThan(0, $order_process_instance_id);
	}

	/**
	 * @covers Wiaas_Delivery_Process::extend_gravity_form_entry_meta
	 */
	function test_gravity_form_entry_meta_extended() {
		# create test entry with additional metadata
		$entry = array(
			'form_id' => $this->step_form->id,
			'wiaas_delivery_process_id' => false,
		);

		$result = GFAPI::add_entry($entry);

		# test that entry was successfully created
		$this->assertFalse(is_wp_error($result));
	}

	/**
	 * @covers Wiaas_Delivery_Process::maybe_complete_parent_process_step
	 */
	function test_do_nothing_if_completed_workflow_has_no_parent() {
		# Test there is no exception if entry has no parent process
		$entry_id = GFAPI::add_entry(array(
			'form_id' => $this->step_form->id
		));

		$this->assertFalse(
			Wiaas_Delivery_Process::maybe_complete_parent_process_step(
				$entry_id,
				$this->step_form)
		);
	}

	/**
	 * @covers Wiaas_Delivery_Process::maybe_complete_parent_process_step
	 */
	function test_process_parent_process_step_on_workflow_completion() {
		# get process current step
		$process_form_instance = GFAPI::get_entry($this->process_form_instance['id']);

		# retrieve process steps
		$process_steps = $this->process_form_workflow_api->get_steps($this->process_form);
		$first_process_step = $process_steps[0];
		$second_process_step = $process_steps[1];

		# Check that current step is first step of corresponding process
		$process_instance_current_step = $this->process_form_workflow_api->get_current_step($process_form_instance);
		$this->assertEquals(
			$process_instance_current_step->get_id(),
			$first_process_step->get_id());

		# Update step form entry to complete its workflow
		$step_form_entry = $process_instance_current_step->get_target_form_entry();
		gform_update_meta($step_form_entry['id'], 'workflow_role_administrator', 'approved');

		# execute callback
		Wiaas_Delivery_Process::maybe_complete_parent_process_step($step_form_entry['id'], null);

		# refresh process instance and check we moved to next step
		$process_form_instance = GFAPI::get_entry($this->process_form_instance['id']);
		$this->assertEquals(
			$this->process_form_workflow_api->get_current_step($process_form_instance)->get_id(),
			$second_process_step->get_id());
	}



	/**
	 * @covers Wiaas_Delivery_Process::get_order_delivery_process()
	 */
	function test_get_order_delivery_process() {

		$order = wc_create_order();
		$order_id = $order->get_id();

		$delivery_process = Wiaas_Delivery_Process::get_order_delivery_process($order_id);

		$this->assertNotNull($delivery_process);

		$steps = $delivery_process['steps'];

		$this->assertNotNull($steps);
		$this->assertTrue(is_array($steps));

		foreach ($steps as $step) {

			# test returned step is array
			$this->assertTrue(is_array($step));

			# test returned step properties
			$this->assertArrayHasKey('step_id', $step);
			$this->assertArrayHasKey('step_form_entry_id', $step);
			$this->assertArrayHasKey('short_desc', $step);
			$this->assertArrayHasKey('full_desc', $step);
			$this->assertArrayHasKey('action_code', $step);
			$this->assertArrayHasKey('step_type', $step);
			$this->assertArrayHasKey('status', $step);
			$this->assertArrayHasKey('order_id', $step);

			$this->assertEquals($step['order_id'], $order_id);

			# test that started steps have valid form entry
			if ($step['status'] !== 'inactive') {
				$process_instance = GFAPI::get_entry($step['step_form_entry_id']);
				$this->assertFalse(is_wp_error($process_instance));
			}
		}
	}
}