refactor: replace custom CRM with Monica fork
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s

This commit is contained in:
Kroonk
2026-05-22 16:19:55 +02:00
parent 38cc4c09ca
commit a213a1dba0
2215 changed files with 242567 additions and 6015 deletions

View File

@@ -0,0 +1,340 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Account\Account;
use App\Models\Contact\Address;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiAdressesControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonAddress = [
'id',
'object',
'name',
'street',
'city',
'province',
'postal_code',
'latitude',
'longitude',
'country',
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
/** @test */
public function it_gets_a_list_of_addresses()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/addresses');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => ['*' => $this->jsonAddress],
]);
$response->assertJsonFragment([
'object' => 'address',
'id' => $address->id,
]);
$response->assertJsonFragment([
'total' => 1,
'current_page' => 1,
]);
}
/** @test */
public function it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
factory(Address::class, 20)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/addresses?limit=1');
$response->assertStatus(200);
$response->assertJsonFragment([
'total' => 20,
'current_page' => 1,
'per_page' => 1,
'last_page' => 20,
]);
$response = $this->json('GET', '/api/addresses?limit=2');
$response->assertStatus(200);
$response->assertJsonFragment([
'total' => 20,
'current_page' => 1,
'per_page' => 2,
'last_page' => 10,
]);
}
/** @test */
public function it_gets_addresses_for_a_specific_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/contacts/'.$contact->id.'/addresses');
$response->assertStatus(200);
$response->assertJsonFragment([
'object' => 'address',
'id' => $address->id,
'name' => $address->name,
]);
}
/** @test */
public function calling_addresses_gets_an_error_if_contact_doesnt_exist()
{
$user = $this->signin();
$response = $this->json('GET', '/api/contacts/0/addresses');
$this->expectNotFound($response);
}
/** @test */
public function it_gets_a_specific_address()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/addresses/'.$address->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonAddress,
]);
$response->assertJsonFragment([
'object' => 'address',
'id' => $address->id,
'name' => $address->name,
'street' => $address->place->street,
]);
}
/** @test */
public function it_creates_an_address()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$response = $this->json('POST', '/api/addresses', [
'contact_id' => $contact->id,
'name' => 'address name',
'street' => 'street',
'postal_code' => '12345',
'country' => 'FR',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('addresses', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'name' => 'address name',
]);
$response->assertJsonFragment([
'object' => 'address',
'name' => 'address name',
'country' => [
'object' => 'country',
'id' => 'FR',
'name' => 'France',
'iso' => 'FR',
],
'street' => 'street',
'postal_code' => '12345',
]);
$addressId = $response->json('data.id');
$this->assertGreaterThan(0, $addressId);
}
/** @test */
public function create_addresses_gets_an_error_if_fields_are_missing()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$response = $this->json('POST', '/api/addresses', [
]);
$this->expectDataError($response, [
'The contact id field is required.',
]);
}
/** @test */
public function create_addresses_gets_an_error_if_contact_is_not_linked_to_user()
{
$user = $this->signin();
$account = factory(Account::class)->create();
$contact = factory(Contact::class)->create([
'account_id' => $account->id,
]);
$response = $this->json('POST', '/api/addresses', [
'contact_id' => $contact->id,
'name' => 'address name',
'street' => 'street',
'postal_code' => '12345',
'country' => 'FR',
]);
$this->expectNotFound($response);
}
/** @test */
public function it_updates_an_address()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'name' => 'address name',
]);
$response = $this->json('PUT', '/api/addresses/'.$address->id, [
'contact_id' => $contact->id,
'name' => 'address name up',
'country' => 'US',
]);
$response->assertStatus(200);
$response->assertJsonFragment([
'object' => 'address',
'id' => $address->id,
'name' => 'address name up',
'country' => [
'object' => 'country',
'id' => 'US',
'name' => 'United States',
'iso' => 'US',
],
'postal_code' => $address->place->postal_code,
]);
$this->assertDatabaseHas('addresses', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'place_id' => $address->place->id,
'id' => $address->id,
'name' => 'address name up',
]);
}
/** @test */
public function updating_address_generates_an_error()
{
$user = $this->signin();
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/addresses/'.$address->id, []);
$this->expectDataError($response, [
'The contact id field is required.',
]);
}
/** @test */
public function it_cant_update_an_address_if_account_is_not_linked_to_address()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/addresses/'.$address->id, [
'contact_id' => $contact->id,
]);
$this->expectNotFound($response);
}
/** @test */
public function it_deletes_an_address()
{
$user = $this->signin();
$contact = factory(Contact::class)->create(['account_id' => $user->account_id]);
$address = factory(Address::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('DELETE', '/api/addresses/'.$address->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'id' => $address->id,
'deleted' => true,
]);
$this->assertDatabaseMissing('addresses', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'id' => $address->id,
]);
}
/** @test */
public function address_delete_error()
{
$user = $this->signin();
$response = $this->json('DELETE', '/api/addresses/0');
$this->expectDataError($response, [
'The selected address id is invalid.',
]);
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Contact\Contact;
use App\Models\Instance\AuditLog;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiAuditLogControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonStructureAuditLog = [
'id',
'object',
'author' => [
'name',
],
'action',
'objects',
'audited_at',
'created_at',
'updated_at',
];
/** @test */
public function it_gets_a_list_of_audit_logs()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
'first_name' => 'roger',
]);
factory(AuditLog::class, 10)->create([
'account_id' => $user->account_id,
'about_contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/contacts/'.$contact->id.'/logs');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => ['*' => $this->jsonStructureAuditLog],
]);
$this->assertCount(
10,
$response->decodeResponseJson()['data']
);
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
]);
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Contact\Contact;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiAvatarControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonDatas = [
'id',
'object',
'account' => [
'id',
],
'information' => [
'avatar' => [
'url',
'source',
'default_avatar_color',
],
],
'created_at',
'updated_at',
];
/** @test */
public function it_updates_the_photo_avatar()
{
Storage::fake();
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/photos', [
'contact_id' => $contact->id,
'photo' => UploadedFile::fake()->image('test.jpg'),
]);
$response->assertStatus(201);
$this->assertDatabaseHas('photos', [
'account_id' => $user->account_id,
'original_filename' => 'test.jpg',
]);
$photo = $contact->photos->first();
Storage::disk('public')->assertExists($photo->new_filename);
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'photo' => UploadedFile::fake()->image('test.jpg'),
'source' => 'photo',
'photo_id' => $photo->id,
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDatas,
]);
$this->assertDatabaseHas('contacts', [
'id' => $contact->id,
'avatar_source' => 'photo',
'avatar_photo_id' => $photo->id,
]);
}
/** @test */
public function it_updates_the_gravatar_avatar()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
'avatar_gravatar_url' => 'a gravatar url',
]);
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'source' => 'gravatar',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDatas,
]);
$this->assertDatabaseHas('contacts', [
'id' => $contact->id,
'avatar_source' => 'gravatar',
]);
}
/** @test */
public function it_updates_the_adorable_avatar()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'source' => 'adorable',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDatas,
]);
$this->assertDatabaseHas('contacts', [
'id' => $contact->id,
'avatar_source' => 'adorable',
]);
}
/** @test */
public function it_updates_the_default_avatar()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'source' => 'default',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDatas,
]);
$this->assertDatabaseHas('contacts', [
'id' => $contact->id,
'avatar_source' => 'default',
]);
}
/** @test */
public function avatar_update_gets_an_error_if_fields_are_missing()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'source' => 'blabla',
]);
$this->expectDataError($response, [
'The selected source is invalid.',
]);
}
/** @test */
public function avatar_update_gets_an_error_if_contact_is_not_linked_to_user()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$response = $this->json('PUT', '/api/contacts/'.$contact->id.'/avatar', [
'source' => 'default',
]);
$this->expectNotFound($response);
}
}

