diff --git a/app/Domains/Contact/ManageContact/Web/ViewHelpers/ContactShowViewHelper.php b/app/Domains/Contact/ManageContact/Web/ViewHelpers/ContactShowViewHelper.php
index 59af6d505..04c9b87e0 100644
--- a/app/Domains/Contact/ManageContact/Web/ViewHelpers/ContactShowViewHelper.php
+++ b/app/Domains/Contact/ManageContact/Web/ViewHelpers/ContactShowViewHelper.php
@@ -24,6 +24,7 @@ use App\Domains\Contact\ManageRelationships\Web\ViewHelpers\ModuleRelationshipVi
use App\Domains\Contact\ManageReligion\Web\ViewHelpers\ModuleReligionViewHelper;
use App\Domains\Contact\ManageReminders\Web\ViewHelpers\ModuleRemindersViewHelper;
use App\Domains\Contact\ManageTasks\Web\ViewHelpers\ModuleContactTasksViewHelper;
+use App\Domains\Vault\ManageJournals\Web\ViewHelpers\ModulePostsViewHelper;
use App\Helpers\StorageHelper;
use App\Models\Contact;
use App\Models\Module;
@@ -285,6 +286,10 @@ class ContactShowViewHelper
$data = ModulePhotosViewHelper::data($contact);
}
+ if ($module->type == Module::TYPE_POSTS) {
+ $data = ModulePostsViewHelper::data($contact, $user);
+ }
+
$modulesCollection->push([
'id' => $module->id,
'type' => $module->type,
diff --git a/app/Domains/Settings/CreateAccount/Jobs/SetupAccount.php b/app/Domains/Settings/CreateAccount/Jobs/SetupAccount.php
index d2cf83351..260da85f3 100644
--- a/app/Domains/Settings/CreateAccount/Jobs/SetupAccount.php
+++ b/app/Domains/Settings/CreateAccount/Jobs/SetupAccount.php
@@ -561,6 +561,22 @@ class SetupAccount extends QueuableService implements ServiceInterface
'template_page_id' => $templatePageInformation->id,
'module_id' => $module->id,
]);
+
+ // Posts
+ $module = (new CreateModule())->execute([
+ 'account_id' => $this->author->account_id,
+ 'author_id' => $this->author->id,
+ 'name' => trans('app.module_posts'),
+ 'type' => Module::TYPE_POSTS,
+ 'can_be_deleted' => false,
+ ]);
+ (new AssociateModuleToTemplatePage())->execute([
+ 'account_id' => $this->author->account_id,
+ 'author_id' => $this->author->id,
+ 'template_id' => $this->template->id,
+ 'template_page_id' => $templatePageInformation->id,
+ 'module_id' => $module->id,
+ ]);
}
private function addFirstInformation(): void
diff --git a/app/Domains/Vault/ManageJournals/Services/AddContactToPost.php b/app/Domains/Vault/ManageJournals/Services/AddContactToPost.php
new file mode 100644
index 000000000..fc1916739
--- /dev/null
+++ b/app/Domains/Vault/ManageJournals/Services/AddContactToPost.php
@@ -0,0 +1,96 @@
+ 'required|integer|exists:accounts,id',
+ 'vault_id' => 'required|integer|exists:vaults,id',
+ 'author_id' => 'required|integer|exists:users,id',
+ 'journal_id' => 'required|integer|exists:journals,id',
+ 'post_id' => 'required|integer|exists:posts,id',
+ 'contact_id' => 'required|integer|exists:contacts,id',
+ ];
+ }
+
+ /**
+ * Get the permissions that apply to the user calling the service.
+ *
+ * @return array
+ */
+ public function permissions(): array
+ {
+ return [
+ 'author_must_belong_to_account',
+ 'vault_must_belong_to_account',
+ 'author_must_be_vault_editor',
+ 'contact_must_belong_to_vault',
+ ];
+ }
+
+ /**
+ * Add a contact to a post.
+ *
+ * @param array $data
+ * @return Post
+ */
+ public function execute(array $data): Post
+ {
+ $this->data = $data;
+ $this->validate();
+
+ $this->post->contacts()->syncWithoutDetaching($this->contact);
+
+ $this->createFeedItem();
+ $this->updateLastEditedDate();
+
+ return $this->post;
+ }
+
+ private function validate(): void
+ {
+ $this->validateRules($this->data);
+
+ $journal = $this->vault->journals()
+ ->findOrFail($this->data['journal_id']);
+
+ $this->post = $journal->posts()
+ ->findOrFail($this->data['post_id']);
+ }
+
+ private function updateLastEditedDate(): void
+ {
+ $this->contact->last_updated_at = Carbon::now();
+ $this->contact->save();
+ }
+
+ private function createFeedItem(): void
+ {
+ $feedItem = ContactFeedItem::create([
+ 'author_id' => $this->author->id,
+ 'contact_id' => $this->contact->id,
+ 'action' => ContactFeedItem::ACTION_ADDED_TO_POST,
+ 'description' => $this->post->title,
+ ]);
+ $this->post->feedItem()->save($feedItem);
+ }
+}
diff --git a/app/Domains/Vault/ManageJournals/Services/RemoveContactFromPost.php b/app/Domains/Vault/ManageJournals/Services/RemoveContactFromPost.php
new file mode 100644
index 000000000..a87df6a54
--- /dev/null
+++ b/app/Domains/Vault/ManageJournals/Services/RemoveContactFromPost.php
@@ -0,0 +1,98 @@
+ 'required|integer|exists:accounts,id',
+ 'vault_id' => 'required|integer|exists:vaults,id',
+ 'author_id' => 'required|integer|exists:users,id',
+ 'journal_id' => 'required|integer|exists:journals,id',
+ 'post_id' => 'required|integer|exists:posts,id',
+ 'contact_id' => 'required|integer|exists:contacts,id',
+ ];
+ }
+
+ /**
+ * Get the permissions that apply to the user calling the service.
+ *
+ * @return array
+ */
+ public function permissions(): array
+ {
+ return [
+ 'author_must_belong_to_account',
+ 'vault_must_belong_to_account',
+ 'author_must_be_vault_editor',
+ 'contact_must_belong_to_vault',
+ ];
+ }
+
+ /**
+ * Remove a contact from a post.
+ *
+ * @param array $data
+ * @return Post
+ */
+ public function execute(array $data): Post
+ {
+ $this->data = $data;
+ $this->validate();
+
+ $this->post->contacts()->detach([
+ $this->contact->id,
+ ]);
+
+ $this->updateLastEditedDate();
+ $this->createFeedItem();
+
+ return $this->post;
+ }
+
+ private function validate(): void
+ {
+ $this->validateRules($this->data);
+
+ $journal = $this->vault->journals()
+ ->findOrFail($this->data['journal_id']);
+
+ $this->post = $journal->posts()
+ ->findOrFail($this->data['post_id']);
+ }
+
+ private function updateLastEditedDate(): void
+ {
+ $this->contact->last_updated_at = Carbon::now();
+ $this->contact->save();
+ }
+
+ private function createFeedItem(): void
+ {
+ $feedItem = ContactFeedItem::create([
+ 'author_id' => $this->author->id,
+ 'contact_id' => $this->contact->id,
+ 'action' => ContactFeedItem::ACTION_REMOVED_FROM_POST,
+ 'description' => $this->post->title,
+ ]);
+ $this->post->feedItem()->save($feedItem);
+ }
+}
diff --git a/app/Domains/Vault/ManageJournals/Web/Controllers/PostController.php b/app/Domains/Vault/ManageJournals/Web/Controllers/PostController.php
index e1e386085..46436f11d 100644
--- a/app/Domains/Vault/ManageJournals/Web/Controllers/PostController.php
+++ b/app/Domains/Vault/ManageJournals/Web/Controllers/PostController.php
@@ -2,6 +2,7 @@
namespace App\Domains\Vault\ManageJournals\Web\Controllers;
+use App\Domains\Vault\ManageJournals\Services\AddContactToPost;
use App\Domains\Vault\ManageJournals\Services\CreatePost;
use App\Domains\Vault\ManageJournals\Services\DestroyPost;
use App\Domains\Vault\ManageJournals\Services\IncrementPostReadCounter;
@@ -125,6 +126,25 @@ class PostController extends Controller
'written_at' => Carbon::now()->format('Y-m-d'),
]);
+ $post->contacts()->detach();
+
+ if ($request->input('contacts')) {
+ if (count($request->input('contacts')) > 0) {
+ foreach ($request->input('contacts') as $contact) {
+ $data = [
+ 'account_id' => Auth::user()->account_id,
+ 'author_id' => Auth::user()->id,
+ 'vault_id' => $vaultId,
+ 'journal_id' => $journalId,
+ 'post_id' => $postId,
+ 'contact_id' => $contact['id'],
+ ];
+
+ (new AddContactToPost())->execute($data);
+ }
+ }
+ }
+
return response()->json([
'data' => PostHelper::statistics($post),
], 200);
diff --git a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModuleContactPostViewHelper.php b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModuleContactPostViewHelper.php
new file mode 100644
index 000000000..1c7e34b1c
--- /dev/null
+++ b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModuleContactPostViewHelper.php
@@ -0,0 +1,29 @@
+posts()
+ ->orderBy('written_at', 'desc')
+ ->get()
+ ->map(fn (Post $post) => [
+ 'id' => $post->id,
+ 'title' => $post->title,
+ 'excerpt' => $post->excerpt,
+ 'url' => [
+ 'show' => route('post.show', [
+ 'vault' => $contact->vault_id,
+ 'journal' => $post->journal_id,
+ 'post' => $post->id,
+ ]),
+ ],
+ ]);
+ }
+}
diff --git a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelper.php b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelper.php
new file mode 100644
index 000000000..fff308c3f
--- /dev/null
+++ b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelper.php
@@ -0,0 +1,46 @@
+posts()
+ ->orderBy('created_at', 'desc')
+ ->get()
+ ->map(fn (Post $post) => self::dto($post, $user));
+ }
+
+ public static function dto(Post $post, User $user): array
+ {
+ return [
+ 'id' => $post->id,
+ 'title' => $post->title,
+ 'journal' => [
+ 'id' => $post->journal->id,
+ 'name' => $post->journal->name,
+ 'url' => [
+ 'show' => route('journal.show', [
+ 'vault' => $post->journal->vault->id,
+ 'journal' => $post->journal->id,
+ ]),
+ ],
+ ],
+ 'written_at' => DateHelper::formatDate($post->written_at, $user->timezone),
+ 'url' => [
+ 'show' => route('post.show', [
+ 'vault' => $post->journal->vault_id,
+ 'journal' => $post->journal->id,
+ 'post' => $post->id,
+ ]),
+ ],
+ ];
+ }
+}
diff --git a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelper.php b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelper.php
index d5a3c9a40..5bc8aabcc 100644
--- a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelper.php
+++ b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelper.php
@@ -3,6 +3,7 @@
namespace App\Domains\Vault\ManageJournals\Web\ViewHelpers;
use App\Helpers\PostHelper;
+use App\Models\Contact;
use App\Models\Journal;
use App\Models\Post;
use App\Models\PostSection;
@@ -37,10 +38,15 @@ class PostEditViewHelper
return self::dtoTag($journal, $post, $tag);
});
+ $contacts = $post->contacts()
+ ->get()
+ ->map(fn (Contact $contact) => self::dtoContact($contact));
+
return [
'id' => $post->id,
'title' => $post->title,
'sections' => $sectionsCollection,
+ 'contacts' => $contacts,
'statistics' => PostHelper::statistics($post),
'tags_in_post' => $tagsAssociatedWithPostCollection,
'tags_in_vault' => $tagsInVaultCollection,
@@ -98,4 +104,19 @@ class PostEditViewHelper
],
];
}
+
+ public static function dtoContact(Contact $contact): array
+ {
+ return [
+ 'id' => $contact->id,
+ 'name' => $contact->name,
+ 'avatar' => $contact->avatar,
+ 'url' => [
+ 'show' => route('contact.show', [
+ 'vault' => $contact->vault_id,
+ 'contact' => $contact->id,
+ ]),
+ ],
+ ];
+ }
}
diff --git a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelper.php b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelper.php
index 99ac2d212..7f63f2edb 100644
--- a/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelper.php
+++ b/app/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelper.php
@@ -2,7 +2,9 @@
namespace App\Domains\Vault\ManageJournals\Web\ViewHelpers;
+use App\Helpers\ContactCardHelper;
use App\Helpers\DateHelper;
+use App\Models\Contact;
use App\Models\Post;
use App\Models\PostSection;
use App\Models\Tag;
@@ -30,6 +32,10 @@ class PostShowViewHelper
'name' => $tag->name,
]);
+ $contacts = $post->contacts()
+ ->get()
+ ->map(fn (Contact $contact) => ContactCardHelper::data($contact, $user));
+
return [
'id' => $post->id,
'title' => $post->title,
@@ -38,6 +44,7 @@ class PostShowViewHelper
'published' => $post->published,
'sections' => $sections,
'tags' => $tags,
+ 'contacts' => $contacts,
'journal' => [
'name' => $post->journal->name,
'url' => [
diff --git a/app/Models/Contact.php b/app/Models/Contact.php
index 3738c8687..d2db5829f 100644
--- a/app/Models/Contact.php
+++ b/app/Models/Contact.php
@@ -362,6 +362,16 @@ class Contact extends Model
return $this->belongsToMany(Group::class, 'contact_group');
}
+ /**
+ * Get the posts associated with the contact.
+ *
+ * @return BelongsToMany
+ */
+ public function posts(): BelongsToMany
+ {
+ return $this->belongsToMany(Post::class, 'contact_post');
+ }
+
/**
* Get the religion associated with the contact.
*
diff --git a/app/Models/ContactFeedItem.php b/app/Models/ContactFeedItem.php
index 0d9f64f64..9b8c5b829 100644
--- a/app/Models/ContactFeedItem.php
+++ b/app/Models/ContactFeedItem.php
@@ -84,6 +84,10 @@ class ContactFeedItem extends Model
public const ACTION_REMOVED_FROM_GROUP = 'removed_from_group';
+ public const ACTION_ADDED_TO_POST = 'added_to_post';
+
+ public const ACTION_REMOVED_FROM_POST = 'removed_from_post';
+
public const ACTION_ARCHIVED_CONTACT = 'archived';
public const ACTION_UNARCHIVED_CONTACT = 'unarchived';
diff --git a/app/Models/Module.php b/app/Models/Module.php
index 4ae23598e..5997a0106 100644
--- a/app/Models/Module.php
+++ b/app/Models/Module.php
@@ -57,6 +57,8 @@ class Module extends Model
public const TYPE_PHOTOS = 'photos';
+ public const TYPE_POSTS = 'posts';
+
public const TYPE_RELIGIONS = 'religions';
/**
diff --git a/app/Models/Post.php b/app/Models/Post.php
index 8dd200ef2..0984d81f4 100644
--- a/app/Models/Post.php
+++ b/app/Models/Post.php
@@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
+use Illuminate\Database\Eloquent\Relations\MorphOne;
use Illuminate\Support\Str;
class Post extends Model
@@ -69,6 +70,26 @@ class Post extends Model
return $this->hasMany(PostSection::class);
}
+ /**
+ * Get the contacts associated with the post.
+ *
+ * @return BelongsToMany
+ */
+ public function contacts(): BelongsToMany
+ {
+ return $this->belongsToMany(Contact::class);
+ }
+
+ /**
+ * Get the post's feed item.
+ *
+ * @return MorphOne
+ */
+ public function feedItem(): MorphOne
+ {
+ return $this->morphOne(ContactFeedItem::class, 'feedable');
+ }
+
/**
* Get the tags associated with the post.
*
@@ -106,7 +127,7 @@ class Post extends Model
protected function excerpt(): Attribute
{
return Attribute::make(
- get: fn () => Str::limit(optional($this->postSections()->first())->content, 200)
+ get: fn () => Str::limit(optional($this->postSections()->whereNotNull('content')->first())->content, 200)
);
}
}
diff --git a/database/migrations/2022_09_22_111510_create_posts_table.php b/database/migrations/2022_09_22_111510_create_posts_table.php
index 5940a93ed..188a6cfc1 100644
--- a/database/migrations/2022_09_22_111510_create_posts_table.php
+++ b/database/migrations/2022_09_22_111510_create_posts_table.php
@@ -53,6 +53,14 @@ return new class extends Migration
$table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
});
+ Schema::create('contact_post', function (Blueprint $table) {
+ $table->unsignedBigInteger('post_id');
+ $table->unsignedBigInteger('contact_id');
+ $table->timestamps();
+ $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
+ $table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
+ });
+
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('vault_id');
@@ -81,6 +89,9 @@ return new class extends Migration
Schema::dropIfExists('post_templates');
Schema::dropIfExists('post_template_sections');
Schema::dropIfExists('posts');
- Schema::dropIfExists('journal_tags');
+ Schema::dropIfExists('post_sections');
+ Schema::dropIfExists('contact_post');
+ Schema::dropIfExists('tags');
+ Schema::dropIfExists('post_tag');
}
};
diff --git a/lang/en/app.php b/lang/en/app.php
index f9888a52c..15138b9af 100644
--- a/lang/en/app.php
+++ b/lang/en/app.php
@@ -115,6 +115,7 @@ return [
'module_contact_information' => 'Contact information',
'module_documents' => 'Documents',
'module_photos' => 'Photos',
+ 'module_posts' => 'Posts about the contact',
'module_religions' => 'Religions',
'module_option_default_number_of_items_to_display' => 'Default number of items to display',
diff --git a/lang/en/contact.php b/lang/en/contact.php
index fe4775503..bb5d8fc84 100644
--- a/lang/en/contact.php
+++ b/lang/en/contact.php
@@ -45,6 +45,8 @@ return [
'feed_item_goal_destroyed' => 'deleted a goal',
'feed_item_added_to_group' => 'added the contact to a group',
'feed_item_removed_from_group' => 'removed the contact from a group',
+ 'feed_item_added_to_post' => 'added the contact to a post',
+ 'feed_item_removed_from_post' => 'removed the contact from a post',
'feed_item_archived' => 'archived the contact',
'feed_item_unarchived' => 'unarchived the contact',
'feed_item_favorited' => 'added the contact to the favorites',
diff --git a/lang/en/vault.php b/lang/en/vault.php
index a4a6a7170..c1b8325c5 100644
--- a/lang/en/vault.php
+++ b/lang/en/vault.php
@@ -114,6 +114,7 @@ return [
'journal_show_cta' => 'Create a post',
'journal_show_years' => 'Years',
'journal_show_tags' => 'All tags',
+ 'journal_show_contacts' => 'Contacts in this post',
'journal_show_options' => 'Options',
'journal_show_blank' => 'The journal lets you document your life with your own words.',
'journal_post_edit_tags' => 'Tags',
diff --git a/public/img/contact_blank_posts.svg b/public/img/contact_blank_posts.svg
new file mode 100644
index 000000000..cf97323f0
--- /dev/null
+++ b/public/img/contact_blank_posts.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/js/Pages/Vault/Contact/Relationships/Create.vue b/resources/js/Pages/Vault/Contact/Relationships/Create.vue
index 3b201c03b..54f7e3028 100644
--- a/resources/js/Pages/Vault/Contact/Relationships/Create.vue
+++ b/resources/js/Pages/Vault/Contact/Relationships/Create.vue
@@ -222,7 +222,7 @@
:display-most-consulted-contacts="false"
:add-multiple-contacts="false"
:required="true"
- :div-outer-class="'flex-1 border-r border-gray-200 dark:border-gray-700'" />
+ :div-outer-class="'flex-1 border-gray-200 dark:border-gray-700'" />
diff --git a/resources/js/Pages/Vault/Contact/Show.vue b/resources/js/Pages/Vault/Contact/Show.vue
index 990ca24d1..946acfaf4 100644
--- a/resources/js/Pages/Vault/Contact/Show.vue
+++ b/resources/js/Pages/Vault/Contact/Show.vue
@@ -31,6 +31,7 @@ import ContactInformation from '@/Shared/Modules/ContactInformation.vue';
import Documents from '@/Shared/Modules/Documents.vue';
import Photos from '@/Shared/Modules/Photos.vue';
import Religion from '@/Shared/Modules/Religion.vue';
+import Posts from '@/Shared/Modules/Posts.vue';
import Uploadcare from '@/Components/Uploadcare.vue';
const props = defineProps({
@@ -324,6 +325,8 @@ const destroyAvatar = () => {
+ Contacts in this post +
+
{{ $t('vault.journal_post_edit_tags') }}
-
-
+
+ {{ $t('app.edit') }}
diff --git a/resources/js/Pages/Vault/Journal/Post/Show.vue b/resources/js/Pages/Vault/Journal/Post/Show.vue
index b81beaa24..d004a4388 100644
--- a/resources/js/Pages/Vault/Journal/Post/Show.vue
+++ b/resources/js/Pages/Vault/Journal/Post/Show.vue
@@ -1,5 +1,6 @@
+
+
+
+ in
+ There are no posts yet.
+
+
+
+
diff --git a/routes/web.php b/routes/web.php
index 4033ba197..4fc31049e 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -291,7 +291,6 @@ Route::middleware([
Route::delete('calls/{call}', [ContactModuleCallController::class, 'destroy'])->name('contact.call.destroy');
// groups
- Route::get('groups', [ContactModuleGroupController::class, 'index'])->name('contact.group.index');
Route::post('groups', [ContactModuleGroupController::class, 'store'])->name('contact.group.store');
Route::delete('groups/{group}', [ContactModuleGroupController::class, 'destroy'])->name('contact.group.destroy');
});
diff --git a/tests/Unit/Domains/Settings/CreateAccount/Services/SetupAccountTest.php b/tests/Unit/Domains/Settings/CreateAccount/Services/SetupAccountTest.php
index 02e435e18..d8e399ed4 100644
--- a/tests/Unit/Domains/Settings/CreateAccount/Services/SetupAccountTest.php
+++ b/tests/Unit/Domains/Settings/CreateAccount/Services/SetupAccountTest.php
@@ -125,6 +125,10 @@ class SetupAccountTest extends TestCase
'account_id' => $user->account_id,
'name' => trans('app.module_groups'),
]);
+ $this->assertDatabaseHas('modules', [
+ 'account_id' => $user->account_id,
+ 'name' => trans('app.module_posts'),
+ ]);
$this->assertDatabaseHas('relationship_group_types', [
'name' => trans('account.relationship_type_love'),
diff --git a/tests/Unit/Domains/Vault/ManageJournals/Services/AddContactToPostTest.php b/tests/Unit/Domains/Vault/ManageJournals/Services/AddContactToPostTest.php
new file mode 100644
index 000000000..b85fff6f3
--- /dev/null
+++ b/tests/Unit/Domains/Vault/ManageJournals/Services/AddContactToPostTest.php
@@ -0,0 +1,150 @@
+createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ ]);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_wrong_parameters_are_given(): void
+ {
+ $request = [
+ 'title' => 'Ross',
+ ];
+
+ $this->expectException(ValidationException::class);
+ (new AddContactToPost())->execute($request);
+ }
+
+ /** @test */
+ public function it_fails_if_user_doesnt_belong_to_account(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $account = Account::factory()->create();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ ]);
+
+ $this->executeService($regis, $account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_journal_doesnt_belong_to_vault(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create();
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ ]);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_contact_doesnt_belong_to_vault(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create();
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ ]);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_post_doesnt_belong_to_journal(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create();
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_user_doesnt_have_right_permission_in_vault(): void
+ {
+ $this->expectException(NotEnoughPermissionException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ ]);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ private function executeService(User $author, Account $account, Vault $vault, Contact $contact, Journal $journal, Post $post): void
+ {
+ $request = [
+ 'account_id' => $account->id,
+ 'author_id' => $author->id,
+ 'vault_id' => $vault->id,
+ 'journal_id' => $journal->id,
+ 'post_id' => $post->id,
+ 'contact_id' => $contact->id,
+ ];
+
+ (new AddContactToPost())->execute($request);
+
+ $this->assertDatabaseHas('contact_post', [
+ 'contact_id' => $contact->id,
+ 'post_id' => $post->id,
+ ]);
+ }
+}
diff --git a/tests/Unit/Domains/Vault/ManageJournals/Services/RemoveContactFromPostTest.php b/tests/Unit/Domains/Vault/ManageJournals/Services/RemoveContactFromPostTest.php
new file mode 100644
index 000000000..80980871f
--- /dev/null
+++ b/tests/Unit/Domains/Vault/ManageJournals/Services/RemoveContactFromPostTest.php
@@ -0,0 +1,146 @@
+createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create(['journal_id' => $journal->id]);
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_wrong_parameters_are_given(): void
+ {
+ $request = [
+ 'title' => 'Ross',
+ ];
+
+ $this->expectException(ValidationException::class);
+ (new RemoveContactFromPost())->execute($request);
+ }
+
+ /** @test */
+ public function it_fails_if_user_doesnt_belong_to_account(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $account = Account::factory()->create();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create(['journal_id' => $journal->id]);
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_post_doesnt_belong_to_journal(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create();
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_journal_doesnt_belong_to_vault(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create();
+ $post = Post::factory()->create(['journal_id' => $journal->id]);
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_contact_doesnt_belong_to_vault(): void
+ {
+ $this->expectException(ModelNotFoundException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_EDIT, $vault);
+ $contact = Contact::factory()->create();
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create(['journal_id' => $journal->id]);
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ /** @test */
+ public function it_fails_if_user_doesnt_have_right_permission_in_vault(): void
+ {
+ $this->expectException(NotEnoughPermissionException::class);
+
+ $regis = $this->createUser();
+ $vault = $this->createVault($regis->account);
+ $vault = $this->setPermissionInVault($regis, Vault::PERMISSION_VIEW, $vault);
+ $contact = Contact::factory()->create(['vault_id' => $vault->id]);
+ $journal = Journal::factory()->create(['vault_id' => $vault->id]);
+ $post = Post::factory()->create(['journal_id' => $journal->id]);
+ $post->contacts()->attach($contact->id);
+
+ $this->executeService($regis, $regis->account, $vault, $contact, $journal, $post);
+ }
+
+ private function executeService(User $author, Account $account, Vault $vault, Contact $contact, Journal $journal, Post $post): void
+ {
+ $request = [
+ 'account_id' => $account->id,
+ 'author_id' => $author->id,
+ 'vault_id' => $vault->id,
+ 'journal_id' => $journal->id,
+ 'post_id' => $post->id,
+ 'contact_id' => $contact->id,
+ ];
+
+ (new RemoveContactFromPost())->execute($request);
+
+ $this->assertDatabaseMissing('contact_post', [
+ 'contact_id' => $contact->id,
+ 'post_id' => $post->id,
+ ]);
+ }
+}
diff --git a/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelperTest.php b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelperTest.php
new file mode 100644
index 000000000..71de1b6f8
--- /dev/null
+++ b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/ModulePostsViewHelperTest.php
@@ -0,0 +1,65 @@
+create();
+ $vault = Vault::factory()->create();
+ $contact = Contact::factory()->create([
+ 'vault_id' => $vault->id,
+ ]);
+ $journal = Journal::factory()->create([
+ 'vault_id' => $vault->id,
+ 'name' => 'this is a title',
+ ]);
+ $post = Post::factory()->create([
+ 'journal_id' => $journal->id,
+ 'title' => 'this is a title',
+ 'written_at' => '2022-01-01 00:00:00',
+ ]);
+ $post->contacts()->attach($contact->id);
+
+ $collection = ModulePostsViewHelper::data($contact, $user);
+
+ $this->assertEquals(
+ 1,
+ count($collection)
+ );
+
+ $this->assertEquals(
+ [
+ 0 => [
+ 'id' => $post->id,
+ 'title' => 'this is a title',
+ 'journal' => [
+ 'id' => $post->journal->id,
+ 'name' => 'this is a title',
+ 'url' => [
+ 'show' => env('APP_URL').'/vaults/'.$vault->id.'/journals/'.$journal->id,
+ ],
+ ],
+ 'written_at' => 'Jan 01, 2022',
+ 'url' => [
+ 'show' => env('APP_URL').'/vaults/'.$vault->id.'/journals/'.$journal->id.'/posts/'.$post->id,
+ ],
+ ],
+ ],
+ $collection->toArray()
+ );
+ }
+}
diff --git a/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelperTest.php b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelperTest.php
index 39243a2d2..81949ee69 100644
--- a/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelperTest.php
+++ b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostEditViewHelperTest.php
@@ -3,6 +3,7 @@
namespace Tests\Unit\Domains\Vault\ManageJournals\Web\ViewHelpers;
use App\Domains\Vault\ManageJournals\Web\ViewHelpers\PostEditViewHelper;
+use App\Models\Contact;
use App\Models\Journal;
use App\Models\Post;
use App\Models\PostSection;
@@ -28,10 +29,14 @@ class PostEditViewHelperTest extends TestCase
PostSection::factory()->create([
'post_id' => $post->id,
]);
+ $contact = Contact::factory()->create([
+ 'vault_id' => $vault->id,
+ ]);
+ $post->contacts()->attach($contact);
$array = PostEditViewHelper::data($journal, $post);
- $this->assertCount(8, $array);
+ $this->assertCount(9, $array);
$this->assertEquals(
$post->id,
$array['id']
@@ -46,6 +51,19 @@ class PostEditViewHelperTest extends TestCase
],
$array['journal']
);
+ $this->assertEquals(
+ [
+ 0 => [
+ 'id' => $contact->id,
+ 'name' => $contact->name,
+ 'avatar' => $contact->avatar,
+ 'url' => [
+ 'show' => env('APP_URL').'/vaults/'.$vault->id.'/contacts/'.$contact->id,
+ ],
+ ],
+ ],
+ $array['contacts']->toArray()
+ );
$this->assertEquals(
[
'update' => env('APP_URL').'/vaults/'.$vault->id.'/journals/'.$journal->id.'/posts/'.$post->id.'/update',
diff --git a/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelperTest.php b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelperTest.php
index d51894f2e..c28816eaa 100644
--- a/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelperTest.php
+++ b/tests/Unit/Domains/Vault/ManageJournals/Web/ViewHelpers/PostShowViewHelperTest.php
@@ -42,7 +42,7 @@ class PostShowViewHelperTest extends TestCase
$array = PostShowViewHelper::data($post, $user);
- $this->assertCount(9, $array);
+ $this->assertCount(10, $array);
$this->assertEquals(
$post->id,
$array['id']
diff --git a/tests/Unit/Models/ContactTest.php b/tests/Unit/Models/ContactTest.php
index 04db7ebe2..fc3a8f463 100644
--- a/tests/Unit/Models/ContactTest.php
+++ b/tests/Unit/Models/ContactTest.php
@@ -19,6 +19,7 @@ use App\Models\Label;
use App\Models\Loan;
use App\Models\Note;
use App\Models\Pet;
+use App\Models\Post;
use App\Models\Pronoun;
use App\Models\RelationshipType;
use App\Models\Religion;
@@ -260,6 +261,16 @@ class ContactTest extends TestCase
$this->assertTrue($contact->groups()->exists());
}
+ /** @test */
+ public function it_has_many_posts(): void
+ {
+ $contact = Contact::factory()->create();
+ $post = Post::factory()->create();
+ $contact->posts()->sync([$post->id]);
+
+ $this->assertTrue($contact->posts()->exists());
+ }
+
/** @test */
public function it_has_one_religion(): void
{
diff --git a/tests/Unit/Models/PostTest.php b/tests/Unit/Models/PostTest.php
index ae7e5fdae..3f70b50c0 100644
--- a/tests/Unit/Models/PostTest.php
+++ b/tests/Unit/Models/PostTest.php
@@ -2,6 +2,7 @@
namespace Tests\Unit\Models;
+use App\Models\Contact;
use App\Models\Post;
use App\Models\PostSection;
use App\Models\Tag;
@@ -31,6 +32,17 @@ class PostTest extends TestCase
$this->assertTrue($post->postSections()->exists());
}
+ /** @test */
+ public function it_has_many_contacts(): void
+ {
+ $ross = Contact::factory()->create([]);
+ $post = Post::factory()->create();
+
+ $post->contacts()->sync([$ross->id]);
+
+ $this->assertTrue($post->contacts()->exists());
+ }
+
/** @test */
public function it_has_many_tags(): void
{
@@ -63,4 +75,31 @@ class PostTest extends TestCase
$post->title
);
}
+
+ /** @test */
+ public function it_gets_the_excerpt(): void
+ {
+ $post = Post::factory()->create([
+ 'title' => null,
+ ]);
+
+ $this->assertNull(
+ $post->excerpt
+ );
+
+ PostSection::factory()->create([
+ 'post_id' => $post->id,
+ 'content' => null,
+ ]);
+
+ PostSection::factory()->create([
+ 'post_id' => $post->id,
+ 'content' => 'this is incredible',
+ ]);
+
+ $this->assertEquals(
+ 'this is incredible',
+ $post->excerpt
+ );
+ }
}