refactor: replace custom CRM with Monica fork
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account\Activity;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\ActivityTypeCategory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiActivityTypeCategoryControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureActivityTypeCategory = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_list_of_activity_type_categories()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(ActivityTypeCategory::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypecategories');
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructureActivityTypeCategory,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_applies_limit_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(ActivityTypeCategory::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypecategories?limit=1');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypecategories?limit=2');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 2,
|
||||
'last_page' => 5,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_stores_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/activitytypecategories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_type_categories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityTypeCategory,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activitytypecategories/'.$activityTypeCategory->id, [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_type_categories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityTypeCategory,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_update_if_custom_field_not_found()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('PUT', '/api/activitytypecategories/2349273984279348', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected activity type category id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'France',
|
||||
]);
|
||||
|
||||
$response = $this->delete('/api/activitytypecategories/'.$activityTypeCategory->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('activity_type_categories', [
|
||||
'id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'deleted' => true,
|
||||
'id' => $activityTypeCategory->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_delete_the_custom_field_if_not_found()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->delete('/api/activitytypecategories/2349273984279348');
|
||||
|
||||
$response->assertStatus(422);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected activity type category id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_single_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypecategories/'.$activityTypeCategory->id);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityTypeCategory,
|
||||
]);
|
||||
}
|
||||
}
|
||||
228
tests/Api/Account/Activity/ApiActivityTypeControllerTest.php
Normal file
228
tests/Api/Account/Activity/ApiActivityTypeControllerTest.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account\Activity;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Activity;
|
||||
use App\Models\Account\ActivityType;
|
||||
use App\Models\Account\ActivityTypeCategory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiActivityTypeControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureActivityType = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'location_type',
|
||||
'activity_type_category' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_list_of_activity_types()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(ActivityType::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypes');
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructureActivityType,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_applies_limit_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypes = factory(ActivityType::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypes?limit=1');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypes?limit=2');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 2,
|
||||
'last_page' => 5,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_stores_an_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/activitytypes', [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_types', [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityType,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_store_an_activity_type_if_query_not_valid()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/activitytypes');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The activity type category id field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_an_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activitytypes/'.$activityType->id, [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_types', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityType,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_update_if_activity_type_not_found()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('PUT', '/api/activitytypes/2349273984279348', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The activity type category id field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_an_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activities = factory(Activity::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response = $this->delete('/api/activitytypes/'.$activityType->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('activity_types', [
|
||||
'id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('activities', [
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'deleted' => true,
|
||||
'id' => $activityType->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_delete_the_activity_type_if_not_found()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->delete('/api/activitytypes/2349273984279348');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected activity type id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_single_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activitytypes/'.$activityType->id);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureActivityType,
|
||||
]);
|
||||
}
|
||||
}
|
||||
216
tests/Api/Account/ApiCompanyControllerTest.php
Normal file
216
tests/Api/Account/ApiCompanyControllerTest.php
Normal file
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Account\Company;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiCompanyControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonCompany = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'website',
|
||||
'number_of_employees',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_list_of_companies()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Company::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/companies');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonCompany],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_applies_the_limit_parameter_in_search()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Company::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/companies?limit=1');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/companies?limit=2');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 2,
|
||||
'last_page' => 5,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_company()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$company = factory(Company::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('get', '/api/companies/'.$company->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonCompany,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'company',
|
||||
'id' => $company->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_call_with_unexistent_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('get', '/api/companies/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_company()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('post', '/api/companies', [
|
||||
'name' => 'Central Perk',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonCompany,
|
||||
]);
|
||||
|
||||
$companyId = $response->json('data.id');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'company',
|
||||
'id' => $companyId,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('companies', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $companyId,
|
||||
'name' => 'Central Perk',
|
||||
'number_of_employees' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_company()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$company = factory(Company::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/companies/'.$company->id, [
|
||||
'name' => 'Central Perk Central',
|
||||
'number_of_employees' => 30,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonCompany,
|
||||
]);
|
||||
|
||||
$companyId = $response->json('data.id');
|
||||
|
||||
$this->assertEquals($company->id, $companyId);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'company',
|
||||
'id' => $companyId,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('companies', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $companyId,
|
||||
'name' => 'Central Perk Central',
|
||||
'number_of_employees' => 30,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_company_if_account_is_not_linked_to_company()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$company = factory(Company::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/companies/'.$company->id, [
|
||||
'name' => 'Central Perk',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_company()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$company = factory(Company::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('delete', '/api/companies/'.$company->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertdatabasemissing('companies', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $company->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_company_if_company_doesnt_exist()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('delete', '/api/companies/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected company id is invalid.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
236
tests/Api/Account/ApiGenderControllerTest.php
Normal file
236
tests/Api/Account/ApiGenderControllerTest.php
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Gender;
|
||||
use App\Models\Account\Account;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiGenderControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonGender = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'type',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_list_of_genders()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Gender::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/genders');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonGender],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_applies_the_limit_parameter_in_search()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Gender::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/genders?limit=1');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/genders?limit=2');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 2,
|
||||
'last_page' => 5,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_gender()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('get', '/api/genders/'.$gender->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGender,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gender',
|
||||
'id' => $gender->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_gender_with_unexistent_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('get', '/api/genders/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_gender()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/genders', [
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGender,
|
||||
]);
|
||||
|
||||
$genderId = $response->json('data.id');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gender',
|
||||
'id' => $genderId,
|
||||
]);
|
||||
|
||||
$this->assertDatabasehas('genders', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $genderId,
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_gender()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/genders/'.$gender->id, [
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGender,
|
||||
]);
|
||||
|
||||
$genderId = $response->json('data.id');
|
||||
|
||||
$this->assertEquals($gender->id, $genderId);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gender',
|
||||
'id' => $genderId,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('genders', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $genderId,
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_gender_if_account_is_not_linked_to_gender()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/genders/'.$gender->id, [
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_gender_if_account_is_not_linked_to_gender2()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/genders/'.$gender->id, [
|
||||
'account_id' => $account->id,
|
||||
'name' => 'man',
|
||||
'type' => 'M',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_gender()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('delete', '/api/genders/'.$gender->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('genders', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $gender->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_gender_if_gender_doesnt_exist()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('delete', '/api/genders/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected gender id is invalid.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
210
tests/Api/Account/ApiPlaceControllerTest.php
Normal file
210
tests/Api/Account/ApiPlaceControllerTest.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Place;
|
||||
use App\Models\Account\Account;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiPlaceControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonPlace = [
|
||||
'id',
|
||||
'object',
|
||||
'street',
|
||||
'city',
|
||||
'province',
|
||||
'postal_code',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'country',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
public function test_it_gets_a_list_of_places()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Place::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/places');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonPlace],
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_applies_the_limit_parameter_in_search()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Place::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/places?limit=1');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 10,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/places?limit=2');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
'per_page' => 2,
|
||||
'last_page' => 5,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_gets_one_place()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$place = factory(Place::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('get', '/api/places/'.$place->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPlace,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'place',
|
||||
'id' => $place->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_cant_get_a_call_with_unexistent_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('get', '/api/places/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
public function test_it_create_a_place()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('post', '/api/places', [
|
||||
'city' => 'New York',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPlace,
|
||||
]);
|
||||
|
||||
$placeId = $response->json('data.id');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'place',
|
||||
'id' => $placeId,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('places', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $placeId,
|
||||
'city' => 'New York',
|
||||
'latitude' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_updates_a_place()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$place = factory(Place::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/places/'.$place->id, [
|
||||
'city' => 'New York',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPlace,
|
||||
]);
|
||||
|
||||
$placeId = $response->json('data.id');
|
||||
|
||||
$this->assertEquals($place->id, $placeId);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'place',
|
||||
'id' => $placeId,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('places', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $placeId,
|
||||
'city' => 'New York',
|
||||
'latitude' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_cant_update_a_place_if_account_is_not_linked_to_place()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$place = factory(Place::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('put', '/api/places/'.$place->id, [
|
||||
'city' => 'New York',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
public function test_it_deletes_a_place()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$place = factory(Place::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('delete', '/api/places/'.$place->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertdatabasemissing('places', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $place->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_cant_delete_a_place_if_place_doesnt_exist()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('delete', '/api/places/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected place id is invalid.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
157
tests/Api/Account/ApiUserControllerTest.php
Normal file
157
tests/Api/Account/ApiUserControllerTest.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Account;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Settings\Term;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiUserControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureUser = [
|
||||
'id',
|
||||
'object',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'timezone',
|
||||
'currency',
|
||||
'locale',
|
||||
'is_policy_compliant',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_authenticated_user()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$response = $this->get('/api/me');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureUser,
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'first_name' => $user->first_name,
|
||||
'object' => 'user',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_tells_if_the_user_has_signed_a_given_policy()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$term = factory(Term::class)->create([]);
|
||||
$user->terms()->syncWithoutDetaching([$term->id => ['account_id' => $user->account_id]]);
|
||||
|
||||
$response = $this->get('/api/me/compliance/'.$term->id);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'signed' => true,
|
||||
'ip_address' => null,
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'signed',
|
||||
'signed_date',
|
||||
'ip_address',
|
||||
'user',
|
||||
'term',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_returns_method_not_found_if_no_policy_is_found()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$response = $this->get('/api/me/compliance/32455212');
|
||||
|
||||
$response->assertStatus(404);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'message' => 'The resource has not been found',
|
||||
'error_code' => 31,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_compliances_signed_by_user()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
$term = factory(Term::class)->create([]);
|
||||
$user->terms()->syncWithoutDetaching([$term->id => ['account_id' => $user->account_id]]);
|
||||
|
||||
$term2 = factory(Term::class)->create([]);
|
||||
$user->terms()->syncWithoutDetaching([$term2->id => ['account_id' => $user->account_id]]);
|
||||
|
||||
$response = $this->get('/api/me/compliance');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonCount(2, 'data');
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_no_compliances_signed_by_user()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$response = $this->get('/api/me/compliance');
|
||||
|
||||
$response->assertStatus(404);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_tries_to_sign_lapolicy()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$response = $this->post('/api/me/compliance');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The ip address field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_signs_lapolicy()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
$term = factory(Term::class)->create([]);
|
||||
$user->terms()->syncWithoutDetaching([$term->id => ['account_id' => $user->account_id]]);
|
||||
|
||||
$term2 = factory(Term::class)->create([]);
|
||||
$user->terms()->syncWithoutDetaching([$term2->id => ['account_id' => $user->account_id]]);
|
||||
|
||||
$params = [
|
||||
'ip_address' => '128.3.1.2',
|
||||
];
|
||||
|
||||
$response = $this->json('POST', '/api/me/compliance', $params);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'signed',
|
||||
'signed_date',
|
||||
'ip_address',
|
||||
'user',
|
||||
'term',
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
595
tests/Api/ApiActivitiesTest.php
Normal file
595
tests/Api/ApiActivitiesTest.php
Normal file
@@ -0,0 +1,595 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Account\Activity;
|
||||
use App\Models\Account\ActivityType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiActivitiesTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonActivity = [
|
||||
'id',
|
||||
'object',
|
||||
'summary',
|
||||
'description',
|
||||
'happened_at',
|
||||
'activity_type' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'location_type',
|
||||
'activity_type_category' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'account'=> [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'attendees' => [
|
||||
'total',
|
||||
'contacts' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'complete_name',
|
||||
],
|
||||
],
|
||||
],
|
||||
'emotions' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
],
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected $jsonActivityNoCategory = [
|
||||
'id',
|
||||
'object',
|
||||
'summary',
|
||||
'description',
|
||||
'happened_at',
|
||||
'attendees' => [
|
||||
'total',
|
||||
'contacts' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'complete_name',
|
||||
],
|
||||
],
|
||||
],
|
||||
'emotions' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
],
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function activities_get_all()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity1 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity2 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activities');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonActivity],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_contact_all()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity1 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity1->contacts()->attach($contact1, ['account_id' => $user->account_id]);
|
||||
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity2 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity2->contacts()->attach($contact2, ['account_id' => $user->account_id]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/activities');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonActivity],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'activity',
|
||||
'id' => $activity2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_contact_all_error()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/activities');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_contact_all_error_wrong_account()
|
||||
{
|
||||
$this->signin();
|
||||
$contact = factory(Contact::class)->create();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact->id.'/activities');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_one()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity1 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity2 = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/activities/'.$activity1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivity,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'activity',
|
||||
'id' => $activity2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_one_error()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/activities/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_get_one_error_wrong_account()
|
||||
{
|
||||
$this->signin();
|
||||
$activity = factory(Activity::class)->create();
|
||||
|
||||
$response = $this->json('GET', '/api/activities/'.$activity->id);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivity,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'description' => 'the description',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_wrong_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/activities', [
|
||||
'contact_id' => [$contact->id],
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The summary field is required.',
|
||||
'The happened at field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_bad_account()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/api/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_bad_account2()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$activityType = factory(ActivityType::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/api/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivityNoCategory,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivity,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$activity_type_id = $response->json('data.activity_type.id');
|
||||
$this->assertEquals($activityType->id, $activity_type_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activityType',
|
||||
'id' => $activity_type_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_existing()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact->activities()->attach($activity, [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2->activities()->attach($activity, [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'activity_id' => $activity->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivityNoCategory,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/0', [
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected activity id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_account_for_activity()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_account_for_contacts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/activities/'.$activity->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete_error()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/activities/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected activity id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete_with_wrong_account()
|
||||
{
|
||||
$this->signin();
|
||||
$activity = factory(Activity::class)->create();
|
||||
|
||||
$response = $this->json('DELETE', '/api/activities/'.$activity->id);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
203
tests/Api/ApiControllerTest.php
Normal file
203
tests/Api/ApiControllerTest.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Http\Controllers\Api\ApiController;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function get_http_status_code_returns_the_status_code()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$this->assertEquals(
|
||||
200,
|
||||
$apiController->getHTTPStatusCode()
|
||||
);
|
||||
|
||||
$apiController->setHTTPStatusCode(300);
|
||||
|
||||
$this->assertEquals(
|
||||
300,
|
||||
$apiController->getHTTPStatusCode()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function get_error_code_returns_the_error_code()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$this->assertNull(
|
||||
$apiController->getErrorCode()
|
||||
);
|
||||
|
||||
$apiController->setErrorCode(30);
|
||||
|
||||
$this->assertEquals(
|
||||
30,
|
||||
$apiController->getErrorCode()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function get_with_parameter_returns_the_parameter()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$this->assertNull(
|
||||
$apiController->getWithParameter()
|
||||
);
|
||||
|
||||
$apiController->setWithParameter('test');
|
||||
|
||||
$this->assertEquals(
|
||||
'test',
|
||||
$apiController->getWithParameter()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function get_limit_per_page_code_returns_the_limit_per_page()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$apiController->getLimitPerPage()
|
||||
);
|
||||
|
||||
$apiController->setLimitPerPage(30);
|
||||
|
||||
$this->assertEquals(
|
||||
30,
|
||||
$apiController->getLimitPerPage()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_sort_criteria()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$this->assertEquals(
|
||||
'created_at',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
|
||||
$apiController->setSortCriteria('created_at');
|
||||
|
||||
$this->assertEquals(
|
||||
'created_at',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_only_accepts_some_sorting_parameters()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$apiController->setSortCriteria('created_at');
|
||||
|
||||
$this->assertEquals(
|
||||
'created_at',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
|
||||
$apiController->setSortCriteria('anything');
|
||||
|
||||
$this->assertEquals(
|
||||
'',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function calling_api_with_insane_limit_number_raises_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$insaneLimit = config('api.max_limit_per_page') * 100;
|
||||
|
||||
$response = $this->json('GET', "/api/contacts?limit={$insaneLimit}");
|
||||
|
||||
$response->assertStatus(400);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'message' => 'The limit parameter is too big',
|
||||
'error_code' => 30,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function calling_api_with_a_wrong_sort_parameter_raises_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$criteria = 'anything';
|
||||
|
||||
$response = $this->json('GET', "/api/contacts?sort={$criteria}");
|
||||
|
||||
$response->assertStatus(400);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'message' => 'The sorting criteria is invalid',
|
||||
'error_code' => 39,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_sets_the_order_by_parameters()
|
||||
{
|
||||
$apiController = new ApiController;
|
||||
|
||||
$apiController->setSortCriteria('created_at');
|
||||
|
||||
$this->assertEquals(
|
||||
'created_at',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'asc',
|
||||
$apiController->getSortDirection()
|
||||
);
|
||||
|
||||
$apiController->setSortCriteria('-created_at');
|
||||
|
||||
$this->assertEquals(
|
||||
'created_at',
|
||||
$apiController->getSortCriteria()
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
'desc',
|
||||
$apiController->getSortDirection()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function root_api()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'success' => [
|
||||
'message' => 'Welcome to Monica',
|
||||
],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'contacts_url' => route('api.contacts'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
62
tests/Api/ApiCountriesTest.php
Normal file
62
tests/Api/ApiCountriesTest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiCountriesTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonCountries = [
|
||||
'id',
|
||||
'iso',
|
||||
'name',
|
||||
'object',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_list_of_countries()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/countries');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonCountries],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'de' => [
|
||||
'id' => 'DE',
|
||||
'iso' => 'DE',
|
||||
'name' => 'Germany',
|
||||
'object' => 'country',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_specific_country_in_a_specific_locale()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->locale = 'fr';
|
||||
$user->save();
|
||||
|
||||
$response = $this->json('GET', '/api/countries');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonCountries],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'de' => [
|
||||
'id' => 'DE',
|
||||
'iso' => 'DE',
|
||||
'name' => 'Allemagne',
|
||||
'object' => 'country',
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
377
tests/Api/ApiDebtsTest.php
Normal file
377
tests/Api/ApiDebtsTest.php
Normal file
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Debt;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Settings\Currency;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiDebtsTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonDebt = [
|
||||
'id',
|
||||
'object',
|
||||
'in_debt',
|
||||
'status',
|
||||
'amount',
|
||||
'amount_with_currency',
|
||||
'reason',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_debts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt1 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt2 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/debts');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonDebt],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_debts_for_a_given_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt1 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt2 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/debts');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonDebt],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'debt',
|
||||
'id' => $debt2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_debts_from_an_invalid_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/debts');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt1 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$debt2 = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/debts/'.$debt1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonDebt,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'debt',
|
||||
'id' => $debt2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_debt_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/debts/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->locale = 'fr';
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$currency = factory(Currency::class)->create([
|
||||
'iso' => 'USD',
|
||||
'symbol' => '$',
|
||||
]);
|
||||
$user->currency()->associate($currency);
|
||||
$user->save();
|
||||
|
||||
$response = $this->json('POST', '/api/debts', [
|
||||
'contact_id' => $contact->id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => 42,
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonDebt,
|
||||
]);
|
||||
$debt_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => '42.00',
|
||||
'value' => '42,00',
|
||||
'amount_with_currency' => '42,00'.chr(0xA0).'$US',
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $debt_id);
|
||||
$this->assertDatabaseHas('debts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => 4200,
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_create_a_debt_if_fields_are_missing()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/debts', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The in debt field is required.',
|
||||
'The status field is required.',
|
||||
'The amount field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_create_a_debt_with_a_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/debts', [
|
||||
'contact_id' => $contact->id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'inprogress',
|
||||
'amount' => 42,
|
||||
'reason' => 'that\'s why',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->locale = 'fr';
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/debts/'.$debt->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 142.01,
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonDebt,
|
||||
]);
|
||||
$debt_id = $response->json('data.id');
|
||||
$this->assertEquals($debt->id, $debt_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'debt',
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => '142.01',
|
||||
'value' => '142,01',
|
||||
'amount_with_currency' => '142,01'.chr(0xA0).'$US',
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $debt_id);
|
||||
$this->assertDatabaseHas('debts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $debt_id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 14201,
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_debt_with_missing_parameters()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$debt = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/debts/'.$debt->id, [
|
||||
'contact_id' => $debt->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The in debt field is required.',
|
||||
'The status field is required.',
|
||||
'The amount field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_debt_with_a_wrong_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$debt = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/debts/'.$debt->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'in_debt' => 'yes',
|
||||
'status' => 'completed',
|
||||
'amount' => 142,
|
||||
'reason' => 'voilà',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_debt()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$debt = factory(Debt::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('debts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $debt->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/debts/'.$debt->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('debts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $debt->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_debt_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/debts/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
467
tests/Api/ApiGiftsTest.php
Normal file
467
tests/Api/ApiGiftsTest.php
Normal file
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Gift;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiGiftsTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonGift = [
|
||||
'id',
|
||||
'object',
|
||||
'status',
|
||||
'comment',
|
||||
'name',
|
||||
'url',
|
||||
'amount',
|
||||
'amount_with_currency',
|
||||
'status',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_gifts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift1 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift2 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/gifts');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonGift],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_gifts_of_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift1 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift2 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/gifts');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonGift],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'gift',
|
||||
'id' => $gift2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_all_the_gifts_of_an_invalid_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/gifts');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_gift()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift1 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$gift2 = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/gifts/'.$gift1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGift,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'gift',
|
||||
'id' => $gift2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_gift_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/gifts/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_create_a_gift()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/gifts', [
|
||||
'contact_id' => $contact->id,
|
||||
'status' => 'idea',
|
||||
'name' => 'the gift',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGift,
|
||||
]);
|
||||
$gift_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $gift_id);
|
||||
$this->assertDatabaseHas('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift_id,
|
||||
'name' => 'the gift',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_create_is_for()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/gifts', [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
'recipient_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGift,
|
||||
]);
|
||||
$gift_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $gift_id);
|
||||
$this->assertDatabaseHas('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift_id,
|
||||
'name' => 'the gift',
|
||||
'is_for' => $contact2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_create_is_for_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/gifts', [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
'recipient_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_create_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/gifts', [
|
||||
'contact_id' => $contact->id,
|
||||
'status' => 'idea',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The name field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_create_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/gifts', [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/gifts/'.$gift->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
'comment' => 'one comment',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGift,
|
||||
]);
|
||||
$gift_id = $response->json('data.id');
|
||||
$this->assertEquals($gift->id, $gift_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $gift_id);
|
||||
$this->assertDatabaseHas('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift_id,
|
||||
'name' => 'the gift',
|
||||
'comment' => 'one comment',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_update_is_for()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/gifts/'.$gift->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
'comment' => 'one comment',
|
||||
'recipient_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonGift,
|
||||
]);
|
||||
$gift_id = $response->json('data.id');
|
||||
$this->assertEquals($gift->id, $gift_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'gift',
|
||||
'id' => $gift_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $gift_id);
|
||||
$this->assertDatabaseHas('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift_id,
|
||||
'name' => 'the gift',
|
||||
'comment' => 'one comment',
|
||||
'is_for' => $contact2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_update_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$gift = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/gifts/'.$gift->id, [
|
||||
'contact_id' => $gift->contact_id,
|
||||
'status' => 'idea',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The name field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_update_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$gift = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/gifts/'.$gift->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'name' => 'the gift',
|
||||
'status' => 'idea',
|
||||
'comment' => 'one comment',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$gift = factory(Gift::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/gifts/'.$gift->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJson([
|
||||
'deleted' => true,
|
||||
'id' => $gift->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('gifts', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $gift->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_delete_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/gifts/0');
|
||||
|
||||
$response->assertStatus(422);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function gifts_delete_wrong_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$gift = factory(Gift::class)->create();
|
||||
|
||||
$response = $this->json('DELETE', '/api/gifts/'.$gift->id);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
215
tests/Api/ApiJournalTest.php
Normal file
215
tests/Api/ApiJournalTest.php
Normal file
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Journal\Entry;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiJournalTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonJournal = [
|
||||
'id',
|
||||
'object',
|
||||
'title',
|
||||
'post',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_journal_entries()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$firstEntry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$secondEntry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/journal');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonJournal],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'entry',
|
||||
'id' => $firstEntry->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'entry',
|
||||
'id' => $secondEntry->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_journal_entry()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$firstEntry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$secondEntry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/journal/'.$firstEntry->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonJournal,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'entry',
|
||||
'id' => $firstEntry->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'entry',
|
||||
'id' => $secondEntry->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_journal_entry_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/journal/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_journal_entry()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/journal', [
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonJournal,
|
||||
]);
|
||||
$entryId = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'entry',
|
||||
'id' => $entryId,
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $entryId);
|
||||
$this->assertDatabaseHas('entries', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $entryId,
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_create_a_journal_entry_with_missing_parameters()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/journal', []);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The title field is required.',
|
||||
'The post field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_journal_entry()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$entry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'title' => 'xxx',
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/journal/'.$entry->id, [
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonJournal,
|
||||
]);
|
||||
$entryId = $response->json('data.id');
|
||||
$this->assertEquals($entry->id, $entryId);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'entry',
|
||||
'id' => $entryId,
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $entryId);
|
||||
$this->assertDatabaseHas('entries', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $entryId,
|
||||
'title' => 'my title',
|
||||
'post' => 'content post',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_journal_entry_with_missing_parameters()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$entry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/journal/'.$entry->id, []);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The title field is required.',
|
||||
'The post field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_journal_entry()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$entry = factory(Entry::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('entries', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $entry->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/journal/'.$entry->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('entries', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $entry->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_journal_entry_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/journal/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
428
tests/Api/ApiNotesTest.php
Normal file
428
tests/Api/ApiNotesTest.php
Normal file
@@ -0,0 +1,428 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Note;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiNotesTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonNote = [
|
||||
'id',
|
||||
'object',
|
||||
'body',
|
||||
'is_favorited',
|
||||
'favorited_at',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_notes()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note1 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note2 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/notes');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonNote],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_notes_of_a_given_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note1 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note2 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/notes');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonNote],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'note',
|
||||
'id' => $note2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_notes_from_a_contact_with_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/notes');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_note()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note1 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$note2 = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/notes/'.$note1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonNote,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'note',
|
||||
'id' => $note2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_note_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/notes/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_note()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/notes', [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonNote,
|
||||
]);
|
||||
$note_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $note_id);
|
||||
$this->assertDatabaseHas('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_note_and_marks_as_favorite()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/notes', [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonNote,
|
||||
]);
|
||||
$note_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
'favorited_at' => '2018-01-01T07:00:00Z',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $note_id);
|
||||
$this->assertDatabaseHas('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
'favorited_at' => '2018-01-01',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_create_a_note_with_missing_parameters()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/notes', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The body field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_create_a_note_with_an_invalid_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/notes', [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_note()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/notes/'.$note->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonNote,
|
||||
]);
|
||||
$note_id = $response->json('data.id');
|
||||
$this->assertEquals($note->id, $note_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $note_id);
|
||||
$this->assertDatabaseHas('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_note_and_marks_it_as_favorite()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/notes/'.$note->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonNote,
|
||||
]);
|
||||
$note_id = $response->json('data.id');
|
||||
$this->assertEquals($note->id, $note_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'note',
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
'favorited_at' => '2018-01-01T07:00:00Z',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $note_id);
|
||||
$this->assertDatabaseHas('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note_id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => true,
|
||||
'favorited_at' => '2018-01-01',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_note_with_missing_parameters()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$note = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/notes/'.$note->id, [
|
||||
'contact_id' => $note->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The body field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_update_a_note_with_an_invalid_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$note = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/notes/'.$note->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'body' => 'the body of the note',
|
||||
'is_favorited' => false,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_note()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$note = factory(Note::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/notes/'.$note->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('notes', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $note->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_note_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/notes/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
347
tests/Api/ApiPetsTest.php
Normal file
347
tests/Api/ApiPetsTest.php
Normal file
@@ -0,0 +1,347 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Pet;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\PetCategory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiPetsTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonPet = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'pet_category' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'is_common',
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function pets_get_all()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet1 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet2 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/pets');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonPet],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_get_contact_all()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet1 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet2 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/pets');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonPet],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'pet',
|
||||
'id' => $pet2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_get_contact_all_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/pets');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_get_one()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet1 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$pet2 = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/pets/'.$pet1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPet,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'pet',
|
||||
'id' => $pet2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_get_one_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/pets/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_create()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet_category = factory(PetCategory::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/api/pets', [
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPet,
|
||||
]);
|
||||
$pet_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet_id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $pet_id);
|
||||
$this->assertDatabaseHas('pets', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
'id' => $pet_id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_create_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/pets', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The pet category id field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_create_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$pet_category = factory(PetCategory::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/api/pets', [
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$pet_category = factory(PetCategory::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/api/pets/'.$pet->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonPet,
|
||||
]);
|
||||
$pet_id = $response->json('data.id');
|
||||
$this->assertEquals($pet->id, $pet_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'pet',
|
||||
'id' => $pet_id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $pet_id);
|
||||
$this->assertDatabaseHas('pets', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
'id' => $pet_id,
|
||||
'name' => 'the name',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_update_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$pet = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/pets/'.$pet->id, [
|
||||
'contact_id' => $pet->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The pet category id field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_update_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$pet = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$pet_category = factory(PetCategory::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/api/pets/'.$pet->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'pet_category_id' => $pet_category->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$pet = factory(Pet::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('pets', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $pet->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/pets/'.$pet->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('pets', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $pet->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function pets_delete_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/pets/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
389
tests/Api/ApiRelationshipControllerTest.php
Normal file
389
tests/Api/ApiRelationshipControllerTest.php
Normal file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Relationship\Relationship;
|
||||
use App\Models\Relationship\RelationshipType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiRelationshipControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_rejects_the_api_call_if_parameters_are_not_right()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactB = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
// make sure contact_is is an integer
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => 'a',
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, ['The contact is must be an integer.']);
|
||||
|
||||
// make sure relationship type id is an integer
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => 'a',
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, ['The relationship type id must be an integer.']);
|
||||
|
||||
// make sure of_contact is an integer
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => 'a',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, ['The of contact must be an integer.']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_relationship_type_id_is_invalid()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactB = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$relationshipType = factory(RelationshipType::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_contact_is_id_is_invalid()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create();
|
||||
$contactB = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_if_of_contact_id_is_invalid()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactB = factory(Contact::class)->create();
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_new_resource()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$contactB = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'uncle',
|
||||
'name_reverse_relationship' => 'nephew',
|
||||
]);
|
||||
|
||||
$relationshipTypeB = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'nephew',
|
||||
'name_reverse_relationship' => 'uncle',
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/relationships', [
|
||||
'contact_is' => $contactA->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
|
||||
$this->assertDatabaseHas('relationships', [
|
||||
'account_id' => auth()->user()->account_id,
|
||||
'contact_is' => $contactA->id,
|
||||
'of_contact' => $contactB->id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('relationships', [
|
||||
'account_id' => auth()->user()->account_id,
|
||||
'contact_is' => $contactB->id,
|
||||
'of_contact' => $contactA->id,
|
||||
'relationship_type_id' => auth()->user()->account->getRelationshipTypeByType($relationshipType->name_reverse_relationship)->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_displays_a_relationship()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$contactB = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'uncle',
|
||||
'name_reverse_relationship' => 'nephew',
|
||||
]);
|
||||
|
||||
$relationshipTypeB = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'nephew',
|
||||
'name_reverse_relationship' => 'uncle',
|
||||
]);
|
||||
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'contact_is' => $contactA->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationships/'.$relationship->id);
|
||||
|
||||
$response->assertStatus(200)
|
||||
->assertJsonFragment([
|
||||
'id' => $relationship->id,
|
||||
'object' => 'relationship',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_relationship()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$contactB = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'uncle',
|
||||
'name_reverse_relationship' => 'nephew',
|
||||
]);
|
||||
|
||||
$relationshipTypeB = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'nephew',
|
||||
'name_reverse_relationship' => 'uncle',
|
||||
]);
|
||||
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'contact_is' => $contactA->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$relationshipB = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'relationship_type_id' => $relationshipTypeB->id,
|
||||
'contact_is' => $contactB->id,
|
||||
'of_contact' => $contactA->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/relationships/'.$relationship->id);
|
||||
|
||||
$response->assertStatus(200)
|
||||
->assertJson([
|
||||
'deleted' => true,
|
||||
'id' => $relationship->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('relationships', [
|
||||
'id' => $relationship->id,
|
||||
]);
|
||||
|
||||
$this->assertDatabaseMissing('relationships', [
|
||||
'id' => $relationshipB->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_rejects_the_delete_api_call_if_parameters_are_not_right()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
// make sure relationship id is valid
|
||||
$response = $this->json('DELETE', '/api/relationships/0');
|
||||
$this->expectDataError($response, ['The selected relationship id is invalid.']);
|
||||
|
||||
// make sure relationship id is an integer
|
||||
$response = $this->json('DELETE', '/api/relationships/x');
|
||||
$this->expectDataError($response, ['The relationship id must be an integer.']);
|
||||
|
||||
// make sure relationship id is with the right account
|
||||
$relationship = factory(Relationship::class)->create();
|
||||
$response = $this->json('DELETE', '/api/relationships/'.$relationship->id);
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_rejects_the_update_api_call_if_parameters_are_not_right()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$relationshipType = factory(RelationshipType::class)->create();
|
||||
|
||||
// make sure relationship type id is an integer
|
||||
$response = $this->json('PUT', '/api/relationships/'.$relationship->id, [
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_rejects_the_update_api_call_if_parameters_are_not_right2()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
// make sure relationship type id is an integer
|
||||
$response = $this->json('PUT', '/api/relationships/'.$relationship->id, [
|
||||
'relationship_type_id' => 'a',
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, ['The relationship type id must be an integer.']);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_the_update_if_relationship_type_id_is_invalid()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$relationshipType = factory(RelationshipType::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/api/relationships/'.$relationship->id, [
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_relationship()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$contactB = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'uncle',
|
||||
'name_reverse_relationship' => 'nephew',
|
||||
]);
|
||||
|
||||
$relationshipTypeC = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'fuckfriend',
|
||||
'name_reverse_relationship' => 'funnysituation',
|
||||
]);
|
||||
|
||||
$relationship = factory(Relationship::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'contact_is' => $contactA->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/relationships/'.$relationship->id, [
|
||||
'relationship_type_id' => $relationshipTypeC->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200)
|
||||
->assertJsonFragment([
|
||||
'id' => $relationshipTypeC->id,
|
||||
'name' => 'fuckfriend',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('relationships', [
|
||||
'id' => $relationship->id,
|
||||
'relationship_type_id' => $relationshipTypeC->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_displays_all_relationships_of_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactA = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$contactB = factory(Contact::class)->create(['account_id' => $user->account_id]);
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'uncle',
|
||||
'name_reverse_relationship' => 'nephew',
|
||||
]);
|
||||
|
||||
$relationshipTypeB = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'nephew',
|
||||
'name_reverse_relationship' => 'uncle',
|
||||
]);
|
||||
|
||||
$relationship = factory(Relationship::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'relationship_type_id' => $relationshipType->id,
|
||||
'contact_is' => $contactA->id,
|
||||
'of_contact' => $contactB->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contactA->id.'/relationships');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$decodedJson = $response->decodeResponseJson();
|
||||
|
||||
$this->assertCount(
|
||||
3,
|
||||
$decodedJson['data']
|
||||
);
|
||||
}
|
||||
}
|
||||
100
tests/Api/ApiRelationshipTypeControllerTest.php
Normal file
100
tests/Api/ApiRelationshipTypeControllerTest.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Relationship\RelationshipType;
|
||||
use App\Models\Relationship\RelationshipTypeGroup;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiRelationshipTypeControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_right_number_of_relationship_types()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(RelationshipType::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypes');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$decodedJson = $response->decodeResponseJson();
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$decodedJson['data']
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_list_of_relationship_types()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$relationshipTypeGroup = factory(RelationshipTypeGroup::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'father',
|
||||
'name_reverse_relationship' => 'son',
|
||||
'relationship_type_group_id' => $relationshipTypeGroup->id,
|
||||
'delible' => 0,
|
||||
]);
|
||||
$relationshipType2 = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'son',
|
||||
'name_reverse_relationship' => 'father',
|
||||
'relationship_type_group_id' => $relationshipTypeGroup->id,
|
||||
'delible' => 0,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypes');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $relationshipType2->id,
|
||||
'object' => 'relationshiptype',
|
||||
'name' => 'son',
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_specific_relationship_type_group()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$relationshipTypeGroup = factory(RelationshipTypeGroup::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$relationshipType = factory(RelationshipType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'father',
|
||||
'name_reverse_relationship' => 'son',
|
||||
'relationship_type_group_id' => $relationshipTypeGroup->id,
|
||||
'delible' => 0,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypes/'.$relationshipType->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $relationshipType->id,
|
||||
'object' => 'relationshiptype',
|
||||
'name' => 'father',
|
||||
'name_reverse_relationship' => 'son',
|
||||
'relationship_type_group_id' => $relationshipTypeGroup->id,
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
83
tests/Api/ApiRelationshipTypeGroupControllerTest.php
Normal file
83
tests/Api/ApiRelationshipTypeGroupControllerTest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Relationship\RelationshipTypeGroup;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiRelationshipTypeGroupControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_right_number_of_relationship_type_groups()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(RelationshipTypeGroup::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypegroups');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$decodedJson = $response->decodeResponseJson();
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$decodedJson['data']
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_list_of_relationship_type_groups()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(RelationshipTypeGroup::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'love',
|
||||
'delible' => 0,
|
||||
]);
|
||||
$relationshipTypeGroup2 = factory(RelationshipTypeGroup::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'hate',
|
||||
'delible' => 0,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypegroups');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $relationshipTypeGroup2->id,
|
||||
'object' => 'relationshiptypegroup',
|
||||
'name' => 'hate',
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_specific_relationship_type_group()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$relationshipTypeGroup = factory(RelationshipTypeGroup::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'love',
|
||||
'delible' => 0,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/relationshiptypegroups/'.$relationshipTypeGroup->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $relationshipTypeGroup->id,
|
||||
'object' => 'relationshiptypegroup',
|
||||
'name' => 'love',
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
409
tests/Api/ApiReminderControllerTest.php
Normal file
409
tests/Api/ApiReminderControllerTest.php
Normal file
@@ -0,0 +1,409 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\Reminder;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiReminderControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonReminder = [
|
||||
'id',
|
||||
'object',
|
||||
'initial_date',
|
||||
'title',
|
||||
'description',
|
||||
'frequency_type',
|
||||
'frequency_number',
|
||||
'delible',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_reminders()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder1 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder2 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'delible' => false,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/reminders');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonReminder],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder1->id,
|
||||
'delible' => true,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder2->id,
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_reminders_of_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder1 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder2 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/reminders');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonReminder],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_reminder_of_a_contact_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/reminders');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_reminder()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder1 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$reminder2 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/reminders/'.$reminder1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonReminder,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_reminder_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/reminders/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_reminder()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/reminders', [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01',
|
||||
'frequency_type' => 'one_time',
|
||||
'frequency_number' => 1,
|
||||
'description' => 'the description',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonReminder,
|
||||
]);
|
||||
$reminderId = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminderId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $reminderId);
|
||||
$this->assertDatabaseHas('reminders', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $reminderId,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01',
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => 'the description',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function create_reminders_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/reminders', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The initial date field is required.',
|
||||
'The frequency type field is required.',
|
||||
'The frequency number field is required.',
|
||||
'The title field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function reminders_create_error_bad_account()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/reminders', [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01',
|
||||
'frequency_type' => 'one_time',
|
||||
'frequency_number' => 1,
|
||||
'description' => 'the description',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_reminder()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/reminders/'.$reminder->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01',
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => 'the description',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonReminder,
|
||||
]);
|
||||
$reminder_id = $response->json('data.id');
|
||||
$this->assertEquals($reminder->id, $reminder_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'id' => $reminder_id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01T00:00:00Z',
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => 'the description',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $reminder_id);
|
||||
$this->assertDatabaseHas('reminders', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $reminder_id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01 00:00:00',
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => 'the description',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function updating_reminder_generates_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/reminders/'.$reminder->id, [
|
||||
'contact_id' => $reminder->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The initial date field is required.',
|
||||
'The frequency type field is required.',
|
||||
'The title field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function reminders_update_error_bad_account()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 7, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([]);
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $contact->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/reminders/'.$reminder->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the title',
|
||||
'initial_date' => '2018-05-01',
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => 'the description',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_reminder()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/reminders/'.$reminder->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('reminders', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $reminder->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function reminders_delete_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/reminders/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected reminder id is invalid.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_upcoming_reminders()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2017, 1, 1));
|
||||
|
||||
// add 2 reminders for the month of March
|
||||
$reminder1 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'initial_date' => '2017-03-03 00:00:00',
|
||||
]);
|
||||
$reminder1->schedule($user);
|
||||
|
||||
$reminder2 = factory(Reminder::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'initial_date' => '2017-03-03 00:00:00',
|
||||
'delible' => false,
|
||||
]);
|
||||
$reminder2->schedule($user);
|
||||
|
||||
$response = $this->json('GET', '/api/reminders/upcoming/2');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonReminder],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'reminder_id' => $reminder1->id,
|
||||
'delible' => true,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'reminder',
|
||||
'reminder_id' => $reminder2->id,
|
||||
'delible' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
48
tests/Api/ApiStatisticsControllerTest.php
Normal file
48
tests/Api/ApiStatisticsControllerTest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiStatisticsControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructure = [
|
||||
'instance_creation_date',
|
||||
'number_of_contacts',
|
||||
'number_of_users',
|
||||
'number_of_activities',
|
||||
'number_of_reminders',
|
||||
'number_of_new_users_last_week',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_right_structure_of_the_public_statistics()
|
||||
{
|
||||
config(['monica.allow_statistics_through_public_api_access' => true]);
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/statistics');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
$this->jsonStructure,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_returns_an_error_if_public_statistics_are_not_available()
|
||||
{
|
||||
config(['monica.allow_statistics_through_public_api_access' => false]);
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/statistics');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
406
tests/Api/ApiTagControllerTest.php
Normal file
406
tests/Api/ApiTagControllerTest.php
Normal file
@@ -0,0 +1,406 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Tag;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiTagControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonTag = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'name_slug',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected $jsonStructureContactWithContactFields = [
|
||||
'id',
|
||||
'object',
|
||||
'hash_id',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'gender',
|
||||
'gender_type',
|
||||
'is_starred',
|
||||
'is_partial',
|
||||
'is_dead',
|
||||
'last_called',
|
||||
'last_activity_together',
|
||||
'stay_in_touch_frequency',
|
||||
'stay_in_touch_trigger_date',
|
||||
'information' => [
|
||||
'relationships' => [
|
||||
'love' => [
|
||||
'total',
|
||||
'contacts',
|
||||
],
|
||||
'family' => [
|
||||
'total',
|
||||
'contacts',
|
||||
],
|
||||
'friend' => [
|
||||
'total',
|
||||
'contacts',
|
||||
],
|
||||
'work' => [
|
||||
'total',
|
||||
'contacts',
|
||||
],
|
||||
],
|
||||
'dates' => [
|
||||
'birthdate' => [
|
||||
'is_age_based',
|
||||
'is_year_unknown',
|
||||
'date',
|
||||
],
|
||||
'deceased_date' => [
|
||||
'is_age_based',
|
||||
'is_year_unknown',
|
||||
'date',
|
||||
],
|
||||
],
|
||||
'career' => [
|
||||
'job',
|
||||
'company',
|
||||
],
|
||||
'avatar' => [
|
||||
'url',
|
||||
'source',
|
||||
'default_avatar_color',
|
||||
],
|
||||
'food_preferences',
|
||||
'how_you_met' => [
|
||||
'general_information',
|
||||
'first_met_date' => [
|
||||
'is_age_based',
|
||||
'is_year_unknown',
|
||||
'date',
|
||||
],
|
||||
'first_met_through_contact',
|
||||
],
|
||||
],
|
||||
'addresses' => [],
|
||||
'tags' => [],
|
||||
'statistics' => [
|
||||
'number_of_calls',
|
||||
'number_of_notes',
|
||||
'number_of_activities',
|
||||
'number_of_reminders',
|
||||
'number_of_tasks',
|
||||
'number_of_gifts',
|
||||
'number_of_debts',
|
||||
],
|
||||
'contactFields' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'content',
|
||||
'contact_field_type' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'fontawesome_icon',
|
||||
'protocol',
|
||||
'delible',
|
||||
'type',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
],
|
||||
'notes' => [],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_get_all_tags()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$tag1 = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$tag2 = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/tags');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonTag,
|
||||
],
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'tag',
|
||||
'id' => $tag1->id,
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'tag',
|
||||
'id' => $tag2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_specific_tag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/tags/'.$tag->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTag,
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'tag',
|
||||
'id' => $tag->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_triggers_error_if_tag_unknown()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/tags/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_a_tag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/tags', [
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTag,
|
||||
]);
|
||||
$tag_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'tag',
|
||||
'id' => $tag_id,
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $tag_id);
|
||||
$this->assertDatabaseHas('tags', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $tag_id,
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_tag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/tags/'.$tag->id, [
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTag,
|
||||
]);
|
||||
|
||||
$tag_id = $response->json('data.id');
|
||||
$this->assertEquals($tag->id, $tag_id);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'tag',
|
||||
'id' => $tag_id,
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $tag_id);
|
||||
$this->assertDatabaseHas('tags', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $tag_id,
|
||||
'name' => 'the tag',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_tag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/tags/'.$tag->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('contact_tag', [
|
||||
'account_id' => $user->account_id,
|
||||
'tag_id' => $tag->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('tags', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $tag->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_tag_associated()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', "/api/contacts/{$contact1->id}/setTags", ['tags' => [$tag->name]]);
|
||||
$response = $this->json('POST', "/api/contacts/{$contact2->id}/setTags", ['tags' => [$tag->name]]);
|
||||
|
||||
$this->assertDatabaseHas('contact_tag', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
'tag_id' => $tag->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_tag', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'tag_id' => $tag->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/tags/'.$tag->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('contact_tag', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
'tag_id' => $tag->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('contact_tag', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'tag_id' => $tag->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('tags', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $tag->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_contacts_for_a_given_tag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
factory(Contact::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$contact->tags()->sync([
|
||||
$tag->id => [
|
||||
'account_id' => $user->account_id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
$response = $this->json('GET', '/api/tags/'.$tag->id.'/contacts');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonStructureContactWithContactFields],
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
3,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_contacts_for_a_given_tag_and_applies_pagination()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
factory(Contact::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$contact->tags()->sync([
|
||||
$tag->id => [
|
||||
'account_id' => $user->account_id,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
$response = $this->json('GET', '/api/tags/'.$tag->id.'/contacts?limit=1');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonStructureContactWithContactFields],
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 3,
|
||||
'current_page' => 1,
|
||||
'per_page' => 1,
|
||||
'last_page' => 3,
|
||||
]);
|
||||
}
|
||||
}
|
||||
369
tests/Api/ApiTaskControllerTest.php
Normal file
369
tests/Api/ApiTaskControllerTest.php
Normal file
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Task;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiTaskControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonTask = [
|
||||
'id',
|
||||
'object',
|
||||
'title',
|
||||
'description',
|
||||
'completed',
|
||||
'completed_at',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_tasks()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task1 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task2 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/tasks');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonTask],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $task1->id,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $task2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_tasks_of_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task1 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task2 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/tasks');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonTask],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $task1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'task',
|
||||
'id' => $task2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_the_tasks_of_a_contact_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/tasks');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_specific_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task1 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$task2 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/tasks/'.$task1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTask,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $task1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'task',
|
||||
'id' => $task2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_get_a_task_with_an_invalid_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/tasks/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_create_a_task_associated_to_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/tasks', [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the task',
|
||||
'description' => 'description',
|
||||
'completed' => false,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTask,
|
||||
]);
|
||||
$taskId = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $taskId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $taskId);
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $taskId,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_create_a_task_not_associated_to_a_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/tasks', [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the task',
|
||||
'description' => 'description',
|
||||
'completed' => false,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTask,
|
||||
]);
|
||||
$taskId = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $taskId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $taskId);
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $taskId,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function creating_a_task_triggers_invalid_parameter_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/tasks', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The title field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function creating_a_task_with_a_wrong_account_id_triggers_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/tasks', [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_updates_a_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/tasks/'.$task->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonTask,
|
||||
]);
|
||||
$taskId = $response->json('data.id');
|
||||
$this->assertEquals($task->id, $taskId);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'task',
|
||||
'id' => $taskId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $taskId);
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $taskId,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function updating_a_task_with_missing_parameters_triggers_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/tasks/'.$task->id, [
|
||||
'contact_id' => $task->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The title field is required.',
|
||||
'The completed field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function updating_a_task_with_wrong_account_triggers_an_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([]);
|
||||
|
||||
$response = $this->json('PUT', '/api/tasks/'.$task->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'title' => 'the task',
|
||||
'completed' => false,
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/tasks/'.$task->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $task->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_cant_delete_a_task_if_wrong_task_id()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/tasks/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
19
tests/Api/Authentication/ApiAuthenticateTest.php
Normal file
19
tests/Api/Authentication/ApiAuthenticateTest.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Authentication;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
|
||||
class ApiAuthenticateTest extends ApiTestCase
|
||||
{
|
||||
/** @test */
|
||||
public function guest_is_rejected()
|
||||
{
|
||||
$response = $this->json('GET', '/api/contacts');
|
||||
|
||||
$response->assertStatus(401);
|
||||
$response->assertJsonFragment([
|
||||
'message' => 'Unauthenticated.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
340
tests/Api/Contact/ApiAdressesControllerTest.php
Normal file
340
tests/Api/Contact/ApiAdressesControllerTest.php
Normal 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.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
59
tests/Api/Contact/ApiAuditLogControllerTest.php
Normal file
59
tests/Api/Contact/ApiAuditLogControllerTest.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
180
tests/Api/Contact/ApiAvatarControllerTest.php
Normal file
180
tests/Api/Contact/ApiAvatarControllerTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
352
tests/Api/Contact/ApiCallControllerTest.php
Normal file
352
tests/Api/Contact/ApiCallControllerTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
1694
tests/Api/Contact/ApiContactControllerTest.php
Normal file
1694
tests/Api/Contact/ApiContactControllerTest.php
Normal file
File diff suppressed because it is too large
Load Diff
289
tests/Api/Contact/ApiContactTagControllerTest.php
Normal file
289
tests/Api/Contact/ApiContactTagControllerTest.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
208
tests/Api/Contact/ApiConversationControllerTest.php
Normal file
208
tests/Api/Contact/ApiConversationControllerTest.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
256
tests/Api/Contact/ApiDocumentControllerTest.php
Normal file
256
tests/Api/Contact/ApiDocumentControllerTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
340
tests/Api/Contact/ApiLifeEventControllerTest.php
Normal file
340
tests/Api/Contact/ApiLifeEventControllerTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
73
tests/Api/Contact/ApiMeControllerTest.php
Normal file
73
tests/Api/Contact/ApiMeControllerTest.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
127
tests/Api/Contact/ApiMessageControllerTest.php
Normal file
127
tests/Api/Contact/ApiMessageControllerTest.php
Normal 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,
|
||||
]);
|
||||
}
|
||||
}
|
||||
228
tests/Api/Contact/ApiOccupationControllerTest.php
Normal file
228
tests/Api/Contact/ApiOccupationControllerTest.php
Normal 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.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
294
tests/Api/Contact/ApiPhotoControllerTest.php
Normal file
294
tests/Api/Contact/ApiPhotoControllerTest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
311
tests/Api/ContactField/ApiContactFieldControllerTest.php
Normal file
311
tests/Api/ContactField/ApiContactFieldControllerTest.php
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\ContactField;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\ContactField;
|
||||
use App\Models\Contact\ContactFieldType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiContactFieldControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonContactField = [
|
||||
'id',
|
||||
'object',
|
||||
'content',
|
||||
'contact_field_type',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'contact',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_get_contact_all()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactField1 = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactField2 = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/'.$contact1->id.'/contactfields');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonContactField],
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_get_contact_all_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contacts/0/contactfields');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_get_one()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactField1 = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
$contactField2 = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact1->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contactfields/'.$contactField1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactField,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_get_one_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contactfields/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_create()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/contactfields', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactField,
|
||||
]);
|
||||
$contactField_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $contactField_id);
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $contactField_id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_create_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/contactfields', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The contact field type id field is required.',
|
||||
'The data field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_create_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/api/contactfields', [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfields/'.$contactField->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $contactField->contact_field_type_id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactField,
|
||||
]);
|
||||
$contactField_id = $response->json('data.id');
|
||||
$this->assertEquals($contactField->id, $contactField_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfield',
|
||||
'id' => $contactField_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $contactField_id);
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $contactField_id,
|
||||
'contact_field_type_id' => $contactField->contact_field_type_id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_update_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfields/'.$contactField->id, [
|
||||
'contact_id' => $contactField->contact_id,
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The contact field type id field is required.',
|
||||
'The data field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_update_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfields/'.$contactField->id, [
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $contactField->contact_field_type_id,
|
||||
'data' => 'ok',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $contactField->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/contactfields/'.$contactField->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('contact_fields', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => $contactField->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_fields_delete_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/contactfields/0');
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The selected contact field id is invalid.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
223
tests/Api/ContactField/ApiContactFieldTypeControllerTest.php
Normal file
223
tests/Api/ContactField/ApiContactFieldTypeControllerTest.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\ContactField;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\ContactFieldType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiContactFieldTypeControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonContactFieldType = [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'protocol',
|
||||
'delible',
|
||||
'type',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_get_one()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactFieldType1 = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contactFieldType2 = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/contactfieldtypes/'.$contactFieldType1->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactFieldType,
|
||||
]);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfieldtype',
|
||||
'id' => $contactFieldType1->id,
|
||||
]);
|
||||
$response->assertJsonMissingExact([
|
||||
'object' => 'contactfieldtype',
|
||||
'id' => $contactFieldType2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_get_one_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('GET', '/api/contactfieldtypes/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_create()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/contactfieldtypes', [
|
||||
'name' => 'Email',
|
||||
'protocol' => 'mailto:',
|
||||
'type' => 'email',
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactFieldType,
|
||||
]);
|
||||
$contactFieldTypeId = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfieldtype',
|
||||
'id' => $contactFieldTypeId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $contactFieldTypeId);
|
||||
$this->assertDatabaseHas('contact_field_types', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $contactFieldTypeId,
|
||||
'name' => 'Email',
|
||||
'protocol' => 'mailto:',
|
||||
'type' => 'email',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_create_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/api/contactfieldtypes', [
|
||||
]);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The name field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfieldtypes/'.$contactFieldType->id, [
|
||||
'name' => 'Email2',
|
||||
'protocol' => 'mailto:',
|
||||
'type' => 'email',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonContactFieldType,
|
||||
]);
|
||||
$contactFieldTypeId = $response->json('data.id');
|
||||
$this->assertEquals($contactFieldType->id, $contactFieldTypeId);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'contactfieldtype',
|
||||
'id' => $contactFieldTypeId,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $contactFieldTypeId);
|
||||
$this->assertDatabaseHas('contact_field_types', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $contactFieldType->id,
|
||||
'name' => 'Email2',
|
||||
'protocol' => 'mailto:',
|
||||
'type' => 'email',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_update_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfieldtypes/'.$contactFieldType->id, []);
|
||||
|
||||
$this->expectDataError($response, [
|
||||
'The name field is required.',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_update_error_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/api/contactfieldtypes/'.$contactFieldType->id, [
|
||||
'name' => 'Email2',
|
||||
'protocol' => 'mailto:',
|
||||
'type' => 'email',
|
||||
]);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_field_types', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $contactFieldType->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/contactfieldtypes/'.$contactFieldType->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('contact_field_types', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $contactFieldType->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_delete_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/api/contactfieldtypes/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function contact_field_type_delete_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/api/contactfieldtypes/'.$contactFieldType->id);
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
294
tests/Api/DAV/CalDAVBirthdaysTest.php
Normal file
294
tests/Api/DAV/CalDAVBirthdaysTest.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\User\SyncToken;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CalDAVBirthdaysTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_birthdays_propfind()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/birthdays");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/birthdays/</d:href>", false);
|
||||
$specialDate->refresh();
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_propfind_with_props()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => 0,
|
||||
],
|
||||
'<d:propfind xmlns:d="DAV:">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
</d:prop>
|
||||
</d:propfind>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
'<d:displayname>Birthdays</d:displayname>'.
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_birthdays_propfind_one_birthday()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_getctag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/' xmlns:s='http://sabredav.org/ns'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
<s:sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'birthdays',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
"<s:sync-token>http://sabre.io/ns/sync/{$token->id}</s:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_getctag_birthday()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '0',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/' xmlns:s='http://sabredav.org/ns'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
<s:sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'birthdays',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
"<s:sync-token>http://sabre.io/ns/sync/{$token->id}</s:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_sync_collection_with_token()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 9, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 8, 0, 0));
|
||||
$token = factory(SyncToken::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'birthdays',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token>http://sabre.io/ns/sync/{$token->id}</sync-token>
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
|
||||
$token = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'birthdays',
|
||||
])
|
||||
->orderBy('created_at')
|
||||
->get()
|
||||
->last();
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($specialDate)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_sync_collection_init()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token />
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'birthdays',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($specialDate)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
}
|
||||
303
tests/Api/DAV/CalDAVTasksTest.php
Normal file
303
tests/Api/DAV/CalDAVTasksTest.php
Normal file
@@ -0,0 +1,303 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Contact\Task;
|
||||
use App\Models\User\SyncToken;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CalDAVTasksTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_tasks_propfind()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => null,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/tasks");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/tasks/</d:href>", false);
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_propfind_with_props()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => 0,
|
||||
],
|
||||
'<d:propfind xmlns:d="DAV:">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
</d:prop>
|
||||
</d:propfind>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
'<d:displayname>Tasks</d:displayname>'.
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_tasks_propfind_one_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_getctag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/' xmlns:s='http://sabredav.org/ns'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
<s:sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'tasks',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
"<s:sync-token>http://sabre.io/ns/sync/{$token->id}</s:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_getctag_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '0',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/' xmlns:s='http://sabredav.org/ns'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
<s:sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'tasks',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
"<s:sync-token>http://sabre.io/ns/sync/{$token->id}</s:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_sync_collection_with_token()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 9, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 8, 0, 0));
|
||||
$token = factory(SyncToken::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'tasks',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token>http://sabre.io/ns/sync/{$token->id}</sync-token>
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
$response->assertStatus(207);
|
||||
|
||||
$token = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'tasks',
|
||||
])
|
||||
->orderBy('created_at')
|
||||
->get()
|
||||
->last();
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($task)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_sync_collection_init()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token />
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'tasks',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($task)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
}
|
||||
451
tests/Api/DAV/CardDAVTest.php
Normal file
451
tests/Api/DAV/CardDAVTest.php
Normal file
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\User\SyncToken;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CardDAVTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_addressbooks()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav/addressbooks');
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:response><d:href>/dav/addressbooks/</d:href>', false);
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_addressbooks_user()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/</d:href>", false);
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_contacts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/contacts");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>", false);
|
||||
$contactId = urlencode($contact->uuid);
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/contacts/{$contactId}.vcf</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_carddav_propfind_contacts_with_props()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => 0,
|
||||
],
|
||||
'<d:propfind xmlns:d="DAV:">
|
||||
<d:prop>
|
||||
<d:displayname />
|
||||
</d:prop>
|
||||
</d:propfind>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
'<d:displayname>Contacts</d:displayname>'.
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_one_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_one_contact_without_extension()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}</d:href>", false);
|
||||
}
|
||||
|
||||
public function test_carddav_getctag()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_carddav_get_me_card()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$user->me_contact_id = $contact->id;
|
||||
$user->save();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/'>
|
||||
<prop>
|
||||
<cs:me-card />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:me-card>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</cs:me-card>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_carddav_set_me_card()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPPATCH', "/dav/addressbooks/{$user->email}/contacts", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propertyupdate xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/'>
|
||||
<set>
|
||||
<prop>
|
||||
<cs:me-card>
|
||||
<href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</href>
|
||||
</cs:me-card>
|
||||
</prop>
|
||||
</set>
|
||||
</propertyupdate>"
|
||||
);
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
'<cs:me-card/>'.
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'id' => $user->id,
|
||||
'me_contact_id' => $contact->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_carddav_getctag_contacts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '0',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<propfind xmlns='DAV:' xmlns:cs='http://calendarserver.org/ns/'>
|
||||
<prop>
|
||||
<cs:getctag />
|
||||
<sync-token />
|
||||
</prop>
|
||||
</propfind>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">', false);
|
||||
$response->assertSee('<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<cs:getctag>http://sabre.io/ns/sync/{$token->id}</cs:getctag>".
|
||||
"<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
}
|
||||
|
||||
public function test_carddav_sync_collection_with_token()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 9, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2018, 1, 1, 8, 0, 0));
|
||||
$token = factory(SyncToken::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token>http://sabre.io/ns/sync/{$token->id}</sync-token>
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
|
||||
$token = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
])
|
||||
->orderBy('created_at')
|
||||
->get()
|
||||
->last();
|
||||
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($contact)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
|
||||
public function test_carddav_sync_collection_init()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token />
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$tokens = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
])->orderBy('created_at')->get();
|
||||
|
||||
$this->assertGreaterThan(0, $tokens->count());
|
||||
$token = $tokens->last();
|
||||
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>
|
||||
<d:propstat>
|
||||
<d:prop>
|
||||
<d:getetag>"{$this->getEtag($contact)}"</d:getetag>
|
||||
</d:prop>
|
||||
<d:status>HTTP/1.1 200 OK</d:status>
|
||||
</d:propstat>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
|
||||
public function test_carddav_sync_collection_deleted_contact()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 1, 1, 9, 0, 0));
|
||||
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'deleted_at' => Carbon::create(2019, 3, 1, 9, 0, 0),
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 2, 1, 9, 0, 0));
|
||||
$token = factory(SyncToken::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 4, 1, 9, 0, 0));
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<sync-collection xmlns='DAV:'>
|
||||
<sync-token>http://sabre.io/ns/sync/{$token->id}</sync-token>
|
||||
<sync-level>1</sync-level>
|
||||
<prop>
|
||||
<getetag />
|
||||
</prop>
|
||||
</sync-collection>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
|
||||
$token = SyncToken::where([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
])
|
||||
->orderBy('created_at')
|
||||
->get()
|
||||
->last();
|
||||
|
||||
$response->assertSee("<d:multistatus xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\" xmlns:cs=\"http://calendarserver.org/ns/\">
|
||||
<d:response>
|
||||
<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>
|
||||
<d:status>HTTP/1.1 404 Not Found</d:status>
|
||||
</d:response>
|
||||
<d:sync-token>http://sabre.io/ns/sync/{$token->id}</d:sync-token>
|
||||
</d:multistatus>", false);
|
||||
}
|
||||
}
|
||||
176
tests/Api/DAV/CardEtag.php
Normal file
176
tests/Api/DAV/CardEtag.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use App\Models\Contact\Task;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Instance\SpecialDate;
|
||||
use App\Models\Contact\ContactFieldType;
|
||||
|
||||
trait CardEtag
|
||||
{
|
||||
protected function getEtag($obj, bool $quotes = false)
|
||||
{
|
||||
$data = '';
|
||||
if ($obj instanceof Contact) {
|
||||
$data = $this->getCard($obj, true);
|
||||
} elseif ($obj instanceof SpecialDate) {
|
||||
$data = $this->getCal($obj, true);
|
||||
} elseif ($obj instanceof Task) {
|
||||
$data = $this->getVTodo($obj, true);
|
||||
}
|
||||
|
||||
$etag = sha1($data);
|
||||
if ($quotes) {
|
||||
$etag = '"'.$etag.'"';
|
||||
}
|
||||
|
||||
return $etag;
|
||||
}
|
||||
|
||||
protected function getCard(Contact $contact, bool $realFormat = false): string
|
||||
{
|
||||
$contact = $contact->refresh();
|
||||
$url = route('people.show', $contact);
|
||||
$sabreversion = \Sabre\VObject\Version::VERSION;
|
||||
$timestamp = $contact->updated_at->format('Ymd\THis\Z');
|
||||
|
||||
$data = "BEGIN:VCARD
|
||||
VERSION:4.0
|
||||
PRODID:-//Sabre//Sabre VObject {$sabreversion}//EN
|
||||
UID:{$contact->uuid}
|
||||
SOURCE:{$url}
|
||||
FN:{$contact->name}
|
||||
N:{$contact->last_name};{$contact->first_name};{$contact->middle_name};;
|
||||
";
|
||||
|
||||
if ($contact->gender) {
|
||||
$data .= "GENDER:{$contact->gender->type}";
|
||||
$data .= "\n";
|
||||
}
|
||||
|
||||
$picture = $contact->getAvatarURL();
|
||||
if (! empty($picture)) {
|
||||
$data .= "PHOTO;VALUE=URI:{$picture}\n";
|
||||
}
|
||||
|
||||
foreach ($contact->addresses as $address) {
|
||||
$data .= 'ADR:;;';
|
||||
$data .= $address->place->street.';';
|
||||
$data .= $address->place->city.';';
|
||||
$data .= $address->place->province.';';
|
||||
$data .= $address->place->postal_code.';';
|
||||
$data .= $address->place->country;
|
||||
$data .= "\n";
|
||||
}
|
||||
foreach ($contact->contactFields as $contactField) {
|
||||
$type = '';
|
||||
if ($contactField->labels->count() > 0) {
|
||||
$type = ';TYPE='.$contactField->labels->map(function ($label) {
|
||||
return $label->label_i18n ?: $label->label;
|
||||
})->join(',');
|
||||
}
|
||||
switch ($contactField->contactFieldType->type) {
|
||||
case ContactFieldType::PHONE:
|
||||
$data .= "TEL$type:{$contactField->data}\n";
|
||||
break;
|
||||
case ContactFieldType::EMAIL:
|
||||
$data .= "EMAIL$type:{$contactField->data}\n";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data .= "REV:{$timestamp}\n";
|
||||
$tags = $contact->getTagsAsString();
|
||||
if (! empty($tags)) {
|
||||
$data .= "CATEGORIES:{$tags}\n";
|
||||
}
|
||||
$data .= "END:VCARD\n";
|
||||
|
||||
if ($realFormat) {
|
||||
$data = mb_ereg_replace("\n", "\r\n", $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getCal(SpecialDate $specialDate, bool $realFormat = false): string
|
||||
{
|
||||
$contact = $specialDate->contact;
|
||||
$url = route('people.show', $contact);
|
||||
$description = "See {$contact->name}’s profile: {$url}";
|
||||
$description1 = mb_substr($description, 0, 61);
|
||||
$description2 = mb_substr($description, 61);
|
||||
|
||||
$sabreversion = \Sabre\VObject\Version::VERSION;
|
||||
$timestamp = $specialDate->created_at->format('Ymd\THis\Z');
|
||||
|
||||
$start = $specialDate->date->format('Ymd');
|
||||
$end = $specialDate->date->addDays(1)->format('Ymd');
|
||||
|
||||
$data = "BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Sabre//Sabre VObject {$sabreversion}//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:UTC
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:{$specialDate->uuid}
|
||||
DTSTART;VALUE=DATE:{$start}
|
||||
DTEND;VALUE=DATE:{$end}
|
||||
RRULE:FREQ=YEARLY
|
||||
DTSTAMP:{$timestamp}
|
||||
CREATED:{$timestamp}
|
||||
SUMMARY:Birthday of {$contact->name}
|
||||
ATTACH:{$url}
|
||||
DESCRIPTION:{$description1}
|
||||
{$description2}
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
";
|
||||
|
||||
if ($realFormat) {
|
||||
$data = mb_ereg_replace("\n", "\r\n", $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getVTodo(Task $task, bool $realFormat = false): string
|
||||
{
|
||||
$sabreversion = \Sabre\VObject\Version::VERSION;
|
||||
$timestamp = $task->created_at->format('Ymd\THis\Z');
|
||||
$contact = $task->contact;
|
||||
|
||||
$data = "BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Sabre//Sabre VObject {$sabreversion}//EN
|
||||
CALSCALE:GREGORIAN
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:UTC
|
||||
END:VTIMEZONE
|
||||
BEGIN:VTODO
|
||||
UID:{$task->uuid}
|
||||
SUMMARY:{$task->title}
|
||||
DTSTAMP:{$timestamp}
|
||||
CREATED:{$timestamp}
|
||||
DESCRIPTION:{$task->description}
|
||||
";
|
||||
if ($contact) {
|
||||
$url = route('people.show', $contact);
|
||||
$data .= "ATTACH:{$url}
|
||||
";
|
||||
}
|
||||
$data .= 'END:VTODO
|
||||
END:VCALENDAR
|
||||
';
|
||||
|
||||
if ($realFormat) {
|
||||
$data = mb_ereg_replace("\n", "\r\n", $data);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
218
tests/Api/DAV/DAVServerTest.php
Normal file
218
tests/Api/DAV/DAVServerTest.php
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class DAVServerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_propfind_base()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav');
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:response><d:href>/dav/</d:href>', false);
|
||||
$response->assertSee('<d:response><d:href>/dav/principals/</d:href>', false);
|
||||
$response->assertSee('<d:response><d:href>/dav/addressbooks/</d:href>', false);
|
||||
$response->assertSee('<d:response><d:href>/dav/calendars/</d:href>', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_propfind_principals()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav/principals');
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:response><d:href>/dav/principals/</d:href>', false);
|
||||
$response->assertSee("<d:response><d:href>/dav/principals/{$user->email}/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_propfind_principals_user()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/principals/{$user->email}");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/principals/{$user->email}/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_ensure_browser_plugin_not_enabled()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('GET', '/dav');
|
||||
|
||||
$response->assertStatus(302);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeader('Location', route('settings.dav'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_propfind_groupmemberset()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/principals/{$user->email}/", [], [], [],
|
||||
[
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
'<propfind xmlns="DAV:"
|
||||
xmlns:CAL="urn:ietf:params:xml:ns:caldav"
|
||||
xmlns:CARD="urn:ietf:params:xml:ns:carddav">
|
||||
<prop>
|
||||
<CARD:addressbook-home-set />
|
||||
<group-member-set />
|
||||
</prop>
|
||||
</propfind>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/principals/{$user->email}/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
'<card:addressbook-home-set>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/</d:href>".
|
||||
'</card:addressbook-home-set>'.
|
||||
'<d:group-member-set>'.
|
||||
"<d:href>/dav/principals/{$user->email}/</d:href>".
|
||||
'</d:group-member-set>'.
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_report_propertysearch()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('REPORT', '/dav/principals/', [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '0',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"<principal-property-search xmlns=\"DAV:\">
|
||||
<property-search>
|
||||
<match>{$user->name}</match>
|
||||
<prop>
|
||||
<displayname/>
|
||||
</prop>
|
||||
</property-search>
|
||||
<prop>
|
||||
<displayname/>
|
||||
</prop>
|
||||
</principal-property-search>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/principals/{$user->email}/</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:displayname>{$user->name}</d:displayname>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_propfind()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav/calendars');
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:response><d:href>/dav/calendars/</d:href>', false);
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_propfind_calendars_user()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PROPFIND', "/dav/calendars/{$user->email}");
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/</d:href>", false);
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/birthdays/</d:href>", false);
|
||||
$response->assertSee("<d:response><d:href>/dav/calendars/{$user->email}/tasks/</d:href>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_limit_users_unauthorized()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
config(['laravelsabre.users' => 'unauthorized']);
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav');
|
||||
|
||||
$response->assertStatus(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_dav_limit_users_authorized()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
config(['laravelsabre.users' => $user->email]);
|
||||
|
||||
$response = $this->call('PROPFIND', '/dav');
|
||||
|
||||
$response->assertStatus(207);
|
||||
}
|
||||
}
|
||||
494
tests/Api/DAV/VCardContactTest.php
Normal file
494
tests/Api/DAV/VCardContactTest.php
Normal file
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Account\Photo;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Sabre\VObject\PHPUnitAssertions;
|
||||
use Intervention\Image\Facades\Image;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class VCardContactTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag, PHPUnitAssertions;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_get_one_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->get("/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf", [
|
||||
'HTTP_ACCEPT' => 'text/vcard; version=4.0',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$this->assertVObjectEqualsVObject($this->getCard($contact, true), $response->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_put_one_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/single_vcard_stub.vcf", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doe\nN:Doe;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_put_one_contact_with_photo()
|
||||
{
|
||||
Storage::fake();
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$image = Image::canvas(1, 1, '#fff')->encode('data-url');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/single_vcard_stub.vcf", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doe\nN:Doe;John;;;\nPHOTO:$image\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
$this->assertDatabaseHas('photos', [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$photo = Photo::where(['account_id' => $user->account_id])->first();
|
||||
|
||||
Storage::disk('public')->assertExists($photo->new_filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_put_one_contact_with_photo_already_set()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$photo = factory(Photo::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
UploadedFile::fake()->image('file.jpg')->storeAs('', 'file.jpg');
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'avatar_source' => 'photo',
|
||||
'avatar_photo_id' => $photo->id,
|
||||
'uuid' => Str::uuid()->toString(),
|
||||
]);
|
||||
|
||||
$image = Image::canvas(1, 1, '#fff')->encode('data-url');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doe\nN:Doe;John;;;\nPHOTO:$image\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
'avatar_photo_id' => $photo->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_put_one_contact_with_photo_and_attributes()
|
||||
{
|
||||
Storage::fake();
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$image = base64_encode(Image::canvas(1, 1, '#fff')->encode('jpg'));
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/single_vcard_stub.vcf", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCARD\nVERSION:3.0\nFN:John Doe\nN:Doe;John;;;\nPHOTO;ENCODING=B;TYPE=JPEG:$image\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
$this->assertDatabaseHas('photos', [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$photo = Photo::where(['account_id' => $user->account_id])->first();
|
||||
|
||||
Storage::disk('public')->assertExists($photo->new_filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doex\nN:Doex;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doex',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact_if_modified()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$filename = urlencode($contact->uuid.'.vcf');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$filename}", [], [], [],
|
||||
[
|
||||
'HTTP_If-Modified-Since' => $contact->updated_at->addDays(-1)->toRfc7231String(),
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doex\nN:Doex;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doex',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact_if_modified_not_modified()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$filename = urlencode($contact->uuid.'.vcf');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$filename}", [], [], [],
|
||||
[
|
||||
'HTTP_If-Modified-Since' => $contact->updated_at->addDays(1)->toRfc7231String(),
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doex\nN:Doex;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
// Not modified
|
||||
$response->assertStatus(304);
|
||||
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
// see http://tools.ietf.org/html/rfc2616#section-10.3.5
|
||||
$response->assertHeaderMissing('Last-Modified');
|
||||
|
||||
$response->assertHeaderMissing('ETag');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact_if_unmodified()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$filename = urlencode($contact->uuid.'.vcf');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$filename}", [], [], [],
|
||||
[
|
||||
'HTTP_If-Unmodified-Since' => $contact->updated_at->addDays(1)->toRfc7231String(),
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doex\nN:Doex;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doex',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact_if_unmodified_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$filename = urlencode($contact->uuid.'.vcf');
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$filename}", [], [], [],
|
||||
[
|
||||
'HTTP_If-Unmodified-Since' => $contact->updated_at->addDays(-1)->toRfc7231String(),
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
"BEGIN:VCARD\nVERSION:4.0\nFN:John Doex\nN:Doex;John;;;\nEND:VCARD"
|
||||
);
|
||||
|
||||
// PRECONDITION FAILED
|
||||
$response->assertStatus(412);
|
||||
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$sabreversion = \Sabre\DAV\Version::VERSION;
|
||||
$response->assertSee("<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">
|
||||
<s:sabredav-version>{$sabreversion}</s:sabredav-version>
|
||||
<s:exception>Sabre\DAV\Exception\PreconditionFailed</s:exception>
|
||||
<s:message>An If-Unmodified-Since header was specified, but the entity has been changed since the specified date.</s:message>", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_carddav_update_existing_contact_no_modify()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$filename = urlencode($contact->uuid.'.vcf');
|
||||
|
||||
$response = $this->get("/dav/addressbooks/{$user->email}/contacts/{$filename}");
|
||||
$data = $response->getContent();
|
||||
|
||||
$response = $this->call('PUT', "/dav/addressbooks/{$user->email}/contacts/{$filename}", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
$data
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
//$response->assertHeader('ETag'); // etag no more sent
|
||||
}
|
||||
|
||||
public function test_carddav_contacts_report_version4()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
'<card:addressbook-query xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<card:address-data content-type="text/vcard" version="4.0" />
|
||||
</d:prop>
|
||||
</card:addressbook-query>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$vcard = mb_ereg_replace("\n", " \n", $this->getCard($contact));
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($contact)}"</d:getetag>".
|
||||
"<card:address-data>{$vcard}</card:address-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
public function test_carddav_contacts_report_version3()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
'<card:addressbook-query xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<card:address-data content-type="text/vcard" version="3.0" />
|
||||
</d:prop>
|
||||
</card:addressbook-query>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$vcard = mb_ereg_replace('VERSION:4.0', 'VERSION:3.0', $this->getCard($contact));
|
||||
$vcard = mb_ereg_replace("\n", " \n", $vcard);
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($contact)}"</d:getetag>".
|
||||
"<card:address-data>{$vcard}</card:address-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
public function test_carddav_contacts_report_multiget()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/addressbooks/{$user->email}/contacts/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
],
|
||||
"<card:addressbook-multiget xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<card:address-data content-type=\"text/vcard\" version=\"4.0\" />
|
||||
</d:prop>
|
||||
<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact1->uuid}.vcf</d:href>
|
||||
<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact2->uuid}.vcf</d:href>
|
||||
</card:addressbook-multiget>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$vcard1 = mb_ereg_replace("\n", " \n", $this->getCard($contact1));
|
||||
$vcard2 = mb_ereg_replace("\n", " \n", $this->getCard($contact2));
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact1->uuid}.vcf</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($contact1)}"</d:getetag>".
|
||||
"<card:address-data>{$vcard1}</card:address-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
$response->assertSee(
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/addressbooks/{$user->email}/contacts/{$contact2->uuid}.vcf</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($contact2)}"</d:getetag>".
|
||||
"<card:address-data>{$vcard2}</card:address-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
* @test
|
||||
*/
|
||||
public function carddav_delete_one_contact()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->call('DELETE', "/dav/addressbooks/{$user->email}/contacts/{$contact->uuid}.vcf");
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseMissing('contacts', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $contact->id,
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
138
tests/Api/DAV/VEventBirthdayTest.php
Normal file
138
tests/Api/DAV/VEventBirthdayTest.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Contact\Contact;
|
||||
use Sabre\VObject\PHPUnitAssertions;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class VEventBirthdayTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag, PHPUnitAssertions;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_get_one_birthday()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->get("/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$this->assertVObjectEqualsVObject($this->getCal($specialDate, true), $response->getContent() ?: $response->streamedContent());
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_report()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate = $contact->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate->uuid = Str::uuid();
|
||||
$specialDate->save();
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
'<cal:calendar-query xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<cal:calendar-data content-type="text/calendar" version="2.0" />
|
||||
</d:prop>
|
||||
<cal:filter>
|
||||
<cal:comp-filter name="VCALENDAR" />
|
||||
</cal:filter>
|
||||
</cal:calendar-query>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($specialDate)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getCal($specialDate)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_birthdays_report_multiget()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact1 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$specialDate1 = $contact1->setSpecialDate('birthdate', 1983, 03, 04);
|
||||
$specialDate1->uuid = Str::uuid();
|
||||
$specialDate1->save();
|
||||
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'firstname' => 'Jane',
|
||||
]);
|
||||
$specialDate2 = $contact2->setSpecialDate('birthdate', 1980, 05, 01);
|
||||
$specialDate2->uuid = Str::uuid();
|
||||
$specialDate2->save();
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/birthdays/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
],
|
||||
"<cal:calendar-multiget xmlns:d=\"DAV:\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<cal:calendar-data content-type=\"text/calendar\" version=\"2.0\" />
|
||||
</d:prop>
|
||||
<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate1->uuid}.ics</d:href>
|
||||
<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate2->uuid}.ics</d:href>
|
||||
</cal:calendar-multiget>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate1->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($specialDate1)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getCal($specialDate1)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
$response->assertSee(
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/birthdays/{$specialDate2->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($specialDate2)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getCal($specialDate2)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
}
|
||||
244
tests/Api/DAV/VTodoTaskTest.php
Normal file
244
tests/Api/DAV/VTodoTaskTest.php
Normal file
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\DAV;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\ApiTestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\Contact\Task;
|
||||
use App\Models\Contact\Contact;
|
||||
use Sabre\VObject\PHPUnitAssertions;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class VTodoTaskTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions, CardEtag, PHPUnitAssertions;
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_get_one_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => null,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->get("/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$this->assertVObjectEqualsVObject($this->getVTodo($task, true), $response->getContent() ?: $response->streamedContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_put_one_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$uuid = Str::uuid();
|
||||
|
||||
$response = $this->call('PUT', "/dav/calendars/{$user->email}/tasks/{$uuid->toString()}.ics", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCALENDAR
|
||||
BEGIN:VTODO
|
||||
UID:{$uuid->toString()}
|
||||
SUMMARY:title
|
||||
DESCRIPTION:description
|
||||
END:VTODO
|
||||
END:VCALENDAR
|
||||
"
|
||||
);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => null,
|
||||
'uuid' => $uuid,
|
||||
'title' => 'title',
|
||||
'description' => 'description',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_update_existing_task()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => null,
|
||||
]);
|
||||
|
||||
$response = $this->call('PUT', "/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCALENDAR
|
||||
BEGIN:VTODO
|
||||
UID:{$task->uuid}
|
||||
SUMMARY:new title
|
||||
DESCRIPTION:new description
|
||||
END:VTODO
|
||||
END:VCALENDAR
|
||||
"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'uuid' => $task->uuid,
|
||||
'title' => 'new title',
|
||||
'description' => 'new description',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group dav
|
||||
*/
|
||||
public function test_caldav_update_task_complete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => null,
|
||||
]);
|
||||
|
||||
$response = $this->call('PUT', "/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics", [], [], [],
|
||||
['content-type' => 'application/xml; charset=utf-8'],
|
||||
"BEGIN:VCALENDAR
|
||||
BEGIN:VTODO
|
||||
UID:{$task->uuid}
|
||||
SUMMARY:{$task->title}
|
||||
DESCRIPTION:{$task->description}
|
||||
STATUS:COMPLETED
|
||||
COMPLETED:20190121T182800Z
|
||||
END:VTODO
|
||||
END:VCALENDAR
|
||||
"
|
||||
);
|
||||
|
||||
$response->assertStatus(204);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
$response->assertHeaderMissing('ETag');
|
||||
|
||||
$this->assertDatabaseHas('tasks', [
|
||||
'account_id' => $user->account_id,
|
||||
'uuid' => $task->uuid,
|
||||
'completed' => true,
|
||||
'completed_at' => Carbon::create(2019, 01, 21, 18, 28, 00),
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_report()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$task = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
'content-type' => 'application/xml; charset=utf-8',
|
||||
],
|
||||
'<cal:calendar-query xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<cal:calendar-data content-type="text/calendar" version="2.0" />
|
||||
</d:prop>
|
||||
<cal:filter>
|
||||
<cal:comp-filter name="VCALENDAR" />
|
||||
</cal:filter>
|
||||
</cal:calendar-query>'
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$peopleurl = route('people.show', $contact);
|
||||
$sabreversion = \Sabre\VObject\Version::VERSION;
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/{$task->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($task)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getVTodo($task)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
|
||||
public function test_caldav_tasks_report_multiget()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$task1 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
$task2 = factory(Task::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
$response = $this->call('REPORT', "/dav/calendars/{$user->email}/tasks/", [], [], [],
|
||||
[
|
||||
'HTTP_DEPTH' => '1',
|
||||
],
|
||||
"<cal:calendar-multiget xmlns:d=\"DAV:\" xmlns:cal=\"urn:ietf:params:xml:ns:caldav\">
|
||||
<d:prop>
|
||||
<d:getetag />
|
||||
<cal:calendar-data content-type=\"text/calendar\" version=\"2.0\" />
|
||||
</d:prop>
|
||||
<d:href>/dav/calendars/{$user->email}/tasks/{$task1->uuid}.ics</d:href>
|
||||
<d:href>/dav/calendars/{$user->email}/tasks/{$task2->uuid}.ics</d:href>
|
||||
</cal:calendar-multiget>"
|
||||
);
|
||||
|
||||
$response->assertStatus(207);
|
||||
$response->assertHeader('X-Sabre-Version');
|
||||
|
||||
$response->assertSee('<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/">'.
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/{$task1->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($task1)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getVTodo($task1)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>', false);
|
||||
$response->assertSee(
|
||||
'<d:response>'.
|
||||
"<d:href>/dav/calendars/{$user->email}/tasks/{$task2->uuid}.ics</d:href>".
|
||||
'<d:propstat>'.
|
||||
'<d:prop>'.
|
||||
"<d:getetag>"{$this->getEtag($task2)}"</d:getetag>".
|
||||
"<cal:calendar-data>{$this->getVTodo($task2)}</cal:calendar-data>".
|
||||
'</d:prop>'.
|
||||
'<d:status>HTTP/1.1 200 OK</d:status>'.
|
||||
'</d:propstat>'.
|
||||
'</d:response>'.
|
||||
'</d:multistatus>', false);
|
||||
}
|
||||
}
|
||||
75
tests/Api/Settings/ApiAuditLogControllerTest.php
Normal file
75
tests/Api/Settings/ApiAuditLogControllerTest.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Settings;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
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();
|
||||
|
||||
factory(AuditLog::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/logs');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonStructureAuditLog],
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'current_page' => 1,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_is_possible_to_get_audit_logs_and_limit_query_and_paginate()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(AuditLog::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/logs?limit=1&page=2');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonStructureAuditLog],
|
||||
]);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 10,
|
||||
'per_page' => 1,
|
||||
'current_page' => 2,
|
||||
]);
|
||||
}
|
||||
}
|
||||
91
tests/Api/Settings/ApiComplianceControllerTest.php
Normal file
91
tests/Api/Settings/ApiComplianceControllerTest.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Settings;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Settings\Term;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiComplianceControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureCompliance = [
|
||||
'id',
|
||||
'object',
|
||||
'term_version',
|
||||
'term_content',
|
||||
'privacy_version',
|
||||
'privacy_content',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_list_of_terms()
|
||||
{
|
||||
$term = factory(Term::class, 10)->create([
|
||||
'term_version' => rand(1, 100),
|
||||
'term_content' => 'dummy data',
|
||||
'privacy_version' => rand(1, 100),
|
||||
'privacy_content' => 'dummy data',
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/compliance/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertCount(
|
||||
Term::get()->count(),
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => Term::get()->count(),
|
||||
'current_page' => 1,
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructureCompliance,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_single_term()
|
||||
{
|
||||
$term = factory(Term::class)->create([
|
||||
'term_version' => rand(1, 100),
|
||||
'term_content' => 'dummy data',
|
||||
'privacy_version' => rand(1, 100),
|
||||
'privacy_content' => 'dummy data',
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/api/compliance/'.$term->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $term->id,
|
||||
'object' => 'term',
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureCompliance,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_get_a_single_term()
|
||||
{
|
||||
$response = $this->json('GET', '/api/compliance/3');
|
||||
|
||||
$response->assertStatus(404);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'message' => 'The resource has not been found',
|
||||
'error_code' => 31,
|
||||
]);
|
||||
}
|
||||
}
|
||||
70
tests/Api/Settings/ApiCurrencyControllerTest.php
Normal file
70
tests/Api/Settings/ApiCurrencyControllerTest.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Api\Settings;
|
||||
|
||||
use Tests\ApiTestCase;
|
||||
use App\Models\Settings\Currency;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiCurrencyControllerTest extends ApiTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureCurrency = [
|
||||
'id',
|
||||
'object',
|
||||
'iso',
|
||||
'name',
|
||||
'symbol',
|
||||
];
|
||||
|
||||
/** @test */
|
||||
public function it_gets_all_the_currencies()
|
||||
{
|
||||
// in theory the currencies table is seeded by the initial script
|
||||
$response = $this->json('GET', '/api/currencies/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertCount(
|
||||
15,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'total' => 153,
|
||||
'current_page' => 1,
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => ['*' => $this->jsonStructureCurrency],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_one_currency()
|
||||
{
|
||||
$currency = factory(Currency::class)->create([]);
|
||||
|
||||
$response = $this->json('GET', '/api/currencies/'.$currency->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'id' => $currency->id,
|
||||
'object' => 'currency',
|
||||
]);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonStructureCurrency,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_currency_that_is_invalid()
|
||||
{
|
||||
$response = $this->json('GET', '/api/currencies/0');
|
||||
|
||||
$this->expectNotFound($response);
|
||||
}
|
||||
}
|
||||
14
tests/ApiTestCase.php
Normal file
14
tests/ApiTestCase.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\Traits\Asserts;
|
||||
use Tests\Traits\ApiSignIn;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ApiTestCase extends TestCase
|
||||
{
|
||||
use ApiSignIn,
|
||||
Asserts,
|
||||
DatabaseTransactions;
|
||||
}
|
||||
235
tests/Browser/Auth/AuthControllerTest.php
Normal file
235
tests/Browser/Auth/AuthControllerTest.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Auth;
|
||||
|
||||
use Tests\TestCase;
|
||||
use GuzzleHttp\Client;
|
||||
use App\Models\User\User;
|
||||
use Tests\Traits\Asserts;
|
||||
use Tests\Traits\ApiSignIn;
|
||||
use Illuminate\Testing\TestResponse;
|
||||
use Laravel\Passport\ClientRepository;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||
|
||||
class AuthControllerTest extends TestCase
|
||||
{
|
||||
use ApiSignIn,
|
||||
Asserts;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ($this->getActualConnection() != 'testing') {
|
||||
$this->markTestSkipped("Set DB_CONNECTION on 'testing' to run this test.");
|
||||
}
|
||||
}
|
||||
|
||||
protected $jsonStructureOAuthLogin = [
|
||||
'access_token',
|
||||
'expires_in',
|
||||
];
|
||||
|
||||
private const OAUTH_LOGIN_URL = 'http://localhost:8001/oauth/login';
|
||||
|
||||
public function test_oauth_login()
|
||||
{
|
||||
$repository = new ClientRepository();
|
||||
$client = null;
|
||||
try {
|
||||
$client = $repository->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
|
||||
$this->setEnvironmentValue([
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_ID' => $client->id,
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
]);
|
||||
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure($this->jsonStructureOAuthLogin);
|
||||
} finally {
|
||||
if ($client) {
|
||||
$repository->delete($client);
|
||||
}
|
||||
if ($user) {
|
||||
$user->account->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function test_oauth_login_bad_password()
|
||||
{
|
||||
$repository = new ClientRepository();
|
||||
$client = null;
|
||||
try {
|
||||
$client = $repository->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
|
||||
$this->setEnvironmentValue([
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_ID' => $client->id,
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
]);
|
||||
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => 'wrongPassword',
|
||||
]);
|
||||
|
||||
$this->expectNotAuthorized($response);
|
||||
} finally {
|
||||
if ($client) {
|
||||
$repository->delete($client);
|
||||
}
|
||||
if ($user) {
|
||||
$user->account->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function test_oauth_login_wrong_mail()
|
||||
{
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => 'badmail',
|
||||
'password' => 'xx',
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$this->expectDataError($response, ['The email must be a valid email address.']);
|
||||
}
|
||||
|
||||
public function test_oauth_login_wrong_password()
|
||||
{
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => 'mail@mail.com',
|
||||
'password' => 'xx',
|
||||
]);
|
||||
|
||||
$this->expectNotAuthorized($response);
|
||||
}
|
||||
|
||||
public function test_oauth_login_2fa()
|
||||
{
|
||||
$repository = new ClientRepository();
|
||||
$client = null;
|
||||
try {
|
||||
$client = $repository->createPasswordGrantClient(
|
||||
null, config('app.name'), config('app.url')
|
||||
);
|
||||
|
||||
$this->setEnvironmentValue([
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_ID' => $client->id,
|
||||
'PASSPORT_PASSWORD_GRANT_CLIENT_SECRET' => $client->secret,
|
||||
]);
|
||||
|
||||
$userPassword = 'password';
|
||||
$user = factory(User::class)->create([
|
||||
'password' => bcrypt($userPassword),
|
||||
'google2fa_secret' => 'UFKZDTYO64WDEZPPQEO4HF3PC5UUTFLE',
|
||||
]);
|
||||
|
||||
$response = $this->postClient(self::OAUTH_LOGIN_URL, [
|
||||
'email' => $user->email,
|
||||
'password' => $userPassword,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('Two Factor Authentication');
|
||||
} finally {
|
||||
if ($client) {
|
||||
$repository->delete($client);
|
||||
}
|
||||
if ($user) {
|
||||
$user->account->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getActualConnection()
|
||||
{
|
||||
$handle = fopen('.env', 'r');
|
||||
if (! $handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
$value = null;
|
||||
while (($line = fgets($handle)) !== false) {
|
||||
if (preg_match('/DB_CONNECTION=(.{1,})/', $line, $matches)) {
|
||||
$value = $matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function setEnvironmentValue(array $values)
|
||||
{
|
||||
$envFile = app()->environmentFilePath();
|
||||
$str = file_get_contents($envFile);
|
||||
|
||||
if (count($values) > 0) {
|
||||
foreach ($values as $envKey => $envValue) {
|
||||
$str .= "\n"; // In case the searched variable is in the last line without \n
|
||||
$keyPosition = strpos($str, "{$envKey}=");
|
||||
$endOfLinePosition = strpos($str, "\n", $keyPosition);
|
||||
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
|
||||
|
||||
// If key does not exist, add it
|
||||
if (! $keyPosition || ! $endOfLinePosition || ! $oldLine) {
|
||||
$str .= "{$envKey}={$envValue}\n";
|
||||
} else {
|
||||
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$str = substr($str, 0, -1);
|
||||
|
||||
return file_put_contents($envFile, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $param
|
||||
* @return TestResponse
|
||||
*/
|
||||
protected function postClient($path, $param)
|
||||
{
|
||||
try {
|
||||
$http = new Client([
|
||||
'timeout' => 30,
|
||||
]);
|
||||
$response = $http->post($path, [
|
||||
'form_params' => $param,
|
||||
]);
|
||||
} catch (\GuzzleHttp\Exception\RequestException $e) {
|
||||
$response = $e->getResponse();
|
||||
}
|
||||
|
||||
$factory = new HttpFoundationFactory();
|
||||
$response = $factory->createResponse($response);
|
||||
|
||||
return TestResponse::fromBaseResponse($response);
|
||||
}
|
||||
}
|
||||
21
tests/Browser/ExampleTest.php
Normal file
21
tests/Browser/ExampleTest.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser;
|
||||
|
||||
use Tests\DuskTestCase;
|
||||
|
||||
class ExampleTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* A basic browser test example.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBasicExample()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->visit('/')
|
||||
->assertSee('Login');
|
||||
});
|
||||
}
|
||||
}
|
||||
83
tests/Browser/Feature/UploadVCardTest.php
Normal file
83
tests/Browser/Feature/UploadVCardTest.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Feature;
|
||||
|
||||
use Tests\DuskTestCase;
|
||||
use Tests\Browser\Pages\ImportVCardUpload;
|
||||
|
||||
class UploadVCardTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* Make sure that the Add contact view has the link to the upload screen,
|
||||
* and that the screen contains the blank view.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_upload_vcard_is_accessible_from_add_contact_view()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->login()
|
||||
->visit('/people/add')
|
||||
->assertSee('import your contacts');
|
||||
|
||||
$browser->clickLink('import your contacts')
|
||||
->assertSee('You haven’t imported any contacts yet');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the Import button leads to the Import screen, and that
|
||||
* the cancel button leads to the Blank import screen.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_import_button_leads_to_import_screen()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->login()
|
||||
->visit('/settings/import')
|
||||
->clickLink('Import vCard')
|
||||
->assertPathIs('/settings/import/upload')
|
||||
->clickLink('Cancel')
|
||||
->assertPathIs('/settings/import');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a single contact from a valid vcard file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_user_can_import_contacts_from_a_vcf_card()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->login()
|
||||
->visit('/settings/import')
|
||||
->clickLink('Import vCard')
|
||||
->attach('vcard', base_path('tests/stubs/single_vcard_stub.vcard'))
|
||||
->on(new ImportVCardUpload)
|
||||
->scrollTo('upload')
|
||||
->press('Upload')
|
||||
->assertSee('1 imported');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a contact from a broken vCard and see that it triggers an error.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_user_see_error_when_importing_broken_vcard()
|
||||
{
|
||||
$this->browse(function ($browser) {
|
||||
$browser->login()
|
||||
->visit('/settings/import')
|
||||
->clickLink('Import vCard')
|
||||
->attach('vcard', base_path('tests/stubs/broken_vcard_stub.vcard'))
|
||||
->on(new ImportVCardUpload)
|
||||
->scrollTo('upload')
|
||||
->press('Upload')
|
||||
->assertSee('The vcard must be a file of type: vcf, vcard.');
|
||||
});
|
||||
}
|
||||
}
|
||||
45
tests/Browser/Pages/DashboardValidate2fa.php
Normal file
45
tests/Browser/Pages/DashboardValidate2fa.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class DashboardValidate2fa extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/dashboard';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'verify' => "button[name='verify']",
|
||||
'otp' => '#one_time_password',
|
||||
];
|
||||
}
|
||||
}
|
||||
43
tests/Browser/Pages/HomePage.php
Normal file
43
tests/Browser/Pages/HomePage.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class HomePage extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'@element' => '#selector',
|
||||
];
|
||||
}
|
||||
}
|
||||
44
tests/Browser/Pages/ImportVCardUpload.php
Normal file
44
tests/Browser/Pages/ImportVCardUpload.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ImportVCardUpload extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/import/upload';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'upload' => '#upload',
|
||||
];
|
||||
}
|
||||
}
|
||||
21
tests/Browser/Pages/Page.php
Normal file
21
tests/Browser/Pages/Page.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Page as BasePage;
|
||||
|
||||
abstract class Page extends BasePage
|
||||
{
|
||||
/**
|
||||
* Get the global element shortcuts for the site.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function siteElements()
|
||||
{
|
||||
return [
|
||||
'@link' => "a[@href='link']",
|
||||
'alert' => '.alert',
|
||||
];
|
||||
}
|
||||
}
|
||||
45
tests/Browser/Pages/Settings/SettingsPersonnalization.php
Normal file
45
tests/Browser/Pages/Settings/SettingsPersonnalization.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages\Settings;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Tests\Browser\Pages\Page;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SettingsPersonnalization extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/personalization';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'@reminder-rule-label' => '.reminder-rule-7 > span',
|
||||
];
|
||||
}
|
||||
}
|
||||
44
tests/Browser/Pages/SettingsDAV.php
Normal file
44
tests/Browser/Pages/SettingsDAV.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SettingsDAV extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/dav';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'dav_url_base' => '#dav_url_base',
|
||||
];
|
||||
}
|
||||
}
|
||||
54
tests/Browser/Pages/SettingsSecurity.php
Normal file
54
tests/Browser/Pages/SettingsSecurity.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SettingsSecurity extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/security';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'two_factor_link' => "a:contains('Enable Two Factor Authentication')",
|
||||
'barcode' => '#barcode',
|
||||
'secretkey' => '#secretkey',
|
||||
'buttonVerify' => "button[name='verify']",
|
||||
'enableVerify' => '#verify1',
|
||||
'disableVerify' => '#verify2',
|
||||
'otpenable' => '#one_time_password1',
|
||||
'otpdisable' => '#one_time_password2',
|
||||
'enableModal' => '#enableModal',
|
||||
'disableModal' => '#disableModal',
|
||||
'registerModal' => '#registerModal',
|
||||
];
|
||||
}
|
||||
}
|
||||
45
tests/Browser/Pages/SettingsSecurity2faDisable.php
Normal file
45
tests/Browser/Pages/SettingsSecurity2faDisable.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SettingsSecurity2faDisable extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/security/2fa-disable';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'verify' => "button[name='verify']",
|
||||
'otp' => '#one_time_password',
|
||||
];
|
||||
}
|
||||
}
|
||||
47
tests/Browser/Pages/SettingsSecurity2faEnable.php
Normal file
47
tests/Browser/Pages/SettingsSecurity2faEnable.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SettingsSecurity2faEnable extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/settings/security/2fa-enable';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'barcode' => '#barcode',
|
||||
'secretkey' => '#secretkey',
|
||||
'verify' => "button[name='verify']",
|
||||
'otp' => '#one_time_password',
|
||||
];
|
||||
}
|
||||
}
|
||||
44
tests/Browser/Pages/Validate2fa.php
Normal file
44
tests/Browser/Pages/Validate2fa.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Pages;
|
||||
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class Validate2fa extends Page
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Get the URL for the page.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return '/validate2fa';
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the browser is on the page.
|
||||
*
|
||||
* @param Browser $browser
|
||||
* @return void
|
||||
*/
|
||||
public function assert(Browser $browser)
|
||||
{
|
||||
$browser->assertPathIs($this->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element shortcuts for the page.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function elements()
|
||||
{
|
||||
return [
|
||||
'@element' => '#selector',
|
||||
];
|
||||
}
|
||||
}
|
||||
23
tests/Browser/Settings/DAVControllerTest.php
Normal file
23
tests/Browser/Settings/DAVControllerTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Settings;
|
||||
|
||||
use Tests\DuskTestCase;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Tests\Browser\Pages\SettingsDAV;
|
||||
|
||||
class DAVControllerTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* Test if the dav url is present.
|
||||
*/
|
||||
public function test_it_has_dav_url()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsDAV)
|
||||
->assertVisible('dav_url_base')
|
||||
->assertSourceHas(config('app.url').'/dav');
|
||||
});
|
||||
}
|
||||
}
|
||||
342
tests/Browser/Settings/MultiFAControllerTest.php
Normal file
342
tests/Browser/Settings/MultiFAControllerTest.php
Normal file
@@ -0,0 +1,342 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Browser\Settings;
|
||||
|
||||
use Zxing\QrReader;
|
||||
use Tests\DuskTestCase;
|
||||
use Laravel\Dusk\Browser;
|
||||
use Illuminate\Console\Application;
|
||||
use Tests\Browser\Pages\SettingsSecurity;
|
||||
use Tests\Browser\Pages\DashboardValidate2fa;
|
||||
|
||||
class MultiFAControllerTest extends DuskTestCase
|
||||
{
|
||||
/**
|
||||
* Cleanup.
|
||||
*/
|
||||
public function cleanup()
|
||||
{
|
||||
exec(Application::formatCommandString('2fa:deactivate --force --email=admin@admin.com'), $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has 2fa Enable Link in Security Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHasSettings2faEnableLink()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->assertSeeLink('Enable Two Factor Authentication');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has WebAuthn Enable Link in Security Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHasSettingsWebAuthnEnableLink()
|
||||
{
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->assertSeeLink('Add a new security key');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the barcode generated in 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testHas2faEnableBarCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal')
|
||||
->assertVisible('barcode')
|
||||
->assertVisible('secretkey');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the barcode generated in 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
* @group multifabarcode
|
||||
*/
|
||||
public function testBarCodeContent()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
// \Facebook\WebDriver\Remote\RemoteWebElement
|
||||
$barcode = $browser->element('barcode');
|
||||
$imgsrc = $barcode->getAttribute('src');
|
||||
|
||||
$key = $this->unparseBarcode($imgsrc);
|
||||
$this->assertEquals(32, strlen($key));
|
||||
|
||||
$this->assertEquals($browser->text('secretkey'), $key);
|
||||
});
|
||||
}
|
||||
|
||||
private function unparseBarcode($imgsrc)
|
||||
{
|
||||
$this->assertStringStartsWith('data:image/png', $imgsrc);
|
||||
|
||||
$imgcode = str_replace('data:image/png;base64,', '', $imgsrc);
|
||||
|
||||
$qrcode = new QrReader(base64_decode($imgcode), QrReader::SOURCE_TYPE_BLOB);
|
||||
$text = $qrcode->text();
|
||||
$this->assertStringStartsWith('otpauth://totp/', $text);
|
||||
|
||||
// unparse $text
|
||||
// See PragmaRX\Google2FA\Support\QRCode getQRCodeUrl
|
||||
// example :
|
||||
//otpauth://totp/monicalocal.test:admin%40admin.com?secret=H25L7JLI7I57KYE7U53BIIOUELWXMRE6&issuer=monicalocal.test
|
||||
|
||||
$ret = preg_match('@^otpauth://totp/([^:]+):([^?]+)\?secret=([^&]+)&issuer=(.+)@i', $text, $matches);
|
||||
$this->assertEquals(1, $ret, 'otp content does not match format');
|
||||
$this->assertCount(5, $matches);
|
||||
|
||||
return $matches[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page with wrong code.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal')
|
||||
->type('otpenable', '000000')
|
||||
->scrollTo('enableVerify')
|
||||
->press('enableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('error', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2fa()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$this->enable2fa($browser);
|
||||
});
|
||||
}
|
||||
|
||||
private function enable2fa(Browser $browser)
|
||||
{
|
||||
$secretkey = $browser->waitFor('enableModal')
|
||||
->text('secretkey');
|
||||
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
$browser->type('otpenable', $one_time_password);
|
||||
|
||||
$browser = $browser->scrollTo('enableVerify')
|
||||
->press('enableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('success', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
|
||||
// TODO: test if user has 2fa enabled actually
|
||||
// TODO: test if session token auth is right
|
||||
|
||||
$browser->assertSeeLink('Disable Two Factor Authentication');
|
||||
|
||||
return $secretkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faLoginWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$user = call_user_func(Browser::$userResolver);
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$browser =
|
||||
$browser->loginAs($user)
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Logout')
|
||||
->loginAs($user)
|
||||
->visit(new DashboardValidate2fa)
|
||||
->assertVisible('otp')
|
||||
->type('otp', '000000')
|
||||
->press('verify');
|
||||
|
||||
$this->assertTrue($this->hasDivAlert($browser));
|
||||
$notification = $this->getDivAlert($browser);
|
||||
$this->assertStringContainsString('alert-danger', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('The two factor authentication has failed.', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 2fa Enable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faLogin()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$user = call_user_func(Browser::$userResolver);
|
||||
|
||||
$this->browse(function (Browser $browser) use ($user) {
|
||||
$browser =
|
||||
$browser->loginAs($user)
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Logout')
|
||||
->loginAs($user)
|
||||
->visit(new DashboardValidate2fa)
|
||||
->assertVisible('otp')
|
||||
->type('otp', $one_time_password)
|
||||
->press('verify');
|
||||
|
||||
$this->assertFalse($this->hasDivAlert($browser));
|
||||
$browser->assertPathIs('/dashboard');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 2fa Enable Page and Disable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faDisable2fa()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$secretkey = $this->enable2fa($browser);
|
||||
$google2fa = new \PragmaRX\Google2FA\Google2FA();
|
||||
$one_time_password = $google2fa->getCurrentOtp($secretkey);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Disable Two Factor Authentication')
|
||||
->waitFor('disableModal')
|
||||
->assertVisible('otpdisable')
|
||||
->type('otpdisable', $one_time_password)
|
||||
->scrollTo('disableVerify')
|
||||
->press('disableVerify')
|
||||
->waitUntilMissing('enableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
$notification = $this->getNotification($browser);
|
||||
$this->assertStringContainsString('success', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test 2fa Enable Page and Disable Page.
|
||||
*
|
||||
* @group multifa
|
||||
*/
|
||||
public function testEnable2faDisable2faWrongCode()
|
||||
{
|
||||
$this->markTestIncomplete('Ignore 2fa tests for now.');
|
||||
|
||||
$this->browse(function (Browser $browser) {
|
||||
$browser =
|
||||
$browser->login()
|
||||
->visit(new SettingsSecurity)
|
||||
->scrollTo('two_factor_link')
|
||||
->clickLink('Enable Two Factor Authentication')
|
||||
->waitFor('enableModal');
|
||||
|
||||
$this->enable2fa($browser);
|
||||
|
||||
$browser =
|
||||
$browser->clickLink('Disable Two Factor Authentication')
|
||||
->waitFor('disableModal')
|
||||
->assertVisible('otpdisable')
|
||||
->type('otpdisable', '000000')
|
||||
->scrollTo('disableVerify')
|
||||
->press('disableVerify')
|
||||
->waitUntilMissing('disableModal');
|
||||
|
||||
$this->assertTrue($this->hasNotification($browser));
|
||||
|
||||
$res = $browser->elements('.notification');
|
||||
$notification = $res[1];
|
||||
|
||||
$this->assertStringContainsString('error', $notification->getAttribute('class'));
|
||||
$this->assertStringContainsString('Two Factor Authentication', $notification->getText());
|
||||
});
|
||||
}
|
||||
}
|
||||
2
tests/Browser/console/.gitignore
vendored
Normal file
2
tests/Browser/console/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
2
tests/Browser/screenshots/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
92
tests/Commands/OneTime/MoveAvatarsToPhotosDirectoryTest.php
Normal file
92
tests/Commands/OneTime/MoveAvatarsToPhotosDirectoryTest.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\OneTime;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Models\Account\Photo;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class MoveAvatarsToPhotosDirectoryTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_move_avatars_to_photo_directory()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
Storage::fake('public');
|
||||
|
||||
Storage::disk('public')->put('avatars/avatar.jpg', 'content');
|
||||
Storage::disk('public')->put('avatars/avatar_110.jpg', 'content');
|
||||
Storage::disk('public')->put('avatars/avatar_174.jpg', 'content');
|
||||
|
||||
$contact->avatar_file_name = 'avatars/avatar.jpg';
|
||||
$contact->avatar_location = 'public';
|
||||
$contact->has_avatar = true;
|
||||
$contact->save();
|
||||
|
||||
Storage::disk('public')->assertExists('avatars/avatar.jpg');
|
||||
|
||||
$this->artisan('monica:moveavatarstophotosdirectory')->run();
|
||||
|
||||
Storage::disk('public')->assertMissing('avatars/avatar.jpg');
|
||||
Storage::disk('public')->assertMissing('avatars/avatar_110.jpg');
|
||||
Storage::disk('public')->assertMissing('avatars/avatar_174.jpg');
|
||||
|
||||
$contact->refresh();
|
||||
$photo = Photo::find($contact->avatar_photo_id);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'avatar_source' => 'photo',
|
||||
]);
|
||||
$this->assertStringContainsString('photos/', $photo->new_filename);
|
||||
|
||||
Storage::disk('public')->assertExists($photo->new_filename);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_handles_missing_avatar()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
Storage::fake('public');
|
||||
|
||||
$contact->avatar_file_name = 'avatars/avatar.jpg';
|
||||
$contact->avatar_location = 'public';
|
||||
$contact->has_avatar = true;
|
||||
$contact->save();
|
||||
|
||||
$this->artisan('monica:moveavatarstophotosdirectory')->run();
|
||||
|
||||
Storage::disk('public')->assertMissing('avatars/avatar.jpg');
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'avatar_source' => 'default',
|
||||
'avatar_file_name' => 'avatars/avatar.jpg',
|
||||
'avatar_location' => 'public',
|
||||
]);
|
||||
}
|
||||
}
|
||||
102
tests/Commands/Other/CleanCommandTest.php
Normal file
102
tests/Commands/Other/CleanCommandTest.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Models\User\SyncToken;
|
||||
use App\Models\Account\Account;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CleanCommandTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function clean_command_left_one_token()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
SyncToken::create([
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
|
||||
$this->artisan('monica:clean')->run();
|
||||
|
||||
$this->assertDatabaseHas('synctoken', [
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function clean_command_left_all_token()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$s1 = SyncToken::create([
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
$s2 = SyncToken::create([
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now()->addDays(-10),
|
||||
]);
|
||||
|
||||
$command = $this->artisan('monica:clean');
|
||||
$command->expectsOutput("Delete token {$s2->id} - User {$user->id} - Type contacts - timestamp {$s2->timestamp}");
|
||||
$command->run();
|
||||
|
||||
$this->assertDatabaseHas('synctoken', [
|
||||
'id' => $s1->id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('synctoken', [
|
||||
'id' => $s2->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function clean_command_dryrun()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
|
||||
$s1 = SyncToken::create([
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now(),
|
||||
]);
|
||||
$s2 = SyncToken::create([
|
||||
'account_id' => $account->id,
|
||||
'user_id' => $user->id,
|
||||
'name' => 'contacts',
|
||||
'timestamp' => now()->addDays(-10),
|
||||
]);
|
||||
|
||||
$this->artisan('monica:clean', ['--dry-run' => true])->run();
|
||||
|
||||
$this->assertDatabaseHas('synctoken', [
|
||||
'id' => $s1->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('synctoken', [
|
||||
'id' => $s2->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
60
tests/Commands/Other/CreateAccountTest.php
Normal file
60
tests/Commands/Other/CreateAccountTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Console\Commands\CreateAccount;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CreateAccountTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_creates_account()
|
||||
{
|
||||
$email = 'user1@example.com';
|
||||
$this->artisan('account:create', ['--email' => 'user1@example.com', '--password' => 'astrongpassword'])
|
||||
->run();
|
||||
|
||||
$user = User::where('email', '=', $email)->first();
|
||||
$this->assertNotEmpty($user);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_creates_account_with_specified_name()
|
||||
{
|
||||
$email = 'user1@example.com';
|
||||
$firstname = 'firstname';
|
||||
$lastname = 'lastname';
|
||||
$this->artisan('account:create', [
|
||||
'--email' => $email,
|
||||
'--password' => 'astrongpassword',
|
||||
'--firstname' => $firstname,
|
||||
'--lastname' => $lastname,
|
||||
])->run();
|
||||
|
||||
$user = User::where('email', '=', $email)->first();
|
||||
$this->assertNotEmpty($user);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_creation_without_email()
|
||||
{
|
||||
$this->artisan('account:create', ['--password' => 'astrongpassword'])
|
||||
->expectsOutput(CreateAccount::ERROR_MISSING_EMAIL)
|
||||
->doesntExpectOutput(CreateAccount::ERROR_MISSING_PASSWORD)
|
||||
->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_fails_creation_without_password()
|
||||
{
|
||||
$email = 'user1@example.com';
|
||||
$this->artisan('account:create', ['--email' => $email])
|
||||
->expectsOutput(CreateAccount::ERROR_MISSING_PASSWORD)
|
||||
->doesntExpectOutput(CreateAccount::ERROR_MISSING_EMAIL)
|
||||
->run();
|
||||
}
|
||||
}
|
||||
43
tests/Commands/Other/CreateAddressBookSubscriptionTest.php
Normal file
43
tests/Commands/Other/CreateAddressBookSubscriptionTest.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use Mockery\MockInterface;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use App\Services\DavClient\CreateAddressBookSubscription;
|
||||
|
||||
class CreateAddressBookSubscriptionTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_add_addressbook()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
|
||||
$this->mock(CreateAddressBookSubscription::class, function (MockInterface $mock) use ($user) {
|
||||
$mock->shouldReceive('execute')
|
||||
->once()
|
||||
->withArgs(function ($data) use ($user) {
|
||||
$this->assertEquals([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'base_uri' => 'https://test',
|
||||
'username' => 'login',
|
||||
'password' => 'password',
|
||||
], $data);
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
$this->artisan('monica:newaddressbooksubscription', [
|
||||
'--email' => $user->email,
|
||||
'--url' => 'https://test',
|
||||
'--login' => 'login',
|
||||
'--password' => 'password',
|
||||
])->run();
|
||||
}
|
||||
}
|
||||
87
tests/Commands/Other/ImportCSVTest.php
Normal file
87
tests/Commands/Other/ImportCSVTest.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ImportCSVTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function csv_import_contacts()
|
||||
{
|
||||
Storage::fake('public');
|
||||
|
||||
$user = $this->getUser();
|
||||
$path = base_path('tests/stubs/single_contact_stub.csv');
|
||||
|
||||
$totalContacts = Contact::where('account_id', $user->account_id)->count();
|
||||
|
||||
$this->artisan('import:csv', [
|
||||
'user' => $user->email,
|
||||
'file' => $path,
|
||||
])
|
||||
->assertSuccessful()
|
||||
->run();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'first_name' => 'Bono',
|
||||
'last_name' => 'Hewson',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'data' => 'bono@example.com',
|
||||
]);
|
||||
|
||||
// Allows checking if birthday was correctly set
|
||||
$this->assertDatabaseHas('special_dates', [
|
||||
'date' => '1960-05-10',
|
||||
]);
|
||||
|
||||
// Asserts that only 3 new contacts were created
|
||||
$this->assertEquals(
|
||||
$totalContacts + 1,
|
||||
Contact::where('account_id', $user->account_id)->count()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function csv_import_validates_user()
|
||||
{
|
||||
$path = base_path('tests/stubs/single_contact_stub.csv');
|
||||
|
||||
$this->artisan('import:csv', [
|
||||
'user' => 'test@test.com',
|
||||
'file' => $path,
|
||||
])
|
||||
->assertFailed()
|
||||
->expectsOutput('You need to provide a valid User ID or email address!')
|
||||
->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function csv_import_validates_file()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->artisan('import:csv', [
|
||||
'user' => $user->email,
|
||||
'file' => 'xxx',
|
||||
])
|
||||
->assertFailed()
|
||||
->expectsOutput('You need to provide a valid file path.')
|
||||
->run();
|
||||
}
|
||||
|
||||
private function getUser()
|
||||
{
|
||||
$account = Account::createDefault('John', 'Doe', 'johndoe@example.com', 'secret', null, 'en');
|
||||
|
||||
return $account->users()->first();
|
||||
}
|
||||
}
|
||||
104
tests/Commands/Other/ImportVCardsTest.php
Normal file
104
tests/Commands/Other/ImportVCardsTest.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ImportVCardsTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_validates_user()
|
||||
{
|
||||
$path = base_path('tests/stubs/vcard_stub.vcf');
|
||||
|
||||
$this->artisan('import:vcard', ['--user' => 'notfound@example.com', '--path' => $path, '--no-interaction' => true])
|
||||
->assertFailed()
|
||||
->expectsOutput('No user with that email.')
|
||||
->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_validates_file()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
$this->artisan('import:vcard', ['--user' => $user->email, '--path' => 'not_found', '--no-interaction' => true])
|
||||
->assertFailed()
|
||||
->expectsOutput('The provided vcard file was not found or is not valid!')
|
||||
->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_imports_contacts()
|
||||
{
|
||||
Storage::fake('public');
|
||||
|
||||
$user = $this->getUser();
|
||||
$path = base_path('tests/stubs/vcard_stub.vcf');
|
||||
|
||||
$totalContacts = Contact::where('account_id', $user->account_id)->count();
|
||||
|
||||
$this->artisan('import:vcard', ['--user' => $user->email, '--path' => $path, '--no-interaction' => true])
|
||||
->assertSuccessful()
|
||||
->run();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'data' => 'john.doe@example.com',
|
||||
]);
|
||||
|
||||
// Allows checking if birthday was correctly set
|
||||
$this->assertDatabaseHas('special_dates', [
|
||||
'date' => '1960-05-10',
|
||||
]);
|
||||
|
||||
// Allows checking nickname fallback
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'first_name' => 'Johnny',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'company' => 'U2',
|
||||
'job' => 'Lead vocalist',
|
||||
]);
|
||||
|
||||
// Allows checking addresses are correctly saved
|
||||
$this->assertDatabaseHas('places', [
|
||||
'street' => '17 Shakespeare Ave.',
|
||||
'postal_code' => 'SO17 2HB',
|
||||
'city' => 'Southampton',
|
||||
'country' => 'GB',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'data' => 'bono@example.com',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', [
|
||||
'data' => '+1 202-555-0191',
|
||||
]);
|
||||
|
||||
// Asserts that only 3 new contacts were created
|
||||
$this->assertEquals(
|
||||
$totalContacts + 3,
|
||||
Contact::where('account_id', $user->account_id)->count()
|
||||
);
|
||||
}
|
||||
|
||||
private function getUser()
|
||||
{
|
||||
$account = Account::createDefault('John', 'Doe', 'johndoe@example.com', 'secret', null, 'en');
|
||||
|
||||
return $account->users()->first();
|
||||
}
|
||||
}
|
||||
59
tests/Commands/Other/UpdateCommandTest.php
Normal file
59
tests/Commands/Other/UpdateCommandTest.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Other;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Console\Commands\Helpers\Command;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class UpdateCommandTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function update_command_default()
|
||||
{
|
||||
/** @var \Tests\Helpers\CommandCallerFake */
|
||||
$fake = Command::fake();
|
||||
|
||||
$this->artisan('monica:update')->run();
|
||||
|
||||
$this->assertCount(9, $fake->buffer);
|
||||
$this->assertCommandContains($fake->buffer[0], 'Maintenance mode: on', 'php artisan down');
|
||||
$this->assertCommandContains($fake->buffer[1], 'Resetting application cache', 'php artisan cache:clear');
|
||||
$this->assertCommandContains($fake->buffer[2], 'Clear config cache', 'php artisan config:clear');
|
||||
$this->assertCommandContains($fake->buffer[3], 'Clear route cache', 'php artisan route:clear');
|
||||
$this->assertCommandContains($fake->buffer[4], 'Clear view cache', 'php artisan view:clear');
|
||||
$this->assertCommandContains($fake->buffer[5], 'Performing migrations', 'php artisan migrate');
|
||||
$this->assertCommandContains($fake->buffer[6], 'Check for encryption keys', 'php artisan monica:passport');
|
||||
$this->assertCommandContains($fake->buffer[7], 'Ping for new version', 'php artisan monica:ping');
|
||||
$this->assertCommandContains($fake->buffer[8], 'Maintenance mode: off', 'php artisan up');
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function update_command_composer()
|
||||
{
|
||||
/** @var \Tests\Helpers\CommandCallerFake */
|
||||
$fake = Command::fake();
|
||||
|
||||
$this->artisan('monica:update', ['--composer-install' => true])->run();
|
||||
|
||||
$this->assertCount(10, $fake->buffer);
|
||||
$this->assertCommandContains($fake->buffer[0], 'Maintenance mode: on', 'php artisan down');
|
||||
$this->assertCommandContains($fake->buffer[1], 'Resetting application cache', 'php artisan cache:clear');
|
||||
$this->assertCommandContains($fake->buffer[2], 'Clear config cache', 'php artisan config:clear');
|
||||
$this->assertCommandContains($fake->buffer[3], 'Clear route cache', 'php artisan route:clear');
|
||||
$this->assertCommandContains($fake->buffer[4], 'Clear view cache', 'php artisan view:clear');
|
||||
$this->assertCommandContains($fake->buffer[5], 'Updating composer dependencies', 'composer install');
|
||||
$this->assertCommandContains($fake->buffer[6], 'Performing migrations', 'php artisan migrate');
|
||||
$this->assertCommandContains($fake->buffer[7], 'Check for encryption keys', 'php artisan monica:passport');
|
||||
$this->assertCommandContains($fake->buffer[8], 'Ping for new version', 'php artisan monica:ping');
|
||||
$this->assertCommandContains($fake->buffer[9], 'Maintenance mode: off', 'php artisan up');
|
||||
}
|
||||
|
||||
private function assertCommandContains($array, $message, $command)
|
||||
{
|
||||
$this->assertStringContainsString($message, $array['message']);
|
||||
$this->assertStringContainsString($command, $array['command']);
|
||||
}
|
||||
}
|
||||
26
tests/Commands/Scheduling/CalculateStatisticsTest.php
Normal file
26
tests/Commands/Scheduling/CalculateStatisticsTest.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CalculateStatisticsTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function the_command_runs_well()
|
||||
{
|
||||
$runsWell = true;
|
||||
|
||||
try {
|
||||
$this->artisan('monica:calculatestatistics')->run();
|
||||
} catch (QueryException $e) {
|
||||
$runsWell = false;
|
||||
}
|
||||
|
||||
$this->assertTrue($runsWell);
|
||||
}
|
||||
}
|
||||
119
tests/Commands/Scheduling/CronEventTest.php
Normal file
119
tests/Commands/Scheduling/CronEventTest.php
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Instance\Cron;
|
||||
use App\Console\Scheduling\CronEvent;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CronEventTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_get_the_right_command()
|
||||
{
|
||||
$cron = factory(Cron::class)->create();
|
||||
|
||||
$event = CronEvent::command($cron->command);
|
||||
|
||||
$this->assertEquals($event->cron()->id, $cron->id);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function now_not_due()
|
||||
{
|
||||
$cron = factory(Cron::class)->create();
|
||||
$event = new CronEvent($cron);
|
||||
|
||||
$this->assertFalse($event->isDue());
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function next_minute_is_due()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 7, 0, 0));
|
||||
|
||||
$cron = factory(Cron::class)->create();
|
||||
$event = new CronEvent($cron);
|
||||
|
||||
$this->assertFalse($event->isDue());
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 7, 1, 0));
|
||||
|
||||
$this->assertTrue($event->isDue());
|
||||
|
||||
$this->assertDatabaseHas('crons', [
|
||||
'command' => $cron->command,
|
||||
'last_run' => '2019-05-01 07:01:00',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function hourly_cron()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 7, 0, 0));
|
||||
|
||||
$cron = factory(Cron::class)->create();
|
||||
$event = new CronEvent($cron);
|
||||
$event->hourly();
|
||||
|
||||
$this->assertFalse($event->isDue());
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 8, 22, 0));
|
||||
|
||||
$this->assertTrue($event->isDue());
|
||||
|
||||
$this->assertDatabaseHas('crons', [
|
||||
'command' => $cron->command,
|
||||
'last_run' => '2019-05-01 08:22:00',
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 8, 59, 0));
|
||||
|
||||
$this->assertFalse($event->isDue());
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 9, 01, 0));
|
||||
|
||||
$this->assertTrue($event->isDue());
|
||||
|
||||
$this->assertDatabaseHas('crons', [
|
||||
'command' => $cron->command,
|
||||
'last_run' => '2019-05-01 09:01:00',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function daily_cron()
|
||||
{
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 1, 7, 0, 0));
|
||||
|
||||
$cron = factory(Cron::class)->create();
|
||||
$event = new CronEvent($cron);
|
||||
$event->daily();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 2, 8, 10, 0));
|
||||
|
||||
$this->assertTrue($event->isDue());
|
||||
|
||||
$this->assertDatabaseHas('crons', [
|
||||
'command' => $cron->command,
|
||||
'last_run' => '2019-05-02 08:10:00',
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 2, 10, 0, 0));
|
||||
|
||||
$this->assertFalse($event->isDue());
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2019, 5, 3, 0, 0, 0));
|
||||
|
||||
$this->assertTrue($event->isDue());
|
||||
|
||||
$this->assertDatabaseHas('crons', [
|
||||
'command' => $cron->command,
|
||||
'last_run' => '2019-05-03 00:00:00',
|
||||
]);
|
||||
}
|
||||
}
|
||||
28
tests/Commands/Scheduling/DavClientsUpdateTest.php
Normal file
28
tests/Commands/Scheduling/DavClientsUpdateTest.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Jobs\SynchronizeAddressBooks;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class DavClientsUpdateTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_dispatch_subscription_update()
|
||||
{
|
||||
Queue::fake();
|
||||
|
||||
$subscription = AddressBookSubscription::factory()->create();
|
||||
|
||||
$this->artisan('monica:davclients')->run();
|
||||
|
||||
Queue::assertPushed(SynchronizeAddressBooks::class, function ($job) use ($subscription) {
|
||||
return $job->subscription->id === $subscription->id;
|
||||
});
|
||||
}
|
||||
}
|
||||
101
tests/Commands/Scheduling/PingVersionServerTest.php
Normal file
101
tests/Commands/Scheduling/PingVersionServerTest.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\Instance\Instance;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class PingVersionServerTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_send_ping()
|
||||
{
|
||||
config(['monica.weekly_ping_server_url' => 'https://version.test/ping']);
|
||||
config(['monica.app_version' => '2.9.0']);
|
||||
config(['monica.check_version' => true]);
|
||||
|
||||
Instance::all()->each(function ($instance) {
|
||||
$instance->delete();
|
||||
});
|
||||
$instance = factory(Instance::class)->create();
|
||||
|
||||
$ret = [
|
||||
'new_version' => true,
|
||||
'latest_version' => '3.1.0',
|
||||
'number_of_versions_since_user_version' => 2,
|
||||
'notes' => 'notes',
|
||||
];
|
||||
|
||||
Http::fake([
|
||||
'https://version.test/*' => Http::response($ret, 200),
|
||||
]);
|
||||
|
||||
$this->artisan('monica:ping')->run();
|
||||
|
||||
$instance->refresh();
|
||||
|
||||
$this->assertEquals('3.1.0', $instance->latest_version);
|
||||
$this->assertEquals('notes', $instance->latest_release_notes);
|
||||
$this->assertEquals(2, $instance->number_of_versions_since_current_version);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_clear_instance()
|
||||
{
|
||||
config(['monica.weekly_ping_server_url' => 'https://version.test/ping']);
|
||||
config(['monica.app_version' => '3.1.0']);
|
||||
|
||||
Instance::all()->each(function ($instance) {
|
||||
$instance->delete();
|
||||
});
|
||||
$instance = factory(Instance::class)->create([
|
||||
'latest_version' => '3.1.0',
|
||||
]);
|
||||
|
||||
$ret = [
|
||||
'new_version' => false,
|
||||
'latest_version' => '2.9.0',
|
||||
'number_of_versions_since_user_version' => 0,
|
||||
'notes' => '',
|
||||
];
|
||||
|
||||
Http::fake([
|
||||
'https://version.test/*' => Http::response($ret, 200),
|
||||
]);
|
||||
|
||||
$this->artisan('monica:ping')->run();
|
||||
|
||||
$instance->refresh();
|
||||
|
||||
$this->assertEquals('3.1.0', $instance->latest_version);
|
||||
$this->assertNull($instance->latest_release_notes);
|
||||
$this->assertNull($instance->number_of_versions_since_current_version);
|
||||
}
|
||||
|
||||
/**
|
||||
* If an instance sets `version_check` env variable to false, the command
|
||||
* should exit with 0.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_check_version_set_to_false_disables_the_check()
|
||||
{
|
||||
config(['monica.weekly_ping_server_url' => 'https://version.test/ping']);
|
||||
config(['monica.app_version' => '2.9.0']);
|
||||
config(['monica.check_version' => false]);
|
||||
|
||||
$fake = Http::fake([
|
||||
'https://version.test/*' => Http::response([], 500),
|
||||
]);
|
||||
|
||||
$this->artisan('monica:ping')
|
||||
->assertSuccessful()
|
||||
->run();
|
||||
|
||||
$fake->assertNothingSent();
|
||||
}
|
||||
}
|
||||
78
tests/Commands/Scheduling/SendRemindersTest.php
Normal file
78
tests/Commands/Scheduling/SendRemindersTest.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\Reminder;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use App\Models\Contact\ReminderOutbox;
|
||||
use App\Jobs\Reminder\NotifyUserAboutReminder;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SendRemindersTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_schedules_a_reminder_email_job()
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2017, 1, 1, 7, 0, 0));
|
||||
|
||||
$account = factory(Account::class)->create([
|
||||
'default_time_reminder_is_sent' => '07:00',
|
||||
]);
|
||||
$contact = factory(Contact::class)->create(['account_id' => $account->id]);
|
||||
$user = factory(User::class)->create(['account_id' => $account->id]);
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'contact_id' => $contact->id,
|
||||
'initial_date' => '2017-01-01',
|
||||
]);
|
||||
factory(ReminderOutbox::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'reminder_id' => $reminder->id,
|
||||
'user_id' => $user->id,
|
||||
'planned_date' => '2017-01-01',
|
||||
]);
|
||||
|
||||
$this->artisan('send:reminders')->run();
|
||||
Bus::assertDispatched(NotifyUserAboutReminder::class);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_schedule_a_notification_if_it_is_not_the_right_time()
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2017, 1, 1, 7, 0, 0));
|
||||
|
||||
$account = factory(Account::class)->create([
|
||||
'default_time_reminder_is_sent' => '08:00',
|
||||
]);
|
||||
|
||||
$contact = factory(Contact::class)->create(['account_id' => $account->id]);
|
||||
$user = factory(User::class)->create([
|
||||
'account_id' => $account->id,
|
||||
]);
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'contact_id' => $contact->id,
|
||||
'initial_date' => '2017-01-01',
|
||||
]);
|
||||
$reminderOutbox = factory(ReminderOutbox::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'reminder_id' => $reminder->id,
|
||||
'user_id' => $user->id,
|
||||
'planned_date' => '2017-01-01',
|
||||
]);
|
||||
|
||||
$this->artisan('send:reminders')->run();
|
||||
Bus::assertNotDispatched(NotifyUserAboutReminder::class);
|
||||
}
|
||||
}
|
||||
54
tests/Commands/Scheduling/SendStayInTouchTest.php
Normal file
54
tests/Commands/Scheduling/SendStayInTouchTest.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Scheduling;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Tests\TestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Bus;
|
||||
use App\Jobs\StayInTouch\ScheduleStayInTouch;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SendStayInTouchTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_schedules_a_stay_in_touch_job()
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2017, 1, 1, 7, 0, 0));
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'stay_in_touch_trigger_date' => '2017-01-01 07:00:00',
|
||||
'stay_in_touch_frequency' => 30,
|
||||
]);
|
||||
|
||||
$this->artisan('send:stay_in_touch')->run();
|
||||
|
||||
Bus::assertDispatched(ScheduleStayInTouch::class);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_doesnt_schedule_stay_in_touch_jobs_if_no_date_is_found()
|
||||
{
|
||||
Bus::fake();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2017, 1, 1, 7, 0, 0));
|
||||
|
||||
$account = factory(Account::class)->create([]);
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'stay_in_touch_trigger_date' => '2017-03-01 07:00:00',
|
||||
'stay_in_touch_frequency' => 30,
|
||||
]);
|
||||
|
||||
$this->artisan('send:stay_in_touch')->run();
|
||||
|
||||
Bus::assertNotDispatched(ScheduleStayInTouch::class);
|
||||
}
|
||||
}
|
||||
71
tests/Commands/Tests/PassportCommandTest.php
Normal file
71
tests/Commands/Tests/PassportCommandTest.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Console\Commands\Helpers\Command;
|
||||
use Laravel\Passport\PersonalAccessClient;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class PassportCommandTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (! file_exists(base_path('storage/oauth-private.key')) || ! file_exists(base_path('storage/oauth-public.key'))) {
|
||||
$this->markTestSkipped('Run "php artisan key:generate" before executing these tests.');
|
||||
}
|
||||
|
||||
foreach (PersonalAccessClient::all() as $client) {
|
||||
$client->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function passport_command_create()
|
||||
{
|
||||
/** @var \Tests\Helpers\CommandCallerFake */
|
||||
$fake = Command::fake();
|
||||
|
||||
$this->artisan('monica:passport')->run();
|
||||
|
||||
$this->assertCount(1, $fake->buffer, $fake->buffer->implode(','));
|
||||
$this->assertCommandContains($fake->buffer[0], '✓ Creating personal access client', 'php artisan passport:client');
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function passport_command_already_created()
|
||||
{
|
||||
/** @var \Tests\Helpers\CommandCallerFake */
|
||||
$fake = Command::fake();
|
||||
|
||||
PersonalAccessClient::create();
|
||||
|
||||
$this->artisan('monica:passport')->run();
|
||||
|
||||
$this->assertCount(0, $fake->buffer, $fake->buffer->implode(','));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function passport_command_env_config()
|
||||
{
|
||||
/** @var \Tests\Helpers\CommandCallerFake */
|
||||
$fake = Command::fake();
|
||||
|
||||
config(['passport.private_key' => '-', 'passport.public_key' => '-']);
|
||||
|
||||
$this->artisan('monica:passport')->run();
|
||||
|
||||
$this->assertCount(1, $fake->buffer, $fake->buffer->implode(','));
|
||||
$this->assertCommandContains($fake->buffer[0], '✓ Creating personal access client', 'php artisan passport:client');
|
||||
}
|
||||
|
||||
private function assertCommandContains($array, $message, $command)
|
||||
{
|
||||
$this->assertStringContainsString($message, $array['message']);
|
||||
$this->assertStringContainsString($command, $array['command']);
|
||||
}
|
||||
}
|
||||
55
tests/Commands/Tests/SendTestEmailTest.php
Normal file
55
tests/Commands/Tests/SendTestEmailTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class SendTestEmailTest extends TestCase
|
||||
{
|
||||
/** @test */
|
||||
public function error_for_bad_email()
|
||||
{
|
||||
$exampleEmail = 'no.at.symbol';
|
||||
|
||||
$this->artisan('monica:test-email', ['--email' => $exampleEmail])
|
||||
->expectsOutput("Invalid email address: \"$exampleEmail\".")
|
||||
->assertFailed()
|
||||
->run();
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function command_prompts_for_email()
|
||||
{
|
||||
$exampleEmail = 'no.at.symbol';
|
||||
|
||||
$this->artisan('monica:test-email')
|
||||
->expectsQuestion('What email address should I send the test email to?', $exampleEmail)
|
||||
->expectsOutput("Invalid email address: \"$exampleEmail\".")
|
||||
->assertFailed()
|
||||
->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function command_attempts_to_send_email()
|
||||
{
|
||||
$exampleEmail = 'test@example.org';
|
||||
|
||||
Mail::shouldReceive('raw')
|
||||
->once()
|
||||
->withArgs(function ($message, $closure) use ($exampleEmail) {
|
||||
$this->assertEquals(
|
||||
"Hi $exampleEmail, you requested a test email from Monica.",
|
||||
$message
|
||||
);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
$this->artisan('monica:test-email', ['--email' => $exampleEmail])
|
||||
->assertSuccessful()
|
||||
->run();
|
||||
}
|
||||
}
|
||||
25
tests/Commands/Tests/SetupFrontEndTestUserTest.php
Normal file
25
tests/Commands/Tests/SetupFrontEndTestUserTest.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Commands\Tests;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\User\User;
|
||||
use App\Models\Account\Account;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class SetupFrontEndTestUserTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_create_a_test_user()
|
||||
{
|
||||
$accountCount = Account::count();
|
||||
$userCount = User::count();
|
||||
|
||||
$this->artisan('setup:frontendtestuser')->run();
|
||||
|
||||
$this->assertEquals($accountCount + 1, Account::count());
|
||||
$this->assertEquals($userCount + 1, User::count());
|
||||
}
|
||||
}
|
||||
125
tests/DuskTestCase.php
Normal file
125
tests/DuskTestCase.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Tests\Traits\SignIn;
|
||||
use App\Models\User\User;
|
||||
use Laravel\Dusk\Browser;
|
||||
use App\Services\User\AcceptPolicy;
|
||||
use Tests\Traits\CreatesApplication;
|
||||
use Laravel\Dusk\TestCase as BaseTestCase;
|
||||
use Facebook\WebDriver\Chrome\ChromeOptions;
|
||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||
|
||||
abstract class DuskTestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication, SignIn;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Browser::$storeScreenshotsAt = base_path('results/screenshots');
|
||||
Browser::$storeConsoleLogAt = base_path('results/console');
|
||||
Browser::$storeSourceAt = base_path('results/source');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for Dusk test execution.
|
||||
*
|
||||
* @beforeClass
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function prepare()
|
||||
{
|
||||
if (! static::runningInSail()) {
|
||||
static::startChromeDriver();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the RemoteWebDriver instance.
|
||||
*
|
||||
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
|
||||
*/
|
||||
protected function driver()
|
||||
{
|
||||
$options = (new ChromeOptions)->addArguments(collect([
|
||||
'--window-size=1920,1080',
|
||||
])->unless($this->hasHeadlessDisabled(), function ($items) {
|
||||
return $items->merge([
|
||||
'--disable-gpu',
|
||||
'--headless',
|
||||
]);
|
||||
})->all());
|
||||
|
||||
return RemoteWebDriver::create(
|
||||
$_ENV['DUSK_DRIVER_URL'] ?? 'http://localhost:9515',
|
||||
DesiredCapabilities::chrome()->setCapability(
|
||||
ChromeOptions::CAPABILITY, $options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the Dusk command has disabled headless mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasHeadlessDisabled()
|
||||
{
|
||||
return isset($_SERVER['DUSK_HEADLESS_DISABLED']) ||
|
||||
isset($_ENV['DUSK_HEADLESS_DISABLED']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default user to authenticate.
|
||||
*
|
||||
* @return \App\Models\User\User
|
||||
*/
|
||||
protected function user()
|
||||
{
|
||||
$user = factory(User::class)->create();
|
||||
$user->account->populateDefaultFields();
|
||||
$user->account->update(['has_access_to_paid_version_for_free' => true]);
|
||||
|
||||
app(AcceptPolicy::class)->execute([
|
||||
'account_id' => $user->account->id,
|
||||
'user_id' => $user->id,
|
||||
'ip_address' => null,
|
||||
]);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function hasDivAlert(Browser $browser)
|
||||
{
|
||||
$res = $browser->elements('alert');
|
||||
|
||||
return count($res) > 0;
|
||||
}
|
||||
|
||||
public function hasNotification(Browser $browser)
|
||||
{
|
||||
$res = $browser->elements('.notifications');
|
||||
|
||||
return count($res) > 0;
|
||||
}
|
||||
|
||||
public function getDivAlert(Browser $browser)
|
||||
{
|
||||
$res = $browser->elements('alert');
|
||||
if (count($res) > 0) {
|
||||
return $res[0];
|
||||
}
|
||||
}
|
||||
|
||||
public function getNotification($browser)
|
||||
{
|
||||
$res = $browser->elements('.notification');
|
||||
if (count($res) > 0) {
|
||||
return $res[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
304
tests/Feature/AccountSubscriptionTest.php
Normal file
304
tests/Feature/AccountSubscriptionTest.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Stripe\Plan;
|
||||
use Stripe\Stripe;
|
||||
use Stripe\Product;
|
||||
use Tests\FeatureTestCase;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Cashier\Subscription;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class AccountSubscriptionTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $stripePrefix = 'cashier-test-';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $productId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $monthlyPlanId;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $annualPlanId;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (! static::$productId) {
|
||||
$this->markTestSkipped('Set STRIPE_SECRET to run this test.');
|
||||
} else {
|
||||
config([
|
||||
'services.stripe.secret' => env('STRIPE_SECRET'),
|
||||
'monica.requires_subscription' => true,
|
||||
'monica.paid_plan_monthly_friendly_name' => 'Monthly',
|
||||
'monica.paid_plan_monthly_id' => 'monthly',
|
||||
'monica.paid_plan_monthly_price' => 100,
|
||||
'monica.paid_plan_annual_friendly_name' => 'Annual',
|
||||
'monica.paid_plan_annual_id' => 'annual',
|
||||
'monica.paid_plan_annual_price' => 500,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
if (empty(env('STRIPE_SECRET'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
Stripe::setApiVersion('2019-03-14');
|
||||
Stripe::setApiKey(env('STRIPE_SECRET'));
|
||||
|
||||
static::$productId = static::$stripePrefix.'product-'.Str::random(10);
|
||||
static::$monthlyPlanId = static::$stripePrefix.'monthly-'.Str::random(10);
|
||||
static::$annualPlanId = static::$stripePrefix.'annual-'.Str::random(10);
|
||||
|
||||
Product::create([
|
||||
'id' => static::$productId,
|
||||
'name' => 'Monica Test Product',
|
||||
'type' => 'service',
|
||||
]);
|
||||
|
||||
Plan::create([
|
||||
'id' => static::$monthlyPlanId,
|
||||
'nickname' => 'Monthly',
|
||||
'currency' => 'USD',
|
||||
'interval' => 'month',
|
||||
'billing_scheme' => 'per_unit',
|
||||
'amount' => 100,
|
||||
'product' => static::$productId,
|
||||
]);
|
||||
Plan::create([
|
||||
'id' => static::$annualPlanId,
|
||||
'nickname' => 'Annual',
|
||||
'currency' => 'USD',
|
||||
'interval' => 'year',
|
||||
'billing_scheme' => 'per_unit',
|
||||
'amount' => 500,
|
||||
'product' => static::$productId,
|
||||
]);
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
parent::tearDownAfterClass();
|
||||
|
||||
if (static::$monthlyPlanId) {
|
||||
static::deleteStripeResource(new Plan(static::$monthlyPlanId));
|
||||
static::$monthlyPlanId = null;
|
||||
}
|
||||
if (static::$annualPlanId) {
|
||||
static::deleteStripeResource(new Plan(static::$annualPlanId));
|
||||
static::$annualPlanId = null;
|
||||
}
|
||||
if (static::$productId) {
|
||||
static::deleteStripeResource(new Product(static::$productId));
|
||||
static::$productId = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected static function deleteStripeResource($resource)
|
||||
{
|
||||
try {
|
||||
if (method_exists($resource, 'delete')) {
|
||||
$resource->delete();
|
||||
}
|
||||
} catch (\Stripe\Exception\ApiErrorException $e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
public function test_it_throw_an_error_on_subscribe()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_throw_an_error_on_subscribe@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
$this->expectException(\App\Exceptions\StripeException::class);
|
||||
$user->account->subscribe('xxx', 'annual');
|
||||
}
|
||||
|
||||
public function test_it_sees_the_plan_names()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->get('/settings/subscriptions');
|
||||
|
||||
$response->assertSee('Pick a plan below and join over 0 persons who upgraded their Monica.');
|
||||
}
|
||||
|
||||
public function test_it_get_the_plan_name()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Subscription::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'Annual',
|
||||
'stripe_price' => 'annual',
|
||||
'stripe_id' => 'test',
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->assertEquals('Annual', $user->account->getSubscribedPlanName());
|
||||
}
|
||||
|
||||
public function test_it_throw_an_error_on_cancel()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Subscription::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'Annual',
|
||||
'stripe_price' => 'annual',
|
||||
'stripe_id' => 'test',
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->expectException(\App\Exceptions\StripeException::class);
|
||||
$user->account->subscriptionCancel();
|
||||
}
|
||||
|
||||
public function test_it_get_subscription_page()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
factory(Subscription::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'Annual',
|
||||
'stripe_price' => 'annual',
|
||||
'stripe_id' => 'sub_X',
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->get('/settings/subscriptions');
|
||||
|
||||
$response->assertSee('You are on the Annual plan. Thanks so much for being a subscriber.');
|
||||
}
|
||||
|
||||
public function test_it_get_upgrade_page()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->get('/settings/subscriptions/upgrade?plan=annual');
|
||||
|
||||
$response->assertSee('You picked the annual plan.');
|
||||
}
|
||||
|
||||
public function test_it_subscribe()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_subscribe@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
$response = $this->post('/settings/subscriptions/processPayment', [
|
||||
'payment_method' => 'pm_card_visa',
|
||||
'plan' => 'annual',
|
||||
]);
|
||||
|
||||
$response->assertRedirect('/settings/subscriptions/upgrade/success');
|
||||
}
|
||||
|
||||
// public function test_it_subscribe_with_2nd_auth()
|
||||
// {
|
||||
// $user = $this->signin();
|
||||
// $user->email = 'test_it_subscribe_with_2nd_auth@monica-test.com';
|
||||
// $user->save();
|
||||
|
||||
// $response = $this->followingRedirects()->post('/settings/subscriptions/processPayment', [
|
||||
// 'payment_method' => 'pm_card_threeDSecure2Required',
|
||||
// 'plan' => 'annual',
|
||||
// ]);
|
||||
|
||||
// $response->assertSee('Extra confirmation is needed to process your payment.');
|
||||
// }
|
||||
|
||||
public function test_it_subscribe_with_error()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_subscribe_with_error@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
$response = $this->post('/settings/subscriptions/processPayment', [
|
||||
'payment_method' => 'error',
|
||||
'plan' => 'annual',
|
||||
], [
|
||||
'HTTP_REFERER' => 'back',
|
||||
]);
|
||||
|
||||
$response->assertRedirect('/back');
|
||||
}
|
||||
|
||||
public function test_it_does_not_subscribe()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_does_not_subscribe@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
try {
|
||||
$user->account->subscribe('pm_card_chargeDeclined', 'annual');
|
||||
} catch (\App\Exceptions\StripeException $e) {
|
||||
$this->assertEquals('Your card was declined. Decline message is: Your card was declined.', $e->getMessage());
|
||||
|
||||
return;
|
||||
}
|
||||
$this->fail();
|
||||
}
|
||||
|
||||
public function test_it_get_blank_page_on_update_if_not_subscribed()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$response = $this->get('/settings/subscriptions/update');
|
||||
|
||||
$response->assertSee('Upgrade Monica today and have more meaningful relationships.');
|
||||
}
|
||||
|
||||
public function test_it_get_subscription_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_subscribe@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
$response = $this->post('/settings/subscriptions/processPayment', [
|
||||
'payment_method' => 'pm_card_visa',
|
||||
'plan' => 'annual',
|
||||
]);
|
||||
|
||||
$response = $this->get('/settings/subscriptions/update');
|
||||
|
||||
$response->assertSee('Monthly – $1.00');
|
||||
$response->assertSee('Annual – $5.00');
|
||||
}
|
||||
|
||||
public function test_it_process_subscription_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$user->email = 'test_it_subscribe@monica-test.com';
|
||||
$user->save();
|
||||
|
||||
$response = $this->post('/settings/subscriptions/processPayment', [
|
||||
'payment_method' => 'pm_card_visa',
|
||||
'plan' => 'monthly',
|
||||
]);
|
||||
|
||||
$response = $this->followingRedirects()->post('/settings/subscriptions/update', [
|
||||
'frequency' => 'annual',
|
||||
]);
|
||||
|
||||
$response->assertSee('You are on the Annual plan.');
|
||||
}
|
||||
}
|
||||
574
tests/Feature/ActivityTest.php
Normal file
574
tests/Feature/ActivityTest.php
Normal file
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User\User;
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Account\Activity;
|
||||
use App\Models\Account\ActivityType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ActivityTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructure = [
|
||||
'id',
|
||||
'object',
|
||||
'summary',
|
||||
'description',
|
||||
'happened_at',
|
||||
'activity_type',
|
||||
'attendees' => [
|
||||
'total',
|
||||
'contacts',
|
||||
],
|
||||
'emotions',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected $jsonStructureContacts = [
|
||||
'id',
|
||||
'name',
|
||||
];
|
||||
|
||||
protected $jsonActivity = [
|
||||
'id',
|
||||
'object',
|
||||
'summary',
|
||||
'description',
|
||||
'happened_at',
|
||||
'activity_type' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'location_type',
|
||||
'activity_type_category' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'account'=> [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
],
|
||||
'attendees' => [
|
||||
'total',
|
||||
'contacts' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'complete_name',
|
||||
],
|
||||
],
|
||||
],
|
||||
'emotions' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
],
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected $jsonActivityNoCategory = [
|
||||
'id',
|
||||
'object',
|
||||
'summary',
|
||||
'description',
|
||||
'happened_at',
|
||||
'attendees' => [
|
||||
'total',
|
||||
'contacts' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'complete_name',
|
||||
],
|
||||
],
|
||||
],
|
||||
'emotions' => [
|
||||
'*' => [
|
||||
'id',
|
||||
'object',
|
||||
'name',
|
||||
],
|
||||
],
|
||||
'account' => [
|
||||
'id',
|
||||
],
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
private function createActivityAndAttachToContact(User $user, Contact $contact)
|
||||
{
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity->contacts()->syncWithoutDetaching([$contact->id => [
|
||||
'account_id' => $activity->account_id,
|
||||
]]);
|
||||
}
|
||||
|
||||
public function test_it_gets_the_list_of_activities()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$this->createActivityAndAttachToContact($user, $contact);
|
||||
$this->createActivityAndAttachToContact($user, $contact);
|
||||
$this->createActivityAndAttachToContact($user, $contact);
|
||||
|
||||
$response = $this->json('GET', '/people/'.$contact->hashID().'/activities');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructure,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
3,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
}
|
||||
|
||||
public function test_it_gets_the_list_of_contacts_to_associate_with_the_activity()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
// also create of other contacts in the account
|
||||
factory(Contact::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/people/'.$contact->hashID().'/activities/contacts/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'*' => $this->jsonStructureContacts,
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
3,
|
||||
$response->decodeResponseJson()
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(201);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivity,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'description' => 'the description',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_wrong_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/activities', [
|
||||
'contact_id' => [$contact->id],
|
||||
]);
|
||||
|
||||
$response->assertStatus(422);
|
||||
$response->assertJson([
|
||||
'errors' => [
|
||||
'summary' => ['The summary field is required.'],
|
||||
'happened_at' => ['The happened at field is required.'],
|
||||
'contacts' => ['The contacts field is required.'],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_bad_account()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => "No query results for model [App\\Models\\Contact\\Contact] {$contact->id}",
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_create_error_bad_account2()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$activityType = factory(ActivityType::class)->create();
|
||||
|
||||
$response = $this->json('POST', '/activities', [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => "No query results for model [App\\Models\\Account\\ActivityType] {$activityType->id}",
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivityNoCategory,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivity,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$activity_type_id = $response->json('data.activity_type.id');
|
||||
$this->assertEquals($activityType->id, $activity_type_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activityType',
|
||||
'id' => $activity_type_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
'activity_type_id' => $activityType->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_existing()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact->activities()->attach($activity, [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact2->activities()->attach($activity, [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'activity_id' => $activity->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertJsonStructure([
|
||||
'data' => $this->jsonActivityNoCategory,
|
||||
]);
|
||||
$activity_id = $response->json('data.id');
|
||||
$this->assertEquals($activity->id, $activity_id);
|
||||
$response->assertJsonFragment([
|
||||
'object' => 'activity',
|
||||
'id' => $activity_id,
|
||||
]);
|
||||
|
||||
$this->assertGreaterThan(0, $activity_id);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity_id,
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
$this->assertDatabaseHas('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
$this->assertDatabaseMissing('activity_contact', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact2->id,
|
||||
'activity_id' => $activity_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_parameter()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('PUT', '/activities/0', [
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => 'No query results for model [App\\Models\\Account\\Activity] 0',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_account_for_activity()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$activity = factory(Activity::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => "No query results for model [App\\Models\\Account\\Activity] {$activity->id}",
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_update_error_wrong_account_for_contacts()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/activities/'.$activity->id, [
|
||||
'contacts' => [$contact->id],
|
||||
'description' => 'the description',
|
||||
'summary' => 'the activity',
|
||||
'happened_at' => '2018-05-01',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => "No query results for model [App\\Models\\Contact\\Contact] {$contact->id}",
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$activity = factory(Activity::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$this->assertDatabaseHas('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/activities/'.$activity->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->assertDatabaseMissing('activities', [
|
||||
'account_id' => $user->account_id,
|
||||
'id' => $activity->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete_error()
|
||||
{
|
||||
$this->signin();
|
||||
|
||||
$response = $this->json('DELETE', '/activities/0');
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => 'No query results for model [App\\Models\\Account\\Activity] 0',
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function activities_delete_with_wrong_account()
|
||||
{
|
||||
$this->signin();
|
||||
$activity = factory(Activity::class)->create();
|
||||
|
||||
$response = $this->json('DELETE', '/activities/'.$activity->id);
|
||||
|
||||
$response->assertStatus(404);
|
||||
$response->assertJson([
|
||||
'message' => "No query results for model [App\\Models\\Account\\Activity] {$activity->id}",
|
||||
]);
|
||||
}
|
||||
}
|
||||
102
tests/Feature/ActivityTypeCategoriesTest.php
Normal file
102
tests/Feature/ActivityTypeCategoriesTest.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Account\ActivityTypeCategory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ActivityTypeCategoriesTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureActivityTypeCategory = [
|
||||
'id',
|
||||
'name',
|
||||
];
|
||||
|
||||
public function test_it_gets_activity_type_categories()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategories = factory(ActivityTypeCategory::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/settings/personalization/activitytypecategories');
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'*' => $this->jsonStructureActivityTypeCategory,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_stores_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/settings/personalization/activitytypecategories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_type_categories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_updates_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/settings/personalization/activitytypecategories/'.$activityTypeCategory->id, [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_type_categories', [
|
||||
'id' => $activityTypeCategory->id,
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_activity_type_category_update_bad_account()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create();
|
||||
|
||||
$response = $this->json('PUT', '/settings/personalization/activitytypecategories/'.$activityTypeCategory->id, [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
|
||||
$response->assertStatus(404);
|
||||
|
||||
$this->assertDatabaseMissing('activity_type_categories', [
|
||||
'id' => $activityTypeCategory->id,
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_deletes_a_activity_type_category()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('DELETE', '/settings/personalization/activitytypecategories/'.$activityTypeCategory->id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseMissing('activity_type_categories', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
}
|
||||
}
|
||||
60
tests/Feature/ActivityTypesTest.php
Normal file
60
tests/Feature/ActivityTypesTest.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Account\ActivityType;
|
||||
use App\Models\Account\ActivityTypeCategory;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ActivityTypesTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructureActivityType = [
|
||||
'id',
|
||||
'name',
|
||||
'location_type',
|
||||
];
|
||||
|
||||
public function test_it_stores_a_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityTypeCategory = factory(ActivityTypeCategory::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/settings/personalization/activitytypes', [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_types', [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityTypeCategory->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_updates_a_activity_type()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$activityType = factory(ActivityType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('PUT', '/settings/personalization/activitytypes/'.$activityType->id, [
|
||||
'name' => 'Movies',
|
||||
'activity_type_category_id' => $activityType->activity_type_category_id,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('activity_types', [
|
||||
'name' => 'Movies',
|
||||
]);
|
||||
}
|
||||
}
|
||||
133
tests/Feature/AddressTest.php
Normal file
133
tests/Feature/AddressTest.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Contact\Address;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Helpers\CountriesHelper;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class AddressTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
public function test_users_can_get_countries()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$response = $this->get('/countries');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$countries = CountriesHelper::getAll();
|
||||
|
||||
$response->assertSee($countries->first()['country']);
|
||||
}
|
||||
|
||||
public function test_users_can_get_addresses()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$address = factory(Address::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'test',
|
||||
]);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/addresses');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('test');
|
||||
}
|
||||
|
||||
public function test_users_can_add_addresses()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$params = [
|
||||
'name' => 'test',
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/addresses', $params);
|
||||
|
||||
$response->assertStatus(201);
|
||||
|
||||
$params['account_id'] = $user->account_id;
|
||||
$params['contact_id'] = $contact->id;
|
||||
$params['name'] = 'test';
|
||||
|
||||
$this->assertDatabaseHas('addresses', $params);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/addresses');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('test');
|
||||
}
|
||||
|
||||
public function test_users_can_edit_addresses()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$params = [
|
||||
'name' => 'test2',
|
||||
];
|
||||
|
||||
$address = factory(Address::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->put('/people/'.$contact->hashID().'/addresses/'.$address->id, $params);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$params['account_id'] = $user->account_id;
|
||||
$params['contact_id'] = $contact->id;
|
||||
$params['name'] = 'test2';
|
||||
|
||||
$this->assertDatabaseHas('addresses', $params);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/addresses');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('test2');
|
||||
}
|
||||
|
||||
public function test_users_can_delete_addresses()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$address = factory(Address::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->delete('/people/'.$contact->hashID().'/addresses/'.$address->id);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$params = ['id' => $address->id];
|
||||
|
||||
$this->assertDatabaseMissing('addresses', $params);
|
||||
}
|
||||
}
|
||||
16
tests/Feature/Authentication/AuthenticateTest.php
Normal file
16
tests/Feature/Authentication/AuthenticateTest.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Authentication;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
|
||||
class AuthenticateTest extends FeatureTestCase
|
||||
{
|
||||
public function test_guest_is_redirect_to_login()
|
||||
{
|
||||
$response = $this->get('/people');
|
||||
|
||||
$response->assertStatus(302);
|
||||
$response->assertRedirect('/');
|
||||
}
|
||||
}
|
||||
137
tests/Feature/AvatarTest.php
Normal file
137
tests/Feature/AvatarTest.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
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 AvatarTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
public function test_user_can_add_an_avatar_as_photo()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
Storage::fake('public');
|
||||
$file = UploadedFile::fake()->image('avatar.jpg');
|
||||
|
||||
$params = [
|
||||
'avatar' => 'upload',
|
||||
'photo' => $file,
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/avatar', $params);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
// Assert the photo has been added for the correct user.
|
||||
$this->assertDatabaseHas('photos', [
|
||||
'account_id' => $user->account_id,
|
||||
'original_filename' => 'avatar.jpg',
|
||||
'new_filename' => 'photos/'.$file->hashName(),
|
||||
]);
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'avatar_source' => 'photo',
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_photo', [
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
Storage::disk('public')->assertExists('photos/'.$file->hashName());
|
||||
}
|
||||
|
||||
public function test_user_can_add_an_avatar_as_adorable()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$params = [
|
||||
'avatar' => 'adorable',
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/avatar', $params);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'avatar_source' => 'adorable',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_associate_an_avatar_as_photo()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
Storage::fake('public');
|
||||
$file = UploadedFile::fake()->image('avatar.jpg');
|
||||
|
||||
$params = [
|
||||
'avatar' => 'upload',
|
||||
'photo' => $file,
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/avatar', $params);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$contact->refresh();
|
||||
$photo = $contact->photos->first();
|
||||
|
||||
$contact2 = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->post('/people/'.$contact2->hashID().'/makeProfilePicture/'.$photo->id);
|
||||
|
||||
// Assert the photo has been added for the correct user.
|
||||
$this->assertDatabaseHas('photos', [
|
||||
'id' => $photo->id,
|
||||
'account_id' => $user->account_id,
|
||||
'original_filename' => 'avatar.jpg',
|
||||
'new_filename' => 'photos/'.$file->hashName(),
|
||||
]);
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'avatar_source' => 'photo',
|
||||
]);
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact2->id,
|
||||
'account_id' => $user->account_id,
|
||||
'avatar_source' => 'photo',
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_photo', [
|
||||
'contact_id' => $contact->id,
|
||||
'photo_id' => $photo->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('contact_photo', [
|
||||
'contact_id' => $contact2->id,
|
||||
'photo_id' => $photo->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
138
tests/Feature/CallsTest.php
Normal file
138
tests/Feature/CallsTest.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Models\Contact\Call;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Services\Contact\Call\CreateCall;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class CallsTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructure = [
|
||||
'id',
|
||||
'object',
|
||||
'called_at',
|
||||
'content',
|
||||
'contact',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
protected $jsonDashboardStructure = [
|
||||
'id',
|
||||
'called_at',
|
||||
'name',
|
||||
'contact_id',
|
||||
];
|
||||
|
||||
public function test_it_gets_the_list_of_calls()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
factory(Call::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/people/'.$contact->hashID().'/calls');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructure,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_last_talked_to()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$referenceDate = now();
|
||||
|
||||
app(CreateCall::class)->execute([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'called_at' => $referenceDate->format('Y-m-d'),
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', "/people/{$contact->hashId()}/calls/last");
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'last_talked_to',
|
||||
]);
|
||||
|
||||
$this->assertEquals($response->json('last_talked_to'), DateHelper::getShortDate($referenceDate));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_empty_last_talked_to()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', "/people/{$contact->hashId()}/calls/last");
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'last_talked_to',
|
||||
]);
|
||||
|
||||
$this->assertNull($response->json('last_talked_to'));
|
||||
}
|
||||
|
||||
public function test_dashboard_calls()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'first_name' => 'Éric',
|
||||
'last_name' => 'Çezt',
|
||||
]);
|
||||
|
||||
factory(Call::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/dashboard/calls');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'*' => $this->jsonDashboardStructure,
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$response->decodeResponseJson()
|
||||
);
|
||||
}
|
||||
}
|
||||
159
tests/Feature/ContactFieldTest.php
Normal file
159
tests/Feature/ContactFieldTest.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\ContactField;
|
||||
use App\Models\Contact\ContactFieldType;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ContactFieldTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
public function test_user_can_get_contact_fields()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
]);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/contactfield');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee($contactField->data);
|
||||
}
|
||||
|
||||
public function test_user_can_get_contact_field_types()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/contactfieldtypes');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee($field->name);
|
||||
}
|
||||
|
||||
public function test_users_can_add_contact_field()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'Test Name',
|
||||
'type' => 'test',
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'contact_field_type_id' => $field->id,
|
||||
'data' => 'test_data',
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/contactfield', $params);
|
||||
|
||||
$response->assertStatus(201);
|
||||
|
||||
$params['account_id'] = $user->account_id;
|
||||
$params['contact_id'] = $contact->id;
|
||||
$params['data'] = 'test_data';
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', $params);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/contactfield');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('test_data');
|
||||
}
|
||||
|
||||
public function test_users_can_edit_contact_field()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$params = ['data' => 'test_data'];
|
||||
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'Test Name',
|
||||
'type' => 'test',
|
||||
]);
|
||||
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
]);
|
||||
|
||||
$params['id'] = $contactField->id;
|
||||
$params['contact_field_type_id'] = $field->id;
|
||||
|
||||
$response = $this->put('/people/'.$contact->hashID().'/contactfield/'.$contactField->id, $params);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$params['account_id'] = $user->account_id;
|
||||
$params['contact_id'] = $contact->id;
|
||||
$params['data'] = 'test_data';
|
||||
|
||||
$this->assertDatabaseHas('contact_fields', $params);
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/contactfield');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertSee('test_data');
|
||||
}
|
||||
|
||||
public function test_users_can_delete_addresses()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$field = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$contactField = factory(ContactField::class)->create([
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
'contact_field_type_id' => $field->id,
|
||||
]);
|
||||
|
||||
$response = $this->delete('/people/'.$contact->hashID().'/contactfield/'.$contactField->id);
|
||||
$response->assertStatus(200);
|
||||
|
||||
$params = ['id' => $contactField->id];
|
||||
|
||||
$this->assertDatabaseMissing('contact_fields', $params);
|
||||
}
|
||||
}
|
||||
705
tests/Feature/ContactTest.php
Normal file
705
tests/Feature/ContactTest.php
Normal file
@@ -0,0 +1,705 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Helpers\DateHelper;
|
||||
use App\Models\Contact\Tag;
|
||||
use App\Models\Contact\Gift;
|
||||
use App\Models\Contact\Gender;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Account\Activity;
|
||||
use App\Models\Contact\Reminder;
|
||||
use App\Models\Settings\Currency;
|
||||
use Illuminate\Foundation\Testing\WithFaker;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ContactTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions, WithFaker;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
public function test_user_can_query_search_contacts()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$keyword = $randomContact->first_name.' '.$randomContact->last_name;
|
||||
|
||||
$records = Contact::search($keyword, $user->account_id, 'id')->get();
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, count($records));
|
||||
}
|
||||
|
||||
public function test_user_can_query_search_no_result()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contacts = factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$keyword = 'no_result_with_this_keyword';
|
||||
|
||||
$records = Contact::search($keyword, $user->account_id, 'id')->get();
|
||||
|
||||
$this->assertEquals(0, count($records));
|
||||
}
|
||||
|
||||
public function test_user_can_search_one_contact_firstname()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$response = $this->post('/people/search', [
|
||||
'needle' => $randomContact->first_name,
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $randomContact->id,
|
||||
'complete_name' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_search_one_contact_lastname()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$response = $this->post('/people/search', [
|
||||
'needle' => $randomContact->last_name,
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $randomContact->id,
|
||||
'complete_name' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_search_one_contact_firstname_lastname()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$response = $this->post('/people/search', [
|
||||
'needle' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $randomContact->id,
|
||||
'complete_name' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_search_one_contact_lastname_firstname()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$response = $this->post('/people/search', [
|
||||
'needle' => $randomContact->last_name.' '.$randomContact->first_name,
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $randomContact->id,
|
||||
'complete_name' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_search_one_contact_no_result()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->post('/people/search', [
|
||||
'needle' => 'no_result_with_this needle',
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'noResults' => 'No results found',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_list_one_contact_firstname()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$randomContact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$response = $this->get('/people/list?search='.$randomContact->first_name);
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $randomContact->id,
|
||||
'complete_name' => $randomContact->first_name.' '.$randomContact->last_name,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_list_contacts_with_tags()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'c++',
|
||||
]);
|
||||
$contact->tags()->sync([
|
||||
$tag->id => [
|
||||
'account_id' => $user->account_id,
|
||||
],
|
||||
]);
|
||||
|
||||
$response = $this->get('/people/list?tags[]='.urlencode($tag->name));
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertJsonFragment([
|
||||
'id' => $contact->id,
|
||||
'complete_name' => $contact->first_name.' '.$contact->last_name,
|
||||
]);
|
||||
$response->assertJsonCount(1, 'contacts');
|
||||
}
|
||||
|
||||
public function test_user_can_show_contacts_with_tags()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
factory(Contact::class, 10)->state('named')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
$contact = Contact::where('account_id', $user->account_id)
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
$tag = factory(Tag::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'name' => 'c++',
|
||||
]);
|
||||
$contact->tags()->sync([
|
||||
$tag->id => [
|
||||
'account_id' => $user->account_id,
|
||||
],
|
||||
]);
|
||||
|
||||
$response = $this->get('/people?tags[]='.urlencode($tag->name));
|
||||
|
||||
$response->assertSuccessful();
|
||||
$response->assertSee('1 contact');
|
||||
}
|
||||
|
||||
public function test_user_can_see_contacts()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
$response = $this->get('/people');
|
||||
$response->assertSee('1 contact');
|
||||
}
|
||||
|
||||
private function setUpContacts()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contacts = factory(Contact::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
factory(Activity::class)->create([
|
||||
'account_id' => $contact->account_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function test_user_can_see_contacts_sorted_by_lastactivitydateNewtoOld()
|
||||
{
|
||||
$this->setUpContacts();
|
||||
|
||||
$response = $this->get('/people/list?sort=lastactivitydateNewtoOld');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'totalRecords' => 10,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_see_contacts_sorted_by_lastactivitydateOldtoNew()
|
||||
{
|
||||
$this->setUpContacts();
|
||||
|
||||
$response = $this->get('/people/list?sort=lastactivitydateOldtoNew');
|
||||
|
||||
$response->assertJsonFragment([
|
||||
'totalRecords' => 10,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_be_reminded_about_an_event_once()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$reminder = [
|
||||
'title' => $this->faker->sentence('5'),
|
||||
'initial_date' => DateHelper::getDate(DateHelper::parseDateTime($this->faker->dateTimeBetween('now', '+2 years'))),
|
||||
'frequency_type' => 'one_time',
|
||||
'description' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$this->post(
|
||||
route('people.reminders.store', $contact),
|
||||
$reminder
|
||||
);
|
||||
|
||||
$this->assertDatabaseHas(
|
||||
'reminders',
|
||||
array_merge($reminder, [
|
||||
'frequency_type' => 'one_time',
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
public function test_user_can_add_a_task_to_a_contact()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$task = [
|
||||
'title' => $this->faker->sentence(),
|
||||
'description' => $this->faker->sentence(3),
|
||||
'completed' => 0,
|
||||
'contact_id' => $contact->id,
|
||||
];
|
||||
|
||||
$this->post(
|
||||
'/tasks',
|
||||
$task
|
||||
);
|
||||
|
||||
$this->assertDatabaseHas(
|
||||
'tasks',
|
||||
$task + [
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function test_user_can_be_in_debt_to_a_contact()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$debt = [
|
||||
'in_debt' => 'yes',
|
||||
'amount' => $this->faker->numberBetween(1, 5000),
|
||||
'reason' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$response = $this->post(
|
||||
route('people.debts.store', $contact),
|
||||
$debt
|
||||
);
|
||||
$response->assertStatus(302);
|
||||
|
||||
$debt['amount'] = $debt['amount'] * 100;
|
||||
$this->assertDatabaseHas('debts',
|
||||
$debt + [
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_can_be_owed_debt_by_a_contact()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$debt = [
|
||||
'in_debt' => 'no',
|
||||
'amount' => $this->faker->numberBetween(1, 5000),
|
||||
'reason' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$response = $this->post(
|
||||
route('people.debts.store', $contact),
|
||||
$debt
|
||||
);
|
||||
$response->assertStatus(302);
|
||||
|
||||
$debt['amount'] = $debt['amount'] * 100;
|
||||
$this->assertDatabaseHas('debts',
|
||||
$debt + [
|
||||
'contact_id' => $contact->id,
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_a_contact_edit_food_preferences()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/food');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('Indicate food preferences');
|
||||
}
|
||||
|
||||
public function test_a_contact_can_have_food_preferences()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$food = ['food' => $this->faker->sentence()];
|
||||
|
||||
$this->post('/people/'.$contact->hashID().'/food/save', $food);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'food_preferences' => $food['food'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_a_contact_edit_work()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/work/edit');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee("Update {$contact->first_name}’s job information");
|
||||
}
|
||||
|
||||
public function test_a_contact_can_update_work()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$input = [
|
||||
'job' => $this->faker->sentence(),
|
||||
'company' => $this->faker->sentence(),
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/work/update', $input);
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'job' => $input['job'],
|
||||
'company' => $input['company'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_a_contact_can_have_its_last_name_removed()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$data = [
|
||||
'firstname' => $contact->first_name,
|
||||
'lastname' => '',
|
||||
'gender' => $contact->gender_id,
|
||||
'birthdate' => 'unknown',
|
||||
];
|
||||
|
||||
$this->put('/people/'.$contact->hashID(), $data);
|
||||
|
||||
$data['id'] = $contact->id;
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'last_name' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_cant_add_new_contacts_if_limit_reached()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$contacts = factory(Contact::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
config(['monica.number_of_allowed_contacts_free_account' => 1]);
|
||||
config(['monica.requires_subscription' => true]);
|
||||
|
||||
$response = $this->get('/people/add');
|
||||
|
||||
$response->assertRedirect('/settings/subscriptions');
|
||||
}
|
||||
|
||||
public function test_user_can_add_new_contacts_when_instance_requires_no_subscription()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$contacts = factory(Contact::class, 3)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
config(['monica.number_of_allowed_contacts_free_account' => 1]);
|
||||
config(['monica.requires_subscription' => false]);
|
||||
|
||||
$response = $this->get('/people/add');
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
|
||||
public function test_viewing_a_user_increments_the_number_of_views()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'number_of_views' => 0,
|
||||
]);
|
||||
|
||||
$this->get('/people/'.$contact->hashID());
|
||||
$this->get('/people/'.$contact->hashID());
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'number_of_views' => 2,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_vcard_download()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/vcard');
|
||||
|
||||
$response->assertOk();
|
||||
$response->assertHeader('Content-type', 'text/x-vcard; charset=UTF-8');
|
||||
$response->assertSee('FN:John Doe');
|
||||
$response->assertSee('N:Doe;John;;;');
|
||||
}
|
||||
|
||||
public function test_edit_contact_has_specialdeceased()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/edit');
|
||||
|
||||
$response->assertSee('<form-specialdeceased
|
||||
:value="false"
|
||||
:date="\'\'"
|
||||
:reminder="false"
|
||||
>
|
||||
</form-specialdeceased>', false);
|
||||
}
|
||||
|
||||
public function test_edit_contact_with_specialdeceased()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$reminder = factory(Reminder::class)->create([
|
||||
'account_id' => $contact->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$contact->is_dead = true;
|
||||
$contact->deceased_reminder_id = $reminder->id;
|
||||
$contact->save();
|
||||
|
||||
$response = $this->get('/people/'.$contact->hashID().'/edit');
|
||||
|
||||
$response->assertSee('<form-specialdeceased
|
||||
:value="true"
|
||||
:date="\''.$reminder->initial_date.'\'"
|
||||
:reminder="true"
|
||||
>
|
||||
</form-specialdeceased>', false);
|
||||
}
|
||||
|
||||
public function test_edit_contact_put_deceased()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$data = [
|
||||
'firstname' => $contact->first_name,
|
||||
'lastname' => $contact->last_name,
|
||||
'gender' => $contact->gender_id,
|
||||
'birthdate' => 'unknown',
|
||||
'is_deceased' => 'true',
|
||||
'is_deceased_date_known' => 'true',
|
||||
'deceased_date' => '2012-06-22',
|
||||
];
|
||||
|
||||
$this->put('/people/'.$contact->hashID(), $data);
|
||||
|
||||
$data['id'] = $contact->id;
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'is_dead' => true,
|
||||
]);
|
||||
|
||||
$contact->refresh();
|
||||
$this->assertDatabaseHas('special_dates', [
|
||||
'id' => $contact->deceased_special_date_id,
|
||||
'date' => '2012-06-22',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_edit_contact_put_deceased_dont_stay_in_touch()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$data = [
|
||||
'firstname' => $contact->first_name,
|
||||
'lastname' => $contact->last_name,
|
||||
'gender' => $contact->gender_id,
|
||||
'birthdate' => 'unknown',
|
||||
'is_deceased' => 'true',
|
||||
'is_deceased_date_known' => 'true',
|
||||
'deceased_date' => '2012-06-22',
|
||||
'stay_in_touch_frequency' => 11,
|
||||
'stay_in_touch_trigger_date' => '2012-06-22',
|
||||
];
|
||||
|
||||
$this->put('/people/'.$contact->hashID(), $data);
|
||||
|
||||
$contact->updateStayInTouchFrequency(0);
|
||||
$contact->setStayInTouchTriggerDate(0);
|
||||
|
||||
$data['id'] = $contact->id;
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'is_dead' => true,
|
||||
'stay_in_touch_frequency' => null,
|
||||
'stay_in_touch_trigger_date' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_edit_contact_put_deceased_with_reminder()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
|
||||
$data = [
|
||||
'firstname' => $contact->first_name,
|
||||
'lastname' => $contact->last_name,
|
||||
'gender' => $contact->gender_id,
|
||||
'birthdate' => 'unknown',
|
||||
'is_deceased' => 'true',
|
||||
'is_deceased_date_known' => 'true',
|
||||
'deceased_date' => '2012-06-22',
|
||||
'add_reminder_deceased' => 'true',
|
||||
];
|
||||
|
||||
$this->put('/people/'.$contact->hashID(), $data);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'is_dead' => true,
|
||||
]);
|
||||
|
||||
$contact->refresh();
|
||||
$this->assertDatabaseHas('special_dates', [
|
||||
'id' => $contact->deceased_special_date_id,
|
||||
'date' => '2012-06-22',
|
||||
]);
|
||||
$this->assertDatabaseHas('reminders', [
|
||||
'id' => $contact->deceased_reminder_id,
|
||||
'contact_id' => $contact->id,
|
||||
'initial_date' => '2012-06-22',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_it_create_a_contact()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$gender = factory(Gender::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$data = [
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
'middle_name' => 'Mike',
|
||||
'gender' => $gender->id,
|
||||
];
|
||||
|
||||
$response = $this->post('/people', $data);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'first_name' => 'John',
|
||||
'last_name' => 'Doe',
|
||||
'middle_name' => 'Mike',
|
||||
'gender_id' => $gender->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_the_value()
|
||||
{
|
||||
$user = $this->signin();
|
||||
$currency = factory(Currency::class)->create([
|
||||
'iso' => 'USD',
|
||||
'symbol' => '$',
|
||||
]);
|
||||
$user->currency()->associate($currency);
|
||||
$user->save();
|
||||
|
||||
$gift = factory(Gift::class)->make();
|
||||
$gift->amount = '100';
|
||||
|
||||
$this->assertEquals('100.00', $gift->amount);
|
||||
$this->assertEquals('$100.00', $gift->displayValue);
|
||||
}
|
||||
}
|
||||
57
tests/Feature/ContactsControllerTest.php
Normal file
57
tests/Feature/ContactsControllerTest.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Helpers\AccountHelper;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ContactsControllerTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_cant_unarchive_contact_if_limited_account()
|
||||
{
|
||||
config(['monica.requires_subscription' => true]);
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->state('archived')->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
factory(Contact::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$this->assertTrue(AccountHelper::hasReachedContactLimit($user->account));
|
||||
$this->assertTrue(AccountHelper::hasLimitations($user->account));
|
||||
|
||||
$response = $this->put("/people/{$contact->hashID()}/archive");
|
||||
|
||||
$response->assertStatus(402);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_stays_in_touch()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->post("/people/{$contact->hashID()}/stayintouch", [
|
||||
'frequency' => 5,
|
||||
'state' => 1,
|
||||
]);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$this->assertDatabaseHas('contacts', [
|
||||
'id' => $contact->id,
|
||||
'stay_in_touch_frequency' => 5,
|
||||
]);
|
||||
}
|
||||
}
|
||||
168
tests/Feature/ConversationTest.php
Normal file
168
tests/Feature/ConversationTest.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
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 ConversationTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Returns an array containing a user object along with
|
||||
* a contact for that user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function fetchUser()
|
||||
{
|
||||
$user = $this->signIn();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
return [$user, $contact];
|
||||
}
|
||||
|
||||
public function test_user_can_add_a_conversation()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'conversationDateRadio' => 'another',
|
||||
'conversationDate' => '2019-08-12',
|
||||
'contactFieldTypeId' => $contactFieldType->id,
|
||||
'messages' => '1',
|
||||
'who_wrote_1' => 'me',
|
||||
'content_1' => 'test',
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/conversations', $params);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('conversations', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $contactFieldType->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('messages', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'content' => 'test',
|
||||
'written_by_me' => true,
|
||||
'written_at' => '2019-08-12',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_cannot_add_a_conversation_without_message()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
$contactFieldType = factory(ContactFieldType::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'conversationDateRadio' => 'today',
|
||||
'contactFieldTypeId' => $contactFieldType->id,
|
||||
];
|
||||
|
||||
$response = $this->post('/people/'.$contact->hashID().'/conversations', $params, [
|
||||
'HTTP_REFERER' => 'back',
|
||||
]);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$response->assertRedirect('back');
|
||||
$response->assertSessionHasErrors(['messages' => 'You must add at least one message.']);
|
||||
}
|
||||
|
||||
public function test_user_can_update_a_conversation()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
$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,
|
||||
]);
|
||||
$message = factory(Message::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'content' => 'test',
|
||||
'written_by_me' => true,
|
||||
'written_at' => '2019-08-12',
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'conversationDateRadio' => 'another',
|
||||
'conversationDate' => '2019-08-01',
|
||||
'contactFieldTypeId' => $contactFieldType->id,
|
||||
'messages' => '1',
|
||||
'who_wrote_1' => 'me',
|
||||
'content_1' => 'bla bla',
|
||||
];
|
||||
|
||||
$response = $this->put('/people/'.$contact->hashID().'/conversations/'.$conversation->hashID(), $params);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('conversations', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'contact_field_type_id' => $contactFieldType->id,
|
||||
]);
|
||||
$this->assertDatabaseHas('messages', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'content' => 'bla bla',
|
||||
'written_by_me' => true,
|
||||
'written_at' => '2019-08-01',
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_user_cannot_update_a_conversation_without_message()
|
||||
{
|
||||
[$user, $contact] = $this->fetchUser();
|
||||
$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,
|
||||
]);
|
||||
$message = factory(Message::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'content' => 'test',
|
||||
'written_by_me' => true,
|
||||
'written_at' => '2019-08-12',
|
||||
]);
|
||||
|
||||
$params = [
|
||||
'conversationDateRadio' => 'today',
|
||||
'contactFieldTypeId' => $contactFieldType->id,
|
||||
];
|
||||
|
||||
$response = $this->put('/people/'.$contact->hashID().'/conversations/'.$conversation->hashID(), $params, [
|
||||
'HTTP_REFERER' => 'back',
|
||||
]);
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$response->assertRedirect('back');
|
||||
$response->assertSessionHasErrors(['messages' => 'You must add at least one message.']);
|
||||
}
|
||||
}
|
||||
55
tests/Feature/DocumentsTest.php
Normal file
55
tests/Feature/DocumentsTest.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use App\Models\Contact\Document;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class DocumentsTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
protected $jsonStructure = [
|
||||
'id',
|
||||
'object',
|
||||
'original_filename',
|
||||
'new_filename',
|
||||
'filesize',
|
||||
'type',
|
||||
'number_of_downloads',
|
||||
'contact',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
public function test_it_gets_the_list_of_documents()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
factory(Document::class, 10)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
]);
|
||||
|
||||
$response = $this->json('GET', '/people/'.$contact->hashID().'/documents');
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$response->assertJsonStructure([
|
||||
'data' => [
|
||||
'*' => $this->jsonStructure,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(
|
||||
10,
|
||||
$response->decodeResponseJson()['data']
|
||||
);
|
||||
}
|
||||
}
|
||||
81
tests/Feature/ExportAccountTest.php
Normal file
81
tests/Feature/ExportAccountTest.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use Illuminate\Support\Carbon;
|
||||
use App\Models\Account\ExportJob;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class ExportAccountTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/** @test */
|
||||
public function it_create_export_job_json()
|
||||
{
|
||||
config(['queue.default' => 'database']);
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/settings/exportToJson');
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('export_jobs', [
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'type' => ExportJob::JSON,
|
||||
'status' => ExportJob::EXPORT_TODO,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_create_export_job_sql()
|
||||
{
|
||||
config(['queue.default' => 'database']);
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
$response = $this->json('POST', '/settings/exportToSql');
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseHas('export_jobs', [
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'type' => ExportJob::SQL,
|
||||
'status' => ExportJob::EXPORT_TODO,
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_delete_old_export()
|
||||
{
|
||||
config(['queue.default' => 'database']);
|
||||
|
||||
$user = $this->signin();
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2022, 1, 1, 0, 0, 0));
|
||||
$exportJob = ExportJob::factory()->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'status' => ExportJob::EXPORT_DONE,
|
||||
]);
|
||||
|
||||
Carbon::setTestNow(Carbon::create(2022, 1, 2, 0, 0, 0));
|
||||
ExportJob::factory()->count(4)->create([
|
||||
'account_id' => $user->account_id,
|
||||
'user_id' => $user->id,
|
||||
'status' => ExportJob::EXPORT_DONE,
|
||||
]);
|
||||
|
||||
$response = $this->json('POST', '/settings/exportToJson');
|
||||
|
||||
$response->assertStatus(302);
|
||||
|
||||
$this->assertDatabaseMissing('export_jobs', [
|
||||
'id' => $exportJob->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
48
tests/Feature/InstanceTest.php
Normal file
48
tests/Feature/InstanceTest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
use App\Models\Account\Account;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class InstanceTest extends TestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
/**
|
||||
* Check if, by default, the disable signups feature is turned off in an
|
||||
* instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_disable_signup_set_to_false_shows_signup_button()
|
||||
{
|
||||
config(['monica.disable_signup' => false]);
|
||||
factory(Account::class)->create();
|
||||
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertSee(
|
||||
'Sign up'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If an instance sets `disable_signup` env variable to true, it should hide
|
||||
* the signup button on the Sign in page.
|
||||
* Also, trying to reach `/register` should lead to a 403 page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_disable_signup_set_to_true_hides_signup_button_and_register_page()
|
||||
{
|
||||
config(['monica.disable_signup' => true]);
|
||||
factory(Account::class)->create();
|
||||
|
||||
$response = $this->get('/');
|
||||
$response->assertDontSee(
|
||||
'Sign up'
|
||||
);
|
||||
}
|
||||
}
|
||||
56
tests/Feature/IntroductionsTest.php
Normal file
56
tests/Feature/IntroductionsTest.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
|
||||
class IntroductionsTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_it_display_introductions_screen()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->get("/people/{$contact->hashID()}/introductions/edit");
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee("How did you meet {$contact->first_name}");
|
||||
}
|
||||
|
||||
public function test_it_update_introductions()
|
||||
{
|
||||
$user = $this->signin();
|
||||
|
||||
$contact = factory(Contact::class)->create([
|
||||
'account_id' => $user->account_id,
|
||||
]);
|
||||
|
||||
$response = $this->post("/people/{$contact->hashID()}/introductions/update", [
|
||||
'first_met_additional_info' => 'info',
|
||||
'is_first_met_date_known' => 'known',
|
||||
'first_met_year' => 2006,
|
||||
'first_met_month' => 1,
|
||||
'first_met_day' => 2,
|
||||
'addReminder' => 'on',
|
||||
]);
|
||||
|
||||
$response->assertStatus(302);
|
||||
$response->assertRedirect("/people/{$contact->hashID()}");
|
||||
|
||||
$this->assertDatabaseHas('special_dates', [
|
||||
'account_id' => $user->account_id,
|
||||
'contact_id' => $contact->id,
|
||||
'id' => Contact::find($contact->id)->first_met_special_date_id,
|
||||
'is_age_based' => false,
|
||||
'is_year_unknown' => false,
|
||||
'date' => '2006-01-02',
|
||||
]);
|
||||
}
|
||||
}
|
||||
61
tests/Feature/InvitationTest.php
Normal file
61
tests/Feature/InvitationTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\FeatureTestCase;
|
||||
use App\Models\Account\Account;
|
||||
use App\Models\Account\Invitation;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||
|
||||
class InvitationTest extends FeatureTestCase
|
||||
{
|
||||
use DatabaseTransactions;
|
||||
|
||||
public function test_it_can_open_invitation()
|
||||
{
|
||||
$account = factory(Account::class)->create();
|
||||
|
||||
$invitation = factory(Invitation::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'email' => 'test@test.com',
|
||||
]);
|
||||
|
||||
$response = $this->get('/invitations/accept/'.$invitation->invitation_key);
|
||||
|
||||
$response->assertStatus(200);
|
||||
$response->assertSee('test@test.com');
|
||||
}
|
||||
|
||||
public function test_it_can_respond_to_invitation()
|
||||
{
|
||||
NotificationFacade::fake();
|
||||
|
||||
$account = factory(Account::class)->create();
|
||||
|
||||
$invitation = factory(Invitation::class)->create([
|
||||
'account_id' => $account->id,
|
||||
'email' => 'test@test.com',
|
||||
]);
|
||||
|
||||
$response = $this->post('/invitations/accept/'.$invitation->invitation_key, [
|
||||
'email' => 'test@test007.com',
|
||||
'first_name' => 'john',
|
||||
'last_name' => 'doe',
|
||||
'password' => 'admin0',
|
||||
'password_confirmation' => 'admin0',
|
||||
'policy' => 'true',
|
||||
'email_security' => $invitation->invitedBy->email,
|
||||
]);
|
||||
|
||||
$response->assertStatus(302);
|
||||
$response->assertRedirect('/dashboard');
|
||||
|
||||
$this->assertDataBaseHas('users', [
|
||||
'email' => 'test@test007.com',
|
||||
'first_name' => 'john',
|
||||
'last_name' => 'doe',
|
||||
'invited_by_user_id' => $invitation->invitedBy->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user