View File

@@ -0,0 +1,352 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Contact\Call;
use App\Models\Account\Account;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiCallControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonCall = [
'id',
'object',
'called_at',
'content',
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
/** @test */
public function it_gets_a_list_of_calls()
{
$user = $this->signin();
$contact1 = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call1 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact1->id,
]);
$contact2 = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call2 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact2->id,
]);
$response = $this->json('GET', '/api/calls');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => ['*' => $this->jsonCall],
]);
$response->assertJsonFragment([
'object' => 'call',
'id' => $call1->id,
]);
$response->assertJsonFragment([
'object' => 'call',
'id' => $call2->id,
]);
}
/** @test */
public function it_gets_the_calls_of_a_contact()
{
$user = $this->signin();
$contact1 = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call1 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact1->id,
]);
$contact2 = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call2 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact2->id,
]);
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/calls');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => ['*' => $this->jsonCall],
]);
$response->assertJsonFragment([
'object' => 'call',
'id' => $call1->id,
]);
$response->assertJsonMissingExact([
'object' => 'call',
'id' => $call2->id,
]);
}
/** @test */
public function calling_calls_get_error()
{
$user = $this->signin();
$response = $this->json('GET', '/api/contacts/0/calls');
$this->expectNotFound($response);
}
/** @test */
public function it_gets_one_call()
{
$user = $this->signin();
$contact1 = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call1 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact1->id,
]);
$call2 = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact1->id,
]);
$response = $this->json('GET', '/api/calls/'.$call1->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonCall,
]);
$response->assertJsonFragment([
'object' => 'call',
'id' => $call1->id,
]);
$response->assertJsonMissingExact([
'object' => 'call',
'id' => $call2->id,
]);
}
/** @test */
public function calling_one_call_gets_an_error()
{
$user = $this->signin();
$response = $this->json('GET', '/api/calls/0');
$this->expectNotFound($response);
}
/** @test */
public function it_creates_a_call()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/calls', [
'contact_id' => $contact->id,
'content' => 'the call',
'called_at' => '2018-05-01',
]);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonCall,
]);
$callId = $response->json('data.id');
$response->assertJsonFragment([
'object' => 'call',
'id' => $callId,
]);
$this->assertGreaterThan(0, $callId);
$this->assertDatabaseHas('calls', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'id' => $callId,
'content' => 'the call',
'called_at' => '2018-05-01',
]);
}
/** @test */
public function create_calls_gets_an_error_if_fields_are_missing()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/calls', [
'contact_id' => $contact->id,
]);
$this->expectDataError($response, [
'The called at field is required.',
]);
}
/** @test */
public function it_cant_create_a_call_if_account_is_wrong()
{
$user = $this->signin();
$account = factory(Account::class)->create();
$contact = factory(Contact::class)->create([
'account_id' => $account->id,
]);
$response = $this->json('POST', '/api/calls', [
'contact_id' => $contact->id,
'content' => 'the call',
'called_at' => '2018-05-01',
]);
$this->expectNotFound($response);
}
/** @test */
public function it_updates_a_call()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('PUT', '/api/calls/'.$call->id, [
'contact_id' => $contact->id,
'content' => 'the call',
'called_at' => '2018-05-01',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonCall,
]);
$callId = $response->json('data.id');
$this->assertEquals($call->id, $callId);
$response->assertJsonFragment([
'object' => 'call',
'id' => $callId,
]);
$this->assertGreaterThan(0, $callId);
$this->assertDatabaseHas('calls', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'id' => $callId,
'content' => 'the call',
'called_at' => '2018-05-01',
]);
}
/** @test */
public function updating_call_generates_an_error()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('PUT', '/api/calls/'.$call->id, [
'contact_id' => $call->contact_id,
]);
$this->expectDataError($response, [
'The called at field is required.',
]);
}
/** @test */
public function it_cant_update_a_call_if_account_is_not_linked_to_call()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([]);
$call = factory(Call::class)->create([
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('PUT', '/api/calls/'.$call->id, [
'content' => 'the call',
'called_at' => '2018-05-01',
]);
$this->expectNotFound($response);
}
/** @test */
public function it_deletes_a_call()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$call = factory(Call::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
$this->assertDatabaseHas('calls', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'id' => $call->id,
]);
$response = $this->json('DELETE', '/api/calls/'.$call->id);
$response->assertStatus(200);
$this->assertDatabaseMissing('calls', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'id' => $call->id,
]);
}
/** @test */
public function it_cant_delete_a_call_if_call_doesnt_exist()
{
$user = $this->signin();
$response = $this->json('DELETE', '/api/calls/0');
$this->expectNotFound($response);
}
/** @test */
public function it_cant_delete_a_call_if_account_is_not_linked()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([]);
$call = factory(Call::class)->create([
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('DELETE', '/api/calls/'.$call->id);
$this->expectNotFound($response);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,289 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Contact\Tag;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiContactTagControllerTest extends ApiTestCase
{
use DatabaseTransactions;
/** @test */
public function tags_are_required_to_associate_tags_to_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/setTags");
$this->expectDataError($response, ['The tags field is required.']);
}
/** @test */
public function it_associates_tags_to_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/setTags", [
'tags' => ['very-specific-tag-name', 'very-specific-tag-name-2'],
]);
$response->assertStatus(200);
$tagId1 = $response->json('data.tags.0.id');
$tagId2 = $response->json('data.tags.1.id');
$response->assertJsonFragment([
'object' => 'tag',
'id' => $tagId1,
'name' => 'very-specific-tag-name',
]);
$response->assertJsonFragment([
'object' => 'tag',
'id' => $tagId2,
'name' => 'very-specific-tag-name-2',
]);
$this->assertDatabaseHas('contact_tag', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'tag_id' => $tagId1,
]);
$this->assertDatabaseHas('contact_tag', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'tag_id' => $tagId2,
]);
}
/** @test */
public function tags_ignore_empty_tags()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/setTags", [
'tags' => [
'very-specific-tag-name',
null,
'very-specific-tag-name-2',
],
]);
$response->assertStatus(200);
$tagId1 = $response->json('data.tags.0.id');
$tagId2 = $response->json('data.tags.1.id');
$response->assertJsonFragment([
'object' => 'tag',
'id' => $tagId1,
'name' => 'very-specific-tag-name',
]);
$response->assertJsonFragment([
'object' => 'tag',
'id' => $tagId2,
'name' => 'very-specific-tag-name-2',
]);
$this->assertDatabaseHas('contact_tag', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'tag_id' => $tagId1,
]);
$this->assertDatabaseHas('contact_tag', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'tag_id' => $tagId2,
]);
}
/** @test */
public function a_list_of_tags_are_required_to_remove_a_tag_from_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/unsetTag");
$this->expectDataError($response, ['The tags field is required.']);
}
/** @test */
public function it_removes_one_tag_from_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$tag = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'friend',
]);
$tag2 = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'family',
]);
$contact->tags()->syncWithoutDetaching([
$tag->id => [
'account_id' => $contact->account_id,
],
$tag2->id => [
'account_id' => $contact->account_id,
],
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/unsetTag", [
'tags' => [$tag->id],
]);
$response->assertStatus(200);
$response->assertJsonFragment([
'id' => $contact->id,
'name' => $tag2->name,
]);
$response->assertJsonMissing([
'name' => $tag->name,
]);
$this->assertDatabaseHas('contact_tag', [
'contact_id' => $contact->id,
'tag_id' => $tag2->id,
'account_id' => $user->account_id,
]);
$this->assertDatabaseMissing('contact_tag', [
'contact_id' => $contact->id,
'tag_id' => $tag->id,
'account_id' => $user->account_id,
]);
}
/** @test */
public function it_removes_multiple_tags_from_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$tag = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'friend',
]);
$tag2 = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'family',
]);
$tag3 = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'work',
]);
$contact->tags()->syncWithoutDetaching([
$tag->id => [
'account_id' => $contact->account_id,
],
$tag2->id => [
'account_id' => $contact->account_id,
],
$tag3->id => [
'account_id' => $contact->account_id,
],
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/unsetTag", [
'tags' => [$tag->id, $tag2->id],
]);
$response->assertStatus(200);
$response->assertJsonFragment([
'id' => $contact->id,
'name' => $tag3->name,
]);
$response->assertJsonMissing([
'name' => $tag2->name,
]);
$this->assertDatabaseMissing('contact_tag', [
'contact_id' => $contact->id,
'account_id' => $user->account_id,
'tag_id' => $tag->id,
]);
$this->assertDatabaseMissing('contact_tag', [
'contact_id' => $contact->id,
'account_id' => $user->account_id,
'tag_id' => $tag2->id,
]);
$this->assertDatabaseHas('contact_tag', [
'contact_id' => $contact->id,
'account_id' => $user->account_id,
'tag_id' => $tag3->id,
]);
}
/** @test */
public function it_removes_all_tags_from_a_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$tag = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'friend',
]);
$tag2 = factory(Tag::class)->create([
'account_id' => $user->account_id,
'name' => 'family',
]);
$contact->tags()->syncWithoutDetaching([
$tag->id => [
'account_id' => $contact->account_id,
],
$tag2->id => [
'account_id' => $contact->account_id,
],
]);
$response = $this->json('POST', "/api/contacts/{$contact->id}/unsetTags");
$response->assertStatus(200);
$response->assertJsonMissing([
'name' => $tag2->name,
]);
$this->assertDatabaseMissing('contact_tag', [
'contact_id' => $contact->id,
'account_id' => $user->account_id,
]);
}
}

