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

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

View File

@@ -0,0 +1,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.');
}
}

View 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}",
]);
}
}

View 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',
]);
}
}

View 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',
]);
}
}

View 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);
}
}

View 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('/');
}
}

View 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
View 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()
);
}
}

View 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);
}
}

View 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);
}
}

View 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,
]);
}
}

View 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.']);
}
}

View 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']
);
}
}

View 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,
]);
}
}

View 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'
);
}
}

View 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',
]);
}
}

View 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,
]);
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Journal\Entry;
use App\Models\Journal\JournalEntry;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class JournalEntryTest extends FeatureTestCase
{
use DatabaseTransactions;
public function test_user_can_add_a_journal_entry()
{
$user = $this->signIn();
$params = [
'entry' => 'Good day',
'date' => '2018-01-01',
];
$response = $this->post('/journal/create', $params);
$response->assertStatus(302);
$this->assertDatabaseHas('journal_entries', [
'account_id' => $user->account_id,
'date' => '2018-01-01 00:00:00',
'journalable_type' => 'App\Models\Journal\Entry',
]);
$this->assertDatabaseHas('entries', [
'account_id' => $user->account_id,
'post' => 'Good day',
]);
}
public function test_user_can_edit_a_journal_entry()
{
$user = $this->signIn();
$entry = factory(Entry::class)->create([
'account_id' => $user->account_id,
'title' => 'This is the title',
'post' => 'this is a post',
]);
$entry->date = '2017-01-01';
$journalEntry = JournalEntry::add($entry);
$params = [
'entry' => 'Good day',
'date' => '2018-01-01',
];
$response = $this->put('/journal/entries/'.$entry->id, $params);
$response->assertStatus(302);
$this->assertDatabaseHas('journal_entries', [
'account_id' => $user->account_id,
'date' => '2018-01-01 00:00:00',
'journalable_id' => $entry->id,
'journalable_type' => 'App\Models\Journal\Entry',
]);
$this->assertDatabaseHas('entries', [
'account_id' => $user->account_id,
'post' => 'Good day',
]);
}
public function test_user_can_delete_a_journal_entry()
{
$user = $this->signIn();
$entry = factory(Entry::class)->create([
'account_id' => $user->account_id,
'title' => 'This is the title',
'post' => 'this is a post',
]);
$entry->date = '2017-01-01';
$journalEntry = JournalEntry::add($entry);
$response = $this->delete('/journal/'.$entry->id);
$response->assertSuccessful();
$this->assertDatabaseMissing('entries', [
'id' => $entry->id,
]);
$this->assertDatabaseMissing('journal_entries', [
'id' => $journalEntry->id,
]);
}
}

87
tests/Feature/MeTest.php Normal file
View File

