Customers can now be created
This commit is contained in:
1 parent
27ddeeacb5
commit
0802d5cac2
5 files changed
+140
No files matched your search
@@ -3,6 +3,7 @@
|
|||||||
namespace Mattitja\BokioApiLaravel\Resources;
|
namespace Mattitja\BokioApiLaravel\Resources;
|
||||||
|
|
||||||
use Mattitja\BokioApiLaravel\BokioClient;
|
use Mattitja\BokioApiLaravel\BokioClient;
|
||||||
|
use Mattitja\BokioApiLaravel\Validation\CustomerValidator;
|
||||||
|
|
||||||
class Customer
|
class Customer
|
||||||
{
|
{
|
||||||
@@ -32,4 +33,11 @@ class Customer
|
|||||||
{
|
{
|
||||||
return $this->client->get('customers/'.$customerId);
|
return $this->client->get('customers/'.$customerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function create(array $data): object
|
||||||
|
{
|
||||||
|
$validated = CustomerValidator::validate($data);
|
||||||
|
|
||||||
|
return $this->client->post('customers', $validated);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Mattitja\BokioApiLaravel\Validation;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
|
class CustomerValidator
|
||||||
|
{
|
||||||
|
public static function validate(array $data): array
|
||||||
|
{
|
||||||
|
$validator = Validator::make($data, [
|
||||||
|
'name' => 'required|string',
|
||||||
|
'type' => 'required|string',
|
||||||
|
'vatNumber' => 'nullable|string',
|
||||||
|
'orgNumber' => 'nullable|string',
|
||||||
|
'paymentTerms' => 'nullable|string',
|
||||||
|
'language' => 'nullable|string|in:sv,en',
|
||||||
|
'contactsDetails' => 'nullable|array',
|
||||||
|
'contactsDetails.*.name' => 'required_with:contactsDetails|string',
|
||||||
|
'contactsDetails.*.email' => 'nullable|email',
|
||||||
|
'contactsDetails.*.phone' => 'nullable|string',
|
||||||
|
'contactsDetails.*.isDefault' => 'boolean',
|
||||||
|
'address' => 'required|array',
|
||||||
|
'address.line1' => 'required|string',
|
||||||
|
'address.line2' => 'nullable|string',
|
||||||
|
'address.city' => 'required|string',
|
||||||
|
'address.postalCode' => 'required|string',
|
||||||
|
'address.country' => 'required|string|size:2',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new ValidationException($validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $validator->validated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
use Mattitja\BokioApiLaravel\BokioClient;
|
use Mattitja\BokioApiLaravel\BokioClient;
|
||||||
use Mattitja\BokioApiLaravel\Resources\Customer;
|
use Mattitja\BokioApiLaravel\Resources\Customer;
|
||||||
|
use Mattitja\BokioApiLaravel\Validation\CustomerValidator;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
function loadFixture(string $path): array
|
function loadFixture(string $path): array
|
||||||
{
|
{
|
||||||
@@ -21,6 +23,10 @@ beforeEach(function () {
|
|||||||
return Http::response(loadFixture('Customer/all.200.json'), 200);
|
return Http::response(loadFixture('Customer/all.200.json'), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($request->method() === 'POST' && str_contains($request->url(), '/customers')) {
|
||||||
|
return Http::response(loadFixture('Customer/create.201.json'), 201);
|
||||||
|
}
|
||||||
|
|
||||||
// fallback
|
// fallback
|
||||||
return Http::response([], 404);
|
return Http::response([], 404);
|
||||||
});
|
});
|
||||||
@@ -42,3 +48,40 @@ it('can fetch a single customer from Bokio', function () {
|
|||||||
expect($response->id)->toBe($customerId);
|
expect($response->id)->toBe($customerId);
|
||||||
expect($response->name)->toBe('customer 1');
|
expect($response->name)->toBe('customer 1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can create a customer via Bokio API', function () {
|
||||||
|
$data = [
|
||||||
|
'name' => 'Testbolaget AB',
|
||||||
|
'type' => 'company',
|
||||||
|
'vatNumber' => 'SE1234567890',
|
||||||
|
'orgNumber' => '556677-8899',
|
||||||
|
'paymentTerms' => '30',
|
||||||
|
'language' => 'sv',
|
||||||
|
'contactsDetails' => [
|
||||||
|
[
|
||||||
|
'name' => 'John Doe',
|
||||||
|
'email' => 'john@example.com',
|
||||||
|
'phone' => '0123456789',
|
||||||
|
'isDefault' => true,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'address' => [
|
||||||
|
'line1' => 'Testgatan 1',
|
||||||
|
'line2' => null,
|
||||||
|
'city' => 'Göteborg',
|
||||||
|
'postalCode' => '12345',
|
||||||
|
'country' => 'SE',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$response = (new Customer($this->client))->create($data);
|
||||||
|
|
||||||
|
expect($response->id)->toBe('generated-id');
|
||||||
|
expect($response->name)->toBe('Testbolaget AB');
|
||||||
|
|
||||||
|
Http::assertSent(function ($request) use ($data) {
|
||||||
|
return $request->method() === 'POST' &&
|
||||||
|
str_contains($request->url(), '/customers') &&
|
||||||
|
$request['name'] === $data['name'];
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Mattitja\BokioApiLaravel\Validation\CustomerValidator;
|
||||||
|
|
||||||
|
it('validates minimal required customer data', function () {
|
||||||
|
$data = [
|
||||||
|
'name' => 'Test AB',
|
||||||
|
'type' => 'company',
|
||||||
|
'address' => [
|
||||||
|
'line1' => 'Gata 1',
|
||||||
|
'city' => 'Ort',
|
||||||
|
'postalCode' => '12345',
|
||||||
|
'country' => 'SE',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$validated = CustomerValidator::validate($data);
|
||||||
|
|
||||||
|
expect($validated['name'])->toBe('Test AB');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws exception when required fields are missing', function () {
|
||||||
|
$this->expectException(ValidationException::class);
|
||||||
|
|
||||||
|
CustomerValidator::validate([]);
|
||||||
|
});
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"id": "generated-id",
|
||||||
|
"name": "Testbolaget AB",
|
||||||
|
"type": "company",
|
||||||
|
"vatNumber": "SE1234567890",
|
||||||
|
"orgNumber": "556677-8899",
|
||||||
|
"paymentTerms": "30",
|
||||||
|
"language": "sv",
|
||||||
|
"contactsDetails": [
|
||||||
|
{
|
||||||
|
"name": "John Doe",
|
||||||
|
"email": "john@example.com",
|
||||||
|
"phone": "0123456789",
|
||||||
|
"isDefault": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"address": {
|
||||||
|
"line1": "Testgatan 1",
|
||||||
|
"line2": null,
|
||||||
|
"city": "Göteborg",
|
||||||
|
"postalCode": "12345",
|
||||||
|
"country": "SE"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user