View File

@@ -0,0 +1,208 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\User\User;
use App\Models\Contact\Contact;
use App\Models\Contact\Conversation;
use App\Models\Contact\ContactFieldType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiConversationControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonConversations = [
'id',
'object',
'happened_at',
'messages',
'contact_field_type' => [
'id',
],
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
private function createConversation(User $user): Conversation
{
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$contactFieldType = factory(ContactFieldType::class)->create([
'account_id' => $user->account_id,
]);
$conversation = factory(Conversation::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'contact_field_type_id' => $contactFieldType->id,
'happened_at' => now(),
]);
return $conversation;
}
/** @test */
public function it_gets_a_list_of_conversations()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createConversation($user);
}
$response = $this->json('GET', '/api/conversations');
$response->assertStatus(200);
$this->assertCount(
10,
$response->decodeResponseJson()['data']
);
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
]);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonConversations,
],
]);
}
/** @test */
public function it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createConversation($user);
}
$response = $this->json('GET', '/api/conversations?limit=1');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 1,
'last_page' => 10,
]);
$response = $this->json('GET', '/api/conversations?limit=2');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 2,
'last_page' => 5,
]);
}
/** @test */
public function it_gets_a_conversation()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$response = $this->json('GET', '/api/conversations/'.$conversation->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonConversations,
]);
}
/** @test */
public function it_gets_a_conversation_for_a_specific_contact()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$response = $this->json('GET', '/api/contacts/'.$conversation['contact_id'].'/conversations');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonConversations,
],
]);
}
/** @test */
public function it_creates_a_conversation()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$contactFieldType = factory(ContactFieldType::class)->create([
'account_id' => $contact->account_id,
]);
$response = $this->json('POST', '/api/conversations', [
'contact_id' => $contact->id,
'happened_at' => '1989-02-02',
'contact_field_type_id' => $contactFieldType->id,
]);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonConversations,
]);
}
/** @test */
public function it_updates_a_conversation()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$contactFieldType = factory(ContactFieldType::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/conversations/'.$conversation->id, [
'happened_at' => '1989-02-02',
'contact_field_type_id' => $contactFieldType->id,
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonConversations,
]);
}
/** @test */
public function it_destroys_a_conversation()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$response = $this->delete('/api/conversations/'.$conversation->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $conversation->id,
]);
}
}

