/**
     * Applying the method on the specific resource
     *
     * @param string                            $method   Http methods
     * @param Klarna_Checkout_ResourceInterface $resource Resource
     * @param array                             $options  Options
     *
     * @return void
     */
    public function apply(
        $method,
        Klarna_Checkout_ResourceInterface $resource,
        array $options = null
    ) {
        $this->applied = array(
            "method" => $method,
            "resource" => $resource,
            "options" => $options
        );

        if ($this->location !== null) {
            $resource->setLocation($this->location);
        }
    }
    /**
     * Test so 201 statuscode will update the location on the resource.
     *
     * @return void
     */
    public function testApplyPost201UpdatedLocation()
    {
        $curl = new Klarna_Checkout_HTTP_TransportStub;

        $payload = '{"flobadob":["bobcat","wookie"]}';
        $location = 'not localhost';

        $data = array(
            'code' => 201,
            'headers' => array('Location' => $location),
            'payload' => $payload
        );
        $curl->addResponse($data);

        $this->orderStub->parse(json_decode($payload, true));

        $expected = 'stnaeu\eu2341aoaaoae==';

        $this->digest->expects($this->once())
            ->method('create')
            ->with("{$payload}aboogie")
            ->will($this->returnValue($expected));

        $object = new Klarna_Checkout_BasicConnector(
            $curl,
            $this->digest,
            'aboogie'
        );

        $this->assertNull($this->orderStub->getLocation(), 'Original Location');

        $result = $object->apply('POST', $this->orderStub);

        $this->assertEquals($payload, $result->getData(), 'Response payload');
        $this->assertEquals(
            "Klarna {$expected}",
            $curl->request->getHeader('Authorization'),
            'Header'
        );

        $this->assertEquals(
            $location,
            $this->orderStub->getLocation(),
            'Location should have beet updated'
        );

        $this->assertEquals(
            json_decode($payload, true),
            $this->orderStub->marshal(),
            'The data on the resource should not be updated!'
        );

        $this->assertEquals(
            $this->orderStub->getContentType(),
            $curl->request->getHeader('Accept'),
            'Accept Content Type'
        );
    }
    /**
     * Test apply with a 200 code
     *
     * @return void
     */
    public function testApplyGet200()
    {
        $curl = new Klarna_Checkout_HTTP_TransportStub;

        $payload = '{"flobadob":["bobcat","wookie"]}';
        $data = array(
            'code' => 200,
            'headers' => array(),
            'payload' => $payload
        );
        $curl->addResponse($data);

        $expectedDigest = 'stnaeu\eu2341aoaaoae==';

        $this->digest->expects($this->once())
            ->method('create')
            ->with('aboogie')
            ->will($this->returnValue($expectedDigest));

        $object = new Klarna_Checkout_BasicConnector(
            $curl,
            $this->digest,
            'aboogie'
        );
        $result = $object->apply('GET', $this->orderStub);

        $this->assertEquals($payload, $result->getData(), 'Response payload');
        $this->assertEquals(
            "Klarna {$expectedDigest}",
            $curl->request->getHeader('Authorization'),
            'Header'
        );

        $this->assertEquals(
            json_decode($payload, true),
            $this->orderStub->marshal(),
            'Content'
        );

        $this->assertEquals(
            $this->orderStub->getContentType(),
            $curl->request->getHeader('Accept'),
            'Accept Content Type'
        );
    }
    /**
     * Act upon the status of a response
     *
     * @param Klarna_Checkout_HTTP_Response     $result   response from server
     * @param Klarna_Checkout_ResourceInterface $resource associated resource
     * @param array                             $visited  list of visited locations
     *
     * @return Klarna_Checkout_HTTP_Response
     */
    protected function handleResponse(
        Klarna_Checkout_HTTP_Response $result,
        Klarna_Checkout_ResourceInterface $resource,
        array $visited = array()
    ) {
        // Check if we got an Error status code back
        $this->verifyResponse($result);

        $url = $result->getHeader('Location');
        switch ($result->getStatus()) {
        case 301:
            // Update location and fallthrough
            $resource->setLocation($url);
        case 302:
            // Don't fallthrough for other than GET
            if ($result->getRequest()->getMethod() !== 'GET') {
                break;
            }
        case 303:
            // Detect eternal loops
            if (in_array($url, $visited)) {
                throw new Klarna_Checkout_ConnectorException(
                    'Infinite redirect loop detected.',
                    -1
                );
            }
            $visited[] = $url;
            // Follow redirect
            return $this->handle(
                'GET',
                $resource,
                array('url' => $url),
                $visited
            );
        case 201:
            // Update Location
            $resource->setLocation($url);
            break;
        case 200:
            // Update Data on resource
            $json = json_decode($result->getData(), true);
            if ($json === null) {
                throw new Klarna_Checkout_ConnectorException(
                    'Bad format on response content.',
                    -2
                );
            }
            $resource->parse($json);
        }

        return $result;
    }