@@ -0,0 +1,87 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class MeTest extends FeatureTestCase
{
use DatabaseTransactions;
/** @test */
public function it_stores_me()
{
$user = $this->signin();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->json('POST', '/me/contact', [
'contact_id' => $contact->id,
]);
$response->assertStatus(200);
$response->assertJson([
'true',
]);
$this->assertDatabaseHas('users', [
'id' => $user->id,
'me_contact_id' => $contact->id,
]);
}
/** @test */
public function it_stores_error_wrong_parameter()
{
$this->signin();
$response = $this->json('POST', '/me/contact', []);
$response->assertStatus(422);
$response->assertJson([
'errors' => [
'contact_id' => ['The contact id field is required.'],
],
]);
}
/** @test */
public function it_stores_error_bad_account()
{
$this->signin();
$contact = factory(Contact::class)->create();
$response = $this->json('POST', '/me/contact', [
'contact_id' => $contact->id,
]);
$response->assertStatus(404);
$response->assertJson([
'message' => "No query results for model [App\\Models\\Contact\\Contact] {$contact->id}",
]);
}
/** @test */
public function it_deletes_me()
{
$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', '/me/contact');
$response->assertStatus(200);
$this->assertDatabaseHas('users', [
'id' => $user->id,
'me_contact_id' => null,
]);
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Contact\Note;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class NoteTest 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_note()
{
[$user, $contact] = $this->fetchUser();
$noteBody = 'This is a note that I would like to see';
$params = [
'body' => $noteBody,
'is_favorited' => 0,
];
$response = $this->post('/people/'.$contact->hashID().'/notes', $params);
// Assert the note has been added for the correct user.
$this->assertDatabaseHas('notes', [
'body' => $noteBody,
]);
}
public function test_user_can_edit_a_note()
{
[$user, $contact] = $this->fetchUser();
$note = factory(Note::class)->create([
'contact_id' => $contact->id,
'account_id' => $user->account_id,
'body' => 'this is a test',
'is_favorited' => 1,
]);
// now edit the note
$params = [
'body' => 'this is another test',
'is_favorited' => 0,
];
$this->put('/people/'.$contact->hashID().'/notes/'.$note->id, $params);
// Assert the note has been added for the correct user.
$this->assertDatabaseHas('notes', [
'body' => 'this is another test',
]);
}
public function test_user_can_delete_a_note()
{
[$user, $contact] = $this->fetchUser();
$note = factory(Note::class)->create([
'contact_id' => $contact->id,
'account_id' => $user->account_id,
'body' => 'this is a test',
]);
$response = $this->delete('/people/'.$contact->hashID().'/notes/'.$note->id);
$params = [];
$params['id'] = $note->id;
$this->assertDatabaseMissing('notes', $params);
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class PasswordChangeTest extends FeatureTestCase
{
use DatabaseTransactions;
public function test_user_can_change_password()
{
$user = $this->signIn();
$user->password = $password = bcrypt('password');
$user->save();
$response = $this->followingRedirects()->post('/settings/security/passwordChange', [
'password_current' => 'password',
'password' => 'newPassword',
'password_confirmation' => 'newPassword',
]);
$response->assertStatus(200);
$response->assertSee('Password changed successfully.');
$user->refresh();
$this->assertNotEquals($password, $user->password);
}
public function test_current_password_checked()
{
$user = $this->signIn();
$user->password = bcrypt('password');
$user->save();
$response = $this->followingRedirects()->post('/settings/security/passwordChange', [
'password_current' => 'xpassword',
'password' => 'newPassword',
'password_confirmation' => 'newPassword',
]);
$response->assertStatus(200);
$response->assertSee('Current password you entered is not correct.');
}
public function test_new_password_policy_check()
{
$user = $this->signIn();
$user->password = bcrypt('password');
$user->save();
$response = $this->followingRedirects()->post('/settings/security/passwordChange', [
'password_current' => 'password',
'password' => 'admin',
'password_confirmation' => 'admin',
], [
'HTTP_REFERER' => '/settings/security',
]);
$response->assertStatus(200);
$response->assertSee('The password must be at least 6 characters.');
}
public function test_new_password_validation_check()
{
$user = $this->signIn();
$user->password = bcrypt('password');
$user->save();
$response = $this->followingRedirects()->post('/settings/security/passwordChange', [
'password_current' => 'password',
'password' => 'admin0',
'password_confirmation' => 'admin1',
], [
'HTTP_REFERER' => '/settings/security',
]);
$response->assertStatus(200);
$response->assertSee('The password confirmation does not match.');
}
}

View File

@@ -0,0 +1,136 @@
<?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 PhotosTest extends FeatureTestCase
{
use DatabaseTransactions;
protected $jsonStructure = [
'id',
'object',
'original_filename',
'new_filename',
'filesize',
'mime_type',
'link',
'contact',
'created_at',
'updated_at',
];
/**
* 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_photo()
{
[$user, $contact] = $this->fetchUser();
Storage::fake('public');
$file = UploadedFile::fake()->image('avatar.jpg');
$params = [
'photo' => $file,
];
$response = $this->post('/people/'.$contact->hashID().'/photos', $params);
$response->assertStatus(201);
$response->assertJsonStructure([
'data' => $this->jsonStructure,
]);
// 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('contact_photo', [
'contact_id' => $contact->id,
'photo_id' => $response->json('data.id'),
]);
Storage::disk('public')->assertExists('photos/'.$file->hashName());
}
public function test_user_can_delete_a_photo()
{
[$user, $contact] = $this->fetchUser();
Storage::fake('public');
$file = UploadedFile::fake()->image('avatar.jpg');
$params = [
'photo' => $file,
];
$response1 = $this->post('/people/'.$contact->hashID().'/photos', $params);
$response2 = $this->delete('/people/'.$contact->hashID().'/photos/'.$response1->json('data.id'));
$response2->assertStatus(200);
$this->assertDatabaseMissing('photos', [
'account_id' => $user->account_id,
'original_filename' => 'avatar.jpg',
'new_filename' => 'photos/'.$file->hashName(),
]);
$this->assertDatabaseMissing('contact_photo', [
'contact_id' => $contact->id,
'photo_id' => $response1->json('data.id'),
]);
}
public function test_user_can_delete_a_photo_even_if_it_s_already_deleted()
{
[$user, $contact] = $this->fetchUser();
Storage::fake('public');
$file = UploadedFile::fake()->image('avatar.jpg');
$params = [
'photo' => $file,
];
$response1 = $this->post('/people/'.$contact->hashID().'/photos', $params);
Storage::delete($response1->json('data.new_filename'));
$response2 = $this->delete('/people/'.$contact->hashID().'/photos/'.$response1->json('data.id'));
$response2->assertStatus(200);
$this->assertDatabaseMissing('photos', [
'account_id' => $user->account_id,
'original_filename' => 'avatar.jpg',
'new_filename' => 'photos/'.$file->hashName(),
]);
$this->assertDatabaseMissing('contact_photo', [
'contact_id' => $contact->id,
'photo_id' => $response1->json('data.id'),
]);
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Tests\Feature;
use App\Models\User\User;
use Tests\FeatureTestCase;
use App\Jobs\SendNewUserAlert;
use App\Notifications\NewUserAlert;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class RegisterTest extends FeatureTestCase
{
use DatabaseTransactions;
public function test_user_can_register()
{
config(['monica.disable_signup' => false]);
Mail::fake();
$params = [
'email' => 'john.mike@doe.com',
'first_name' => 'john',
'last_name' => 'doe',
'password' => 'admin0',
'password_confirmation' => 'admin0',
'policy' => 'true',
'lang' => 'en',
];
$response = $this->post('/register', $params);
$response->assertStatus(302);
$response->assertRedirect('/dashboard');
$this->assertDatabaseHas('users', [
'email' => 'john.mike@doe.com',
]);
}
public function test_user_cannot_register_twice()
{
config(['monica.disable_signup' => false]);
Mail::fake();
$user = factory(User::class)->create();
$params = [
'email' => $user->email,
'first_name' => 'john',
'last_name' => 'doe',
'password' => 'admin0',
'password_confirmation' => 'admin0',
'policy' => 'true',
'lang' => 'en',
];
$response = $this->post('/register', $params, [
'HTTP_REFERER' => '/register',
]);
$response->assertStatus(302);
$response->assertRedirect('/register');
}
public function test_it_dispatches_an_email()
{
config(['monica.disable_signup' => false]);
$route = Notification::route('mail', 'test@test.com');
Notification::fake();
config(['monica.email_new_user_notification' => 'test@test.com']);
$user = factory(User::class)->create();
SendNewUserAlert::dispatch($user);
Notification::assertSentTo($route, NewUserAlert::class);
$notifications = Notification::sent($route, NewUserAlert::class);
$message = $notifications[0]->toMail();
$this->assertStringContainsString('New registration', $message->subject);
$this->assertStringContainsString($user->first_name, implode('', $message->introLines));
$this->assertStringContainsString($user->last_name, implode('', $message->introLines));
$this->assertStringContainsString($user->email, implode('', $message->introLines));
}
}

View File

@@ -0,0 +1,332 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Contact\Gender;
use App\Models\Contact\Contact;
use App\Models\Relationship\Relationship;
use Illuminate\Foundation\Testing\WithFaker;
use App\Models\Relationship\RelationshipType;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class RelationshipTest extends FeatureTestCase
{
use DatabaseTransactions, WithFaker;
public function test_create_a_relationship()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$response = $this->get('/people/'.$contact->hashID().'/relationships/create');
$response->assertStatus(200);
$response->assertSee('This person is…');
}
public function test_user_can_add_a_relationship()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$partner = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_type' => 'existing',
'existing_contact_id' => $partner->id,
'relationship_type_id' => $relationshipType->id,
];
$response = $this->post('/people/'.$contact->hashID().'/relationships', $params);
$response->assertStatus(302);
$this->assertDatabaseHas('relationships', [
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_user_can_add_a_relationship_new_user_birthdate_unknown()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$gender = factory(Gender::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_type' => 'new',
'relationship_type_id' => $relationshipType->id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'birthdate' => 'unknown',
'realContact' => true,
];
$response = $this->post('/people/'.$contact->hashID().'/relationships', $params);
$response->assertStatus(302);
$this->assertDatabaseHas('contacts', [
'account_id' => $user->account_id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'is_partial' => false,
]);
$this->assertDatabaseHas('relationships', [
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_user_can_add_a_relationship_new_user_partial()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$gender = factory(Gender::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_type' => 'new',
'relationship_type_id' => $relationshipType->id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'birthdate' => 'unknown',
'realContact' => false,
];
$response = $this->post('/people/'.$contact->hashID().'/relationships', $params);
$response->assertStatus(302);
$this->assertDatabaseHas('contacts', [
'account_id' => $user->account_id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'is_partial' => true,
]);
$this->assertDatabaseHas('relationships', [
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_user_can_add_a_relationship_new_user_birthdate_known()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$gender = factory(Gender::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_type' => 'new',
'relationship_type_id' => $relationshipType->id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'birthdate' => 'exact',
'birthdayDate' => '1947-07-30',
'realContact' => true,
];
$response = $this->post('/people/'.$contact->hashID().'/relationships', $params);
$response->assertStatus(302);
$this->assertDatabaseHas('contacts', [
'account_id' => $user->account_id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $gender->id,
'is_partial' => false,
]);
$this->assertDatabaseHas('special_dates', [
'account_id' => $user->account_id,
'date' => '1947-07-30',
'is_age_based' => false,
'is_year_unknown' => false,
]);
$this->assertDatabaseHas('relationships', [
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_edit_a_relationship()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$partner = factory(Contact::class)->create([
'account_id' => $user->account_id,
'first_name' => 'Homer',
'last_name' => 'Simpson',
]);
$relationship = factory(Relationship::class)->create([
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
]);
$response = $this->get('/people/'.$contact->hashID().'/relationships/'.$relationship->id.'/edit');
$response->assertStatus(200);
$response->assertSee('Homer Simpson is…');
}
public function test_user_can_update_a_relationship()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$partner = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationship = factory(Relationship::class)->create([
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_id' => $relationship->id,
'relationship_type_id' => $relationshipType->id,
];
$response = $this->put('/people/'.$contact->hashID().'/relationships/'.$relationship->id, $params);
$response->assertStatus(302);
$this->assertDatabaseHas('relationships', [
'id' => $relationship->id,
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_user_can_update_a_relationship_partial_user()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$partner = factory(Contact::class)->create([
'account_id' => $user->account_id,
'is_partial' => true,
]);
$relationship = factory(Relationship::class)->create([
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
]);
$relationshipType = factory(RelationshipType::class)->create([
'account_id' => $user->account_id,
]);
$params = [
'relationship_id' => $relationship->id,
'relationship_type_id' => $relationshipType->id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'gender_id' => $partner->gender_id,
'birthdate' => 'exact',
'birthdayDate' => '1947-07-30',
];
$response = $this->put('/people/'.$contact->hashID().'/relationships/'.$relationship->id, $params);
$response->assertStatus(302);
$this->assertDatabaseHas('contacts', [
'account_id' => $user->account_id,
'first_name' => 'Arnold',
'last_name' => 'Schwarzenegger',
'is_partial' => true,
]);
$this->assertDatabaseHas('special_dates', [
'account_id' => $user->account_id,
'date' => '1947-07-30',
'is_age_based' => false,
'is_year_unknown' => false,
]);
$this->assertDatabaseHas('relationships', [
'id' => $relationship->id,
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
'relationship_type_id' => $relationshipType->id,
]);
}
public function test_user_can_destroy_a_relationship()
{
$user = $this->signIn();
$contact = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$partner = factory(Contact::class)->create([
'account_id' => $user->account_id,
]);
$relationship = factory(Relationship::class)->create([
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
]);
$response = $this->delete('/people/'.$contact->hashID().'/relationships/'.$relationship->id);
$response->assertStatus(302);
$this->assertDatabaseMissing('relationships', [
'id' => $relationship->id,
'account_id' => $user->account_id,
'contact_is' => $contact->id,
'of_contact' => $partner->id,
]);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Contact\ReminderRule;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ReminderRuleTest extends FeatureTestCase
{
use DatabaseTransactions;
/**
* @return array
*/
private function fetchUser()
{
$user = $this->signIn();
$reminderRule = factory(ReminderRule::class)->create([
'account_id' => $user->account_id,
'active' => true,
]);
return [$user, $reminderRule];
}
/** @test */
public function reminder_rule_index()
{
[$user, $reminderRule] = $this->fetchUser();
$response = $this->get('/settings/personalization/reminderrules');
$response->assertJsonFragment([
'id' => $reminderRule->id,
'active' => true,
]);
}
/** @test */
public function reminder_rule_toggle()
{
[$user, $reminderRule] = $this->fetchUser();
$response = $this->post('/settings/personalization/reminderrules/'.$reminderRule->id);
$this->assertDatabaseHas('reminder_rules', [
'id' => $reminderRule->id,
'active' => 0,
]);
$response->assertJsonFragment([
'id' => $reminderRule->id,
'active' => false,
]);
}
}

View File

@@ -0,0 +1,126 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use Illuminate\Support\Carbon;
use App\Models\Contact\Contact;
use LaravelWebauthn\Models\WebauthnKey;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class SettingsTest 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_access_settings_page()
{
[$user, $contact] = $this->fetchUser();
$response = $this->get('/settings');
$response->assertStatus(200);
$response->assertSee(trans('settings.sidebar_settings'));
}
public function test_user_can_export_account()
{
[$user, $contact] = $this->fetchUser();
$response = $this->get('/settings/export');
$response->assertStatus(200);
$response->assertSee(trans('settings.export_title'));
Carbon::setTestNow(Carbon::create(2021, 11, 25, 7, 0, 0));
$response = $this->post(route('settings.export.store.sql'));
$response->assertStatus(302);
// $this->assertTrue($response->headers->get('content-disposition') == 'attachment; filename=monica-export.2021-11-25.sql');
}
public function test_user_can_delete_account()
{
[$user, $contact] = $this->fetchUser();
$response = $this->followingRedirects()
->post(route('settings.delete'));
$response->assertStatus(200);
$response->assertSee('Login');
}
public function test_it_updates_the_default_profile_view()
{
$user = $this->signin();
$response = $this->json('POST', '/settings/updateDefaultProfileView', [
'name' => 'life-events',
]);
$response->assertStatus(200);
$this->assertDatabaseHas('users', [
'profile_active_tab' => 'life-events',
'id' => $user->id,
]);
$response = $this->json('POST', '/settings/updateDefaultProfileView', [
'name' => 'notes',
]);
$response->assertStatus(200);
$this->assertDatabaseHas('users', [
'profile_active_tab' => 'notes',
'id' => $user->id,
]);
$response = $this->json('POST', '/settings/updateDefaultProfileView', [
'name' => 'nawak',
]);
$response->assertStatus(200);
}
public function test_user_see_webauthnkeys()
{
$user = $this->signin();
$webauthnKey = factory(WebauthnKey::class)->create([
'user_id' => $user->id,
'updated_at' => '2019-04-01 09:18:35',
]);
$this->session([
'webauthn_auth' => true,
]);
$response = $this->followingRedirects()
->get(route('settings.security.index'));
$response->assertStatus(200);
$response->assertSee($webauthnKey->name);
$response->assertSee('2019-04-01T09:18:35Z');
}
}

View File

@@ -0,0 +1,355 @@
<?php
namespace Tests\Feature;
use Carbon\Carbon;
use Tests\FeatureTestCase;
use App\Models\Account\Photo;
use App\Helpers\StorageHelper;
use App\Models\Contact\Contact;
use App\Models\Contact\Document;
use Illuminate\Http\Testing\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class StorageControllerTest 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];
}
/** @test */
public function it_get_photo_content()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file);
$response->assertStatus(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_get_avatar_content()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeAvatar($contact);
$response = $this->get('/store/'.$file);
$response->assertStatus(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_get_document_content()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeDocument($contact);
$response = $this->get('/store/'.$file);
$response->assertStatus(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_404_if_avatar_not_exist()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$response = $this->get('/store/avatars/test');
$response->assertStatus(404);
}
/** @test */
public function it_returns_404_if_folder_unknown()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$response = $this->get('/store/xxx/test');
$response->assertStatus(404);
}
/** @test */
public function it_returns_200_if_modified_after_IfModifiedSince()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-Modified-Since' => 'Sat, 12 Jun 2021 07:00:00 GMT',
]);
$response->assertStatus(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_304_if_not_modified_since_IfModifiedSince()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-Modified-Since' => 'Sat, 26 Jun 2021 07:00:00 GMT',
]);
$response->assertNoContent(304);
$response->assertHeaderMissing('Last-Modified');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_200_if_not_modified_after_IfUnmodifiedSince()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-Unmodified-Since' => 'Sat, 26 Jun 2021 07:00:00 GMT',
]);
$response->assertStatus(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_412_if_modified_after_IfUnmodifiedSince()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-Unmodified-Since' => 'Sat, 12 Jun 2021 07:00:00 GMT',
]);
$response->assertStatus(412);
}
/** @test */
public function it_fails_if_file_not_found()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$response = $this->get('/store/photos/fail.png');
$response->assertStatus(404);
}
/** @test */
public function it_fails_if_file_not_exist()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$photo = factory(Photo::class)->create([
'account_id' => $contact->account_id,
'original_filename' => 'avatar.png',
'filesize' => 0,
'mime_type' => '',
'new_filename' => 'avatar.png',
]);
$contact->photos()->syncWithoutDetaching([$photo->id]);
$response = $this->get('/store/photos/avatar.png');
$response->assertStatus(404);
}
/** @test */
public function it_fails_if_file_not_owned_by_user()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$this->signIn();
$response = $this->get('/store/'.$file, [
'If-Unmodified-Since' => 'Sat, 12 Jun 2021 07:00:00 GMT',
]);
$response->assertStatus(404);
}
/** @test */
public function it_returns_200_if_matching_IfMatch()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-Match' => '"'.sha1('/store/'.$file).'"',
]);
$response->assertNoContent(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_200_with_none_matching_IfNoneMatch()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-None-Match' => '"test"',
]);
$response->assertNoContent(200);
$response->assertHeader('Last-Modified', 'Sat, 19 Jun 2021 07:00:00 GMT');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
/** @test */
public function it_returns_304_if_matching_IfNoneMatch()
{
config(['filesystems.default' => 'local']);
[$user, $contact] = $this->fetchUser();
$file = $this->storeImage($contact);
$response = $this->get('/store/'.$file, [
'If-None-Match' => '"'.sha1('/store/'.$file).'"',
]);
$response->assertNoContent(304);
$response->assertHeaderMissing('Last-Modified');
$response->assertHeader('Cache-Control', 'max-age=2628000, private');
$response->assertHeader('etag', '"'.sha1('/store/'.$file).'"');
}
public function storeImage(Contact $contact)
{
Storage::fake('local');
$image = File::createWithContent('avatar.png', file_get_contents(base_path('public/img/favicon.png')));
$file = Storage::putFile('/photos', $image, [
'disk' => 'local',
]);
$photo = factory(Photo::class)->create([
'account_id' => $contact->account_id,
'original_filename' => 'avatar.png',
'filesize' => $image->getSize(),
'mime_type' => $image->getMimeType(),
'new_filename' => $file,
]);
$contact->photos()->syncWithoutDetaching([$photo->id]);
touch(StorageHelper::disk('local')->path($file), Carbon::create(2021, 6, 19, 7, 0, 0, 'UTC')->timestamp);
return $file;
}
public function storeDocument(Contact $contact)
{
Storage::fake('local');
$image = File::createWithContent('file.png', file_get_contents(base_path('public/img/favicon.png')));
$file = Storage::putFile('/documents', $image, [
'disk' => 'local',
]);
factory(Document::class)->create([
'account_id' => $contact->account_id,
'contact_id' => $contact->id,
'original_filename' => 'file.png',
'new_filename' => $file,
]);
touch(StorageHelper::disk('local')->path($file), Carbon::create(2021, 6, 19, 7, 0, 0, 'UTC')->timestamp);
return $file;
}
public function storeAvatar(Contact $contact)
{
$disk = Storage::fake('local');
$image = File::createWithContent('avatar.png', file_get_contents(base_path('public/img/favicon.png')));
$file = Storage::putFile('/avatars', $image, [
'disk' => 'local',
]);
$contact->avatar_source = 'default';
$contact->avatar_default_url = $file.'?123';
$contact->save();
touch(StorageHelper::disk('local')->path($file), Carbon::create(2021, 6, 19, 7, 0, 0, 'UTC')->timestamp);
return $file;
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace Tests\Feature;
use Tests\FeatureTestCase;
use App\Models\Contact\Contact;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class TaskTest 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_add_a_task()
{
[$user, $contact] = $this->fetchUser();
$taskTitle = $this->faker->realText();
$taskDescription = $this->faker->realText();
$params = [
'title' => $taskTitle,
'description' => $taskDescription,
'completed' => 0,
'contact_id' => $contact->id,
];
$response = $this->post('/tasks', $params);
// Assert the note has been added for the correct user.
$params['account_id'] = $user->account_id;
$params['contact_id'] = $contact->id;
$params['title'] = $taskTitle;
$params['description'] = $taskDescription;
$this->assertDatabaseHas('tasks', $params);
}
}