View File

@@ -0,0 +1,256 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\User\User;
use App\Models\Contact\Contact;
use App\Models\Contact\Document;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiDocumentControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonDocuments = [
'id',
'object',
'original_filename',
'new_filename',
'filesize',
'type',
'mime_type',
'number_of_downloads',
'link',
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
private function createDocument(User $user): Document
{
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$document = factory(Document::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
]);
return $document;
}
/** @test */
public function it_gets_a_list_of_documents()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createDocument($user);
}
$response = $this->json('GET', '/api/documents');
$response->assertStatus(200);
$this->assertCount(
10,
$response->decodeResponseJson()['data']
);
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
]);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonDocuments,
],
]);
}
/** @test */
public function it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createDocument($user);
}
$response = $this->json('GET', '/api/documents?limit=1');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 1,
'last_page' => 10,
]);
$response = $this->json('GET', '/api/documents?limit=2');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 2,
'last_page' => 5,
]);
}
/** @test */
public function it_gets_a_document()
{
$user = $this->signin();
$document = $this->createDocument($user);
$response = $this->json('GET', '/api/documents/'.$document->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDocuments,
]);
}
/** @test */
public function document_show_gets_an_error_if_document_is_not_linked_to_account()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$document = factory(Document::class)->create([
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('GET', '/api/documents/'.$document->id);
$this->expectNotFound($response);
}
/** @test */
public function it_gets_a_document_for_a_specific_contact()
{
$user = $this->signin();
$document = $this->createDocument($user);
$response = $this->json('GET', '/api/contacts/'.$document['contact_id'].'/documents');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonDocuments,
],
]);
$response->assertJsonFragment([
'total' => 1,
'current_page' => 1,
'per_page' => 15,
'last_page' => 1,
]);
}
/** @test */
public function it_store_a_document_for_a_specific_contact()
{
Storage::fake();
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/documents', [
'contact_id' => $contact->id,
'document' => UploadedFile::fake()->image('test.pdf'),
]);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonDocuments,
]);
$this->assertDatabaseHas('documents', [
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'original_filename' => 'test.pdf',
]);
Storage::disk('public')->assertExists($response->json('data.new_filename'));
}
/** @test */
public function document_store_gets_an_error_if_fields_are_missing()
{
$user = $this->signin();
$response = $this->json('POST', '/api/documents', [
]);
$this->expectDataError($response, [
'The contact id field is required.',
]);
}
/** @test */
public function document_store_gets_an_error_if_contact_is_not_linked_to_user()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$response = $this->json('POST', '/api/documents', [
'contact_id' => $contact->id,
'document' => UploadedFile::fake()->image('test.pdf'),
]);
$this->expectNotFound($response);
}
/** @test */
public function it_destroy_a_document()
{
$user = $this->signin();
$document = $this->createDocument($user);
$response = $this->json('DELETE', '/api/documents/'.$document->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $document->id,
]);
}
/** @test */
public function document_destroy_gets_an_error_if_document_is_not_linked_to_user()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$document = factory(Document::class)->create([
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
]);
$response = $this->json('DELETE', '/api/documents/'.$document->id);
$this->expectNotFound($response);
}
}

