Skip to content

Commit

Permalink
Added export features, updated accessors to match requirements.
Browse files Browse the repository at this point in the history
  • Loading branch information
elb98rm committed Oct 6, 2020
1 parent 2299f46 commit 2f907f3
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 5 deletions.
57 changes: 55 additions & 2 deletions src/Models/JsonApiFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function setData(?array $data = null): JsonApiFormatter
public function addData(array $extra_data): JsonApiFormatter
{
// catch duplicates
if (array_intersect_key($this->getData(), $extra_data)) {
if (array_intersect_key($this->getData() ?? [], $extra_data)) {
throw new JsonApiFormatterException(
'The data provided clashes with existing data - it should be added manually'
);
Expand All @@ -121,6 +121,16 @@ public function addData(array $extra_data): JsonApiFormatter
return $this;
}

/**
* Fluently unset $base_response_array['data']
* @return JsonApiFormatter
*/
public function unsetData(): JsonApiFormatter
{
unset($this->base_response_array['data']);
return $this;
}

/**
* @return null|array
*/
Expand Down Expand Up @@ -157,6 +167,16 @@ public function addErrors(array $extra_errors): JsonApiFormatter
return $this;
}

/**
* Fluently unset $base_response_array['errors']
* @return JsonApiFormatter
*/
public function unsetErrors(): JsonApiFormatter
{
unset($this->base_response_array['errors']);
return $this;
}

/**
* @return null|array
*/
Expand Down Expand Up @@ -329,7 +349,40 @@ private function correctEncode(?array $array = null): string
return json_encode($content, true);
}

// Main functionality
/**
* internally validates the current object
*
* @return JsonApiFormatter
* @throws JsonApiFormatterException
*/
private function validateObject(): JsonApiFormatter
{
if(is_array($this->getData()) && is_array($this->getErrors())) {
throw new JsonApiFormatterException('Both data and errors properties are set');
}

return $this;
}

// Main functionality:

/**
* Attempts to export the current contents in a valid JSON string.
* This will validate the data but will not set it up correctly for you.
*
* You probably actually want to use the other functions:
* @see errorResponse
* @see dataResourceResponse
*
* @return string
* @throws JsonApiFormatterException
*/
public function export(): string
{
$this->validateObject();

return $this->correctEncode();
}

/**
* Attempts to import/decode a json api compliant string into a JsonApiFormatter object,
Expand Down
149 changes: 146 additions & 3 deletions tests/Unit/JsonApiFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,18 @@ public function testDataAccessors()
$json_api_formatter->addData(['attributes' => 'some_data']);
$this->assertEquals($json_api_formatter->getData(), $test_complete_data);

// unset
$reflection = self::getMethod('getBaseResponseArray');
$test_object = new JsonApiFormatter();
$test_object->unsetData();
$response = $reflection->invokeArgs($test_object, []);
$this->assertFalse(isset($response['data']));

// check that addData catches duplicates
$this->expectException(JsonApiFormatterException::class);
$this->expectExceptionMessage('The data provided clashes with existing data - it should be added manually');
$json_api_formatter->addData(['attributes' => 'some_data']);

}

/**
Expand Down Expand Up @@ -126,6 +134,13 @@ public function testErrorsAccessors()
// extend
$json_api_formatter->addErrors([$error2]);
$this->assertEquals($json_api_formatter->getErrors(), $test_complete_errors);

// unset
$reflection = self::getMethod('getBaseResponseArray');
$test_object = new JsonApiFormatter();
$test_object->unsetErrors();
$response = $reflection->invokeArgs($test_object, []);
$this->assertFalse(isset($response['errors']));
}

/**
Expand Down Expand Up @@ -284,8 +299,11 @@ public function testConstructor()
$this->assertEquals($json_api_formatter->getLinks(), $links);
}

// Internal/reflection testing
// Internal method/reflection testing

/**
* Tests that encode correctly encodes an array
*/
public function testCorrectEncode()
{
$base_response_array = [
Expand All @@ -297,8 +315,7 @@ public function testCorrectEncode()
'jsonapi' => (object)['version' => '1.0']
];
$test_response_array = [
'data' => null,
'errors' => [],
'data' => [],
'meta' => [
'status' => 'changed'
],
Expand All @@ -315,6 +332,50 @@ public function testCorrectEncode()
// modified call
$response = $reflection->invokeArgs($test_object, ['array' => $test_response_array]);
$this->assertSame($response, json_encode($test_response_array, true));

//
}

/**
* Test that validation errors if you include data and errors together
*/
public function testValidationDataAndErrors()
{
$reflection = self::getMethod('validateObject');
$test_object = new JsonApiFormatter();

$test_object->setData([]);
$test_object->setErrors([]);

// basic call
$this->expectException(JsonApiFormatterException::class);
$this->expectExceptionMessage('Both data and errors properties are set');
$reflection->invokeArgs($test_object, []);
}

/**
* Tests validation with good packets
*/
public function testValidationData()
{
$reflection = self::getMethod('validateObject');
$test_object = new JsonApiFormatter();

// null data check
$test_object->setData(null);
$test_object->setErrors([]);

$response = $reflection->invokeArgs($test_object, []);
$this->assertTrue($response instanceof JsonApiFormatter);

// null errors check
$test_object->setData([]);
$test_object->unsetErrors();

// null errors check
$response = $reflection->invokeArgs($test_object, []);
$this->assertTrue($response instanceof JsonApiFormatter);

}

// Main functionality
Expand Down Expand Up @@ -473,6 +534,88 @@ public function testDataResourceResponse()
$this->assertEquals($validated_json, $response);
}

/**
* Tests that invalid JSON is caught
*/
public function testExportException()
{
$not_json = 'Not json';
$json_api_formatter = new JsonApiFormatter();
$json_api_formatter->setData([]);

$this->expectException(JsonApiFormatterException::class);
$this->expectExceptionMessage('The provided json was not valid');
$json_api_formatter->import($not_json);
}

/**
* Tests the export function
*/
public function testExport()
{
$data = [
'id' => '0',
'type' => 'data',
'attributes' => 'some_data'
];

$error = [
'status' => '400',
'title' => 'Bad request',
'detail' => 'The request was not formed well'
];

// errors
$json_api_formatter = new JsonApiFormatter();
$json_api_formatter->unsetData();
$json_api_formatter->addErrors([$error]);

$error_response_array = [
'errors' => [$error],
'meta' => [
'status' => null
],
'jsonapi' => (object)['version' => '1.0']
];

$this->assertSame($json_api_formatter->export(), json_encode($error_response_array, true));

// data
$json_api_formatter = new JsonApiFormatter();
$json_api_formatter->unsetErrors();
$json_api_formatter->addData($data);

$error_response_array = [
'data' => $data,
'meta' => [
'status' => null
],
'jsonapi' => (object)['version' => '1.0']
];

$this->assertSame($json_api_formatter->export(), json_encode($error_response_array, true));

// meta

$meta = [
'status' => '200',
'info' => 'Request loaded in 34ms'
];

$json_api_formatter = new JsonApiFormatter();
$json_api_formatter->unsetErrors();
$json_api_formatter->addData($data);
$json_api_formatter->setMeta($meta);

$error_response_array = [
'data' => $data,
'meta' => $meta,
'jsonapi' => (object)['version' => '1.0']
];

$this->assertSame($json_api_formatter->export(), json_encode($error_response_array, true));
}

/**
* Tests that invalid JSON is caught
*/
Expand Down

0 comments on commit 2f907f3

Please sign in to comment.