View File

@@ -0,0 +1,340 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\User\User;
use App\Models\Contact\Contact;
use App\Models\Contact\LifeEvent;
use App\Models\Contact\LifeEventType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiLifeEventControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonLifeEvents = [
'id',
'object',
'name',
'note',
'happened_at',
'life_event_type' => [
'id',
],
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
private function createLifeEvent(User $user): LifeEvent
{
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $user->account_id,
]);
$lifeEvent = factory(LifeEvent::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'life_event_type_id' => $lifeEventType->id,
'happened_at' => now(),
'name' => 'This is a text',
'note' => 'This is a text',
]);
return $lifeEvent;
}
/** @test */
public function it_gets_a_list_of_life_events()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createLifeEvent($user);
}
$response = $this->json('GET', '/api/lifeevents');
$response->assertStatus(200);
$this->assertCount(
10,
$response->decodeResponseJson()['data']
);
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
]);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonLifeEvents,
],
]);
}
/** @test */
public function it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createLifeEvent($user);
}
$response = $this->json('GET', '/api/lifeevents?limit=1');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 1,
'last_page' => 10,
]);
$response = $this->json('GET', '/api/lifeevents?limit=2');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 2,
'last_page' => 5,
]);
}
/** @test */
public function it_gets_a_life_event()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$response = $this->json('GET', '/api/lifeevents/'.$lifeEvent->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonLifeEvents,
]);
}
/** @test */
public function getting_a_life_event_doesnt_work_if_life_event_doesnt_exist()
{
$user = $this->signin();
$response = $this->json('GET', '/api/lifeevents/329029093809');
$this->expectNotFound($response);
}
/** @test */
public function it_creates_a_life_event()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $contact->account_id,
]);
$response = $this->json('POST', '/api/lifeevents', [
'contact_id' => $contact->id,
'life_event_type_id' => $lifeEventType->id,
'happened_at' => '1989-02-02',
'name' => 'This is a text',
'note' => 'This is a text',
'has_reminder' => false,
'happened_at_month_unknown' => false,
'happened_at_day_unknown' => false,
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonLifeEvents,
]);
}
/** @test */
public function creating_a_life_event_doesnt_work_if_ids_are_not_found()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/lifeevents', [
'contact_id' => $contact->id,
'life_event_type_id' => 0,
'happened_at' => '1989-02-02',
'name' => 'This is a text',
'note' => 'This is a text',
'has_reminder' => false,
'happened_at_month_unknown' => false,
'happened_at_day_unknown' => false,
]);
$this->expectNotFound($response);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $contact->account_id,
]);
$response = $this->json('POST', '/api/lifeevents', [
'contact_id' => 0,
'life_event_type_id' => $lifeEventType->id,
'happened_at' => '1989-02-02',
'name' => 'This is a text',
'note' => 'This is a text',
'has_reminder' => false,
'happened_at_month_unknown' => false,
'happened_at_day_unknown' => false,
]);
$this->expectNotFound($response);
}
/** @test */
public function creating_a_life_event_doesnt_work_if_parameters_are_not_right()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $contact->account_id,
]);
$response = $this->json('POST', '/api/lifeevents', [
'contact_id' => $contact->id,
'life_event_type_id' => $lifeEventType->id,
'name' => 'This is a text',
'note' => 'This is a text',
]);
$this->expectDataError($response, [
'The happened at field is required.',
'The has reminder field is required.',
'The happened at month unknown field is required.',
'The happened at day unknown field is required.',
]);
}
/** @test */
public function it_updates_a_life_event()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/lifeevents/'.$lifeEvent->id, [
'happened_at' => '1989-02-02',
'life_event_type_id' => $lifeEventType->id,
'name' => 'This is a text',
'note' => 'This is a text',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonLifeEvents,
]);
}
/** @test */
public function updating_a_life_event_doesnt_work_if_ids_are_not_found()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/lifeevents/23929390', [
'happened_at' => '1989-02-02',
'life_event_type_id' => $lifeEventType->id,
'name' => 'This is a text',
'note' => 'This is a text',
]);
$this->expectNotFound($response);
$response = $this->json('PUT', '/api/lifeevents/'.$lifeEvent->id, [
'happened_at' => '1989-02-02',
'life_event_type_id' => 3283028,
'name' => 'This is a text',
'note' => 'This is a text',
]);
$this->expectNotFound($response);
}
/** @test */
public function updating_a_life_event_doesnt_work_if_parameters_are_not_right()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$lifeEventType = factory(LifeEventType::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('PUT', '/api/lifeevents/'.$lifeEvent->id, [
'life_event_type_id' => $lifeEventType->id,
'name' => 'This is a text',
'note' => 'This is a text',
]);
$this->expectDataError($response, [
'The happened at field is required.',
]);
}
/** @test */
public function it_destroys_a_life_event()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$response = $this->delete('/api/lifeevents/'.$lifeEvent->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $lifeEvent->id,
]);
}
/** @test */
public function deleting_a_life_event_doesnt_work_if_ids_are_not_found()
{
$user = $this->signin();
$lifeEvent = $this->createLifeEvent($user);
$response = $this->delete('/api/lifeevents/39230990');
$this->expectNotFound($response);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiMeControllerTest extends ApiTestCase
{
use DatabaseTransactions;
/** @test */
public function it_sets_me_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/me/contact', ['contact_id' => $contact->id]);
$response->assertStatus(200);
$this->assertDatabaseHas('users', [
'account_id' => $user->account_id,
'me_contact_id' => $contact->id,
]);
}
/** @test */
public function it_throws_an_error_if_wrong_account_on_sets_me_contact()
{
$this->signin();
$contact = factory(Contact::class)->create();
$response = $this->json('POST', '/api/me/contact', ['contact_id' => $contact->id]);
$this->expectNotFound($response);
}
/** @test */
public function it_throws_an_error_if_account_not_exists_on_sets_me_contact()
{
$this->signin();
$response = $this->json('POST', '/api/me/contact', ['contact_id' => 0]);
$this->expectDataError($response, [
'The selected contact id is invalid.',
]);
}
/** @test */
public function it_removes_me_contact()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$user->me_contact_id = $contact->id;
$user->save();
$response = $this->json('DELETE', '/api/me/contact');
$response->assertStatus(200);
$this->assertDatabaseHas('users', [
'account_id' => $user->account_id,
'me_contact_id' => null,
]);
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\User\User;
use App\Models\Contact\Contact;
use App\Models\Contact\Message;
use App\Models\Contact\Conversation;
use App\Models\Contact\ContactFieldType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiMessageControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonConversations = [
'id',
'object',
'happened_at',
'messages' => [
[
'id',
],
],
'contact_field_type' => [
'id',
],
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
private function createConversation(User $user): Conversation
{
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$contactFieldType = factory(ContactFieldType::class)->create([
'account_id' => $user->account_id,
]);
$conversation = factory(Conversation::class)->create([
'account_id' => $user->account_id,
'contact_id' => $contact->id,
'contact_field_type_id' => $contactFieldType->id,
'happened_at' => now(),
]);
return $conversation;
}
private function addMessage(Conversation $conversation): Message
{
$message = factory(Message::class)->create([
'account_id' => $conversation->account_id,
'contact_id' => $conversation->contact_id,
'conversation_id' => $conversation->id,
]);
return $message;
}
/** @test */
public function it_adds_a_message_to_a_conversation()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$response = $this->json('POST', '/api/conversations/'.$conversation->id.'/messages', [
'written_at' => '1998-02-02',
'written_by_me' => true,
'content' => 'lorem ipsum',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonConversations,
]);
}
/** @test */
public function it_updates_a_message()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$message = $this->addMessage($conversation);
$response = $this->json('PUT', '/api/conversations/'.$conversation->id.'/messages/'.$message->id, [
'written_at' => '1989-02-02',
'written_by_me' => true,
'content' => 'lorem ipsum',
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonConversations,
]);
}
/** @test */
public function it_destroys_a_message()
{
$user = $this->signin();
$conversation = $this->createConversation($user);
$message = $this->addMessage($conversation);
$response = $this->delete('/api/conversations/'.$conversation->id.'/messages/'.$message->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $message->id,
]);
}
}

View File

@@ -0,0 +1,228 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\Account\Account;
use App\Models\Account\Company;
use App\Models\Contact\Contact;
use App\Models\Contact\Occupation;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiOccupationControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonOccupation = [
'id',
'object',
'title',
'description',
'salary',
'salary_unit',
'currently_works_here',
'start_date',
'end_date',
'company' => [
'id',
],
'account' => [
'id',
],
'created_at',
'updated_at',
];
public function test_it_gets_a_list_of_occupations()
{
$user = $this->signin();
factory(Occupation::class, 3)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('GET', '/api/occupations');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => ['*' => $this->jsonOccupation],
]);
}
public function test_it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
factory(Occupation::class, 10)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('GET', '/api/occupations?limit=1');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 1,
'last_page' => 10,
]);
$response = $this->json('GET', '/api/occupations?limit=2');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 2,
'last_page' => 5,
]);
}
public function test_it_gets_one_occupation()
{
$user = $this->signin();
$occupation = factory(Occupation::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('get', '/api/occupations/'.$occupation->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonOccupation,
]);
$response->assertJsonFragment([
'object' => 'occupation',
'id' => $occupation->id,
]);
}
public function test_it_cant_get_a_occupation_with_unexistent_id()
{
$user = $this->signin();
$response = $this->json('get', '/api/occupations/0');
$this->expectNotFound($response);
}
public function test_it_creates_a_occupation()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$company = factory(Company::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('post', '/api/occupations', [
'contact_id' => $contact->id,
'company_id' => $company->id,
'title' => 'Waiter',
]);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonOccupation,
]);
$occupationId = $response->json('data.id');
$response->assertJsonFragment([
'object' => 'occupation',
'id' => $occupationId,
]);
$this->assertDatabaseHas('occupations', [
'account_id' => $user->account_id,
'id' => $occupationId,
'title' => 'Waiter',
]);
}
public function test_it_updates_a_occupation()
{
$user = $this->signin();
$occupation = factory(Occupation::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('put', '/api/occupations/'.$occupation->id, [
'contact_id' => $occupation->contact_id,
'company_id' => $occupation->company_id,
'title' => 'Commissaire',
'salary' => null,
]);
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => $this->jsonOccupation,
]);
$occupationId = $response->json('data.id');
$this->assertEquals($occupation->id, $occupationId);
$response->assertJsonFragment([
'object' => 'occupation',
'id' => $occupationId,
]);
$this->assertDatabaseHas('occupations', [
'account_id' => $user->account_id,
'id' => $occupationId,
'title' => 'Commissaire',
'salary' => null,
]);
}
public function test_it_cant_update_a_occupation_if_account_is_not_linked_to_occupation()
{
$user = $this->signin();
$account = factory(Account::class)->create([]);
$occupation = factory(Occupation::class)->create([
'account_id' => $account->id,
]);
$response = $this->json('put', '/api/occupations/'.$occupation->id, [
'contact_id' => $occupation->contact_id,
'company_id' => $occupation->company_id,
'title' => 'Commissaire',
'salary' => null,
]);
$this->expectNotFound($response);
}
public function test_it_deletes_a_occupation()
{
$user = $this->signin();
$occupation = factory(Occupation::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('delete', '/api/occupations/'.$occupation->id);
$response->assertStatus(200);
$this->assertdatabasemissing('occupations', [
'account_id' => $user->account_id,
'id' => $occupation->id,
]);
}
public function test_it_cant_delete_a_occupation_if_occupation_doesnt_exist()
{
$user = $this->signin();
$response = $this->json('delete', '/api/occupations/0');
$this->expectDataError($response, [
'The selected occupation id is invalid.',
]);
}
}

View File

@@ -0,0 +1,294 @@
<?php
namespace Tests\Api\Contact;
use Tests\ApiTestCase;
use App\Models\User\User;
use App\Models\Account\Photo;
use App\Models\Contact\Contact;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ApiPhotoControllerTest extends ApiTestCase
{
use DatabaseTransactions;
protected $jsonDatas = [
'id',
'object',
'original_filename',
'new_filename',
'filesize',
'mime_type',
'link',
'account' => [
'id',
],
'contact' => [
'id',
],
'created_at',
'updated_at',
];
private function createPhoto(User $user): Photo
{
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$photo = factory(Photo::class)->create([
'account_id' => $user->account_id,
]);
UploadedFile::fake()->image('file.jpg')->storeAs('', 'file.jpg');
$contact->photos()->syncWithoutDetaching([$photo->id]);
return $photo;
}
/** @test */
public function it_gets_a_list_of_photos()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createPhoto($user);
}
$response = $this->json('GET', '/api/photos');
$response->assertStatus(200);
$this->assertCount(
10,
$response->decodeResponseJson()['data']
);
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
]);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonDatas,
],
]);
}
/** @test */
public function it_applies_the_limit_parameter_in_search()
{
$user = $this->signin();
for ($i = 0; $i < 10; $i++) {
$this->createPhoto($user);
}
$response = $this->json('GET', '/api/photos?limit=1');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 1,
'last_page' => 10,
]);
$response = $this->json('GET', '/api/photos?limit=2');
$response->assertJsonFragment([
'total' => 10,
'current_page' => 1,
'per_page' => 2,
'last_page' => 5,
]);
}
/** @test */
public function it_gets_a_photo()
{
$user = $this->signin();
$photo = $this->createPhoto($user);
$response = $this->json('GET', '/api/photos/'.$photo->id);
$response->assertStatus(200);
$response->assertJsonStructure([
'*' => $this->jsonDatas,
]);
}
/** @test */
public function photo_show_gets_an_error_if_photo_is_not_linked_to_account()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$photo = factory(Photo::class)->create([
'account_id' => $contact->account_id,
]);
$contact->photos()->syncWithoutDetaching([$photo->id]);
$response = $this->json('GET', '/api/photos/'.$photo->id);
$this->expectNotFound($response);
}
/** @test */
public function it_gets_a_photo_for_a_specific_contact()
{
$user = $this->signin();
$photo = $this->createPhoto($user);
$response = $this->json('GET', '/api/contacts/'.$photo->contact()->id.'/photos');
$response->assertStatus(200);
$response->assertJsonStructure([
'data' => [
'*' => $this->jsonDatas,
],
]);
$response->assertJsonFragment([
'total' => 1,
'current_page' => 1,
'per_page' => 15,
'last_page' => 1,
]);
}
/** @test */
public function it_store_a_photo_for_a_specific_contact()
{
Storage::fake();
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/photos', [
'contact_id' => $contact->id,
'photo' => UploadedFile::fake()->image('test.jpg'),
]);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonDatas,
]);
$this->assertDatabaseHas('photos', [
'account_id' => $user->account_id,
'original_filename' => 'test.jpg',
]);
Storage::disk('public')->assertExists($response->json('data.new_filename'));
}
/** @test */
public function photo_store_gets_an_error_if_fields_are_missing()
{
$user = $this->signin();
$response = $this->json('POST', '/api/photos', [
]);
$this->expectDataError($response, [
'The contact id field is required.',
]);
}
/** @test */
public function photo_store_gets_an_error_if_contact_is_not_linked_to_user()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$response = $this->json('POST', '/api/photos', [
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
'photo' => UploadedFile::fake()->image('test.jpg'),
]);
$this->expectNotFound($response);
}
/** @test */
public function it_destroy_a_photo()
{
$user = $this->signin();
$photo = $this->createPhoto($user);
$response = $this->json('DELETE', '/api/photos/'.$photo->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $photo->id,
]);
$this->assertDatabaseMissing('photos', [
'id' => $photo->id,
'account_id' => $user->account_id,
]);
}
/** @test */
public function photo_destroy_gets_an_error_if_photo_is_not_linked_to_account()
{
$user = $this->signin();
$contact = factory(Contact::class)->create();
$photo = factory(Photo::class)->create([
'account_id' => $contact->account_id,
]);
$contact->photos()->syncWithoutDetaching([$photo->id]);
$response = $this->json('DELETE', '/api/photos/'.$photo->id);
$this->expectNotFound($response);
}
/** @test */
public function it_store_and_destroy_a_photo()
{
Storage::fake();
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/api/photos/', [
'contact_id' => $contact->id,
'photo' => UploadedFile::fake()->image('test.jpg'),
]);
$photo = $contact->photos->first();
Storage::disk('public')->assertExists($photo->new_filename);
$response = $this->json('DELETE', '/api/photos/'.$photo->id);
$response->assertStatus(200);
$response->assertJsonFragment([
'deleted' => true,
'id' => $photo->id,
]);
Storage::disk('public')->assertMissing($photo->new_filename);
}
}