formatting, juiste use voor UpdateDynamicRequest
This commit is contained in:
parent
3e473de826
commit
10bd46a53e
@ -30,6 +30,7 @@ class MutationCreated implements ShouldBroadcast
|
|||||||
public function broadcastOn(): array
|
public function broadcastOn(): array
|
||||||
{
|
{
|
||||||
$chatId = $this->mutation->ledger->dynamic->chat->id;
|
$chatId = $this->mutation->ledger->dynamic->chat->id;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new PrivateChannel('chats.'.$chatId),
|
new PrivateChannel('chats.'.$chatId),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -30,6 +30,7 @@ class MutationUpdated implements ShouldBroadcast
|
|||||||
public function broadcastOn(): array
|
public function broadcastOn(): array
|
||||||
{
|
{
|
||||||
$chatId = $this->mutation->ledger->dynamic->chat->id;
|
$chatId = $this->mutation->ledger->dynamic->chat->id;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
new PrivateChannel('chats.'.$chatId),
|
new PrivateChannel('chats.'.$chatId),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdateDynamicRequest;
|
||||||
use App\Http\Resources\DynamicResource;
|
use App\Http\Resources\DynamicResource;
|
||||||
use App\Http\Resources\LedgerResource;
|
use App\Http\Resources\LedgerResource;
|
||||||
use App\Http\Resources\MessageResource;
|
use App\Http\Resources\MessageResource;
|
||||||
@ -15,6 +16,7 @@ use Inertia\Inertia;
|
|||||||
class DynamicController extends Controller
|
class DynamicController extends Controller
|
||||||
{
|
{
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -5,16 +5,18 @@ namespace App\Http\Controllers;
|
|||||||
use App\Mail\DynamicInvitationMail;
|
use App\Mail\DynamicInvitationMail;
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\DynamicInvitation;
|
use App\Models\DynamicInvitation;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
class DynamicInvitationController extends Controller
|
class DynamicInvitationController extends Controller
|
||||||
{
|
{
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new invitation.
|
* Show the form for creating a new invitation.
|
||||||
*/
|
*/
|
||||||
@ -39,7 +41,7 @@ class DynamicInvitationController extends Controller
|
|||||||
->where('role', 'owner')
|
->where('role', 'owner')
|
||||||
->exists();
|
->exists();
|
||||||
|
|
||||||
if (!$isOwner) {
|
if (! $isOwner) {
|
||||||
abort(403, 'Only dynamic owners can invite other users.');
|
abort(403, 'Only dynamic owners can invite other users.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +94,7 @@ class DynamicInvitationController extends Controller
|
|||||||
public function accept(Request $request, string $token)
|
public function accept(Request $request, string $token)
|
||||||
{
|
{
|
||||||
// Must be signed!
|
// Must be signed!
|
||||||
if (!$request->hasValidSignature()) {
|
if (! $request->hasValidSignature()) {
|
||||||
abort(401, 'Invalid or expired signature.');
|
abort(401, 'Invalid or expired signature.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +118,9 @@ class DynamicInvitationController extends Controller
|
|||||||
// Log to Dynamic chat activity log!
|
// Log to Dynamic chat activity log!
|
||||||
$dynamic->chat->messages()->create([
|
$dynamic->chat->messages()->create([
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'content' => "<user:{$request->user()->id}> joined the Dynamic as a " . strtoupper($invitation->role),
|
'content' => "<user:{$request->user()->id}> joined the Dynamic as a ".strtoupper($invitation->role),
|
||||||
'subject_id' => $request->user()->id,
|
'subject_id' => $request->user()->id,
|
||||||
'subject_type' => \App\Models\User::class,
|
'subject_type' => User::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Delete the invitation record
|
// Delete the invitation record
|
||||||
|
|||||||
@ -11,8 +11,8 @@ use App\Http\Resources\UserResource;
|
|||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Services\ActivityService;
|
use App\Services\ActivityService;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
class LedgerController extends Controller
|
class LedgerController extends Controller
|
||||||
|
|||||||
@ -2,14 +2,17 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Http\Resources\MutationResource;
|
use App\Events\MessageSent;
|
||||||
|
use App\Events\MutationCreated;
|
||||||
|
use App\Events\MutationUpdated;
|
||||||
use App\Http\Requests\StoreMutationRequest;
|
use App\Http\Requests\StoreMutationRequest;
|
||||||
|
use App\Http\Resources\MutationResource;
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
use App\Models\Mutation;
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
||||||
|
|
||||||
class MutationController extends Controller
|
class MutationController extends Controller
|
||||||
{
|
{
|
||||||
@ -69,7 +72,7 @@ class MutationController extends Controller
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Broadcast the real-time creation event!
|
// Broadcast the real-time creation event!
|
||||||
broadcast(new \App\Events\MutationCreated($mutation));
|
broadcast(new MutationCreated($mutation));
|
||||||
|
|
||||||
return redirect()->route('dynamics.ledgers.show', [$dynamic, $ledger]);
|
return redirect()->route('dynamics.ledgers.show', [$dynamic, $ledger]);
|
||||||
}
|
}
|
||||||
@ -80,7 +83,7 @@ class MutationController extends Controller
|
|||||||
public function show(Dynamic $dynamic, Ledger $ledger, Mutation $mutation)
|
public function show(Dynamic $dynamic, Ledger $ledger, Mutation $mutation)
|
||||||
{
|
{
|
||||||
$this->authorize('view', $mutation);
|
$this->authorize('view', $mutation);
|
||||||
|
|
||||||
return new MutationResource($mutation);
|
return new MutationResource($mutation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +130,12 @@ class MutationController extends Controller
|
|||||||
'subject_id' => $mutation->id,
|
'subject_id' => $mutation->id,
|
||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
broadcast(new \App\Events\MessageSent($mutationMsg));
|
broadcast(new MessageSent($mutationMsg));
|
||||||
|
|
||||||
if ($newStatus === 'approved') {
|
if ($newStatus === 'approved') {
|
||||||
$dynamicMsg = $dynamic->chat->messages()->create([
|
$dynamicMsg = $dynamic->chat->messages()->create([
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'content' => "<user:{$user->id}> APPROVED the suggestion \"{$mutation->description}\" for " . ($mutation->amount >= 0 ? '+' : '') . "{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
'content' => "<user:{$user->id}> APPROVED the suggestion \"{$mutation->description}\" for ".($mutation->amount >= 0 ? '+' : '')."{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
||||||
'subject_id' => $mutation->id,
|
'subject_id' => $mutation->id,
|
||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
@ -144,10 +147,10 @@ class MutationController extends Controller
|
|||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
broadcast(new \App\Events\MessageSent($dynamicMsg));
|
broadcast(new MessageSent($dynamicMsg));
|
||||||
|
|
||||||
// Broadcast the real-time update event!
|
// Broadcast the real-time update event!
|
||||||
broadcast(new \App\Events\MutationUpdated($mutation));
|
broadcast(new MutationUpdated($mutation));
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,14 +30,14 @@ class ParticipantController extends Controller
|
|||||||
public function show(Request $request, Dynamic $dynamic, User $user)
|
public function show(Request $request, Dynamic $dynamic, User $user)
|
||||||
{
|
{
|
||||||
// Ensure both the authenticated user and the target user are in the dynamic
|
// Ensure both the authenticated user and the target user are in the dynamic
|
||||||
if (!$dynamic->participants()->where('user_id', $request->user()->id)->exists()) {
|
if (! $dynamic->participants()->where('user_id', $request->user()->id)->exists()) {
|
||||||
abort(403);
|
abort(403);
|
||||||
}
|
}
|
||||||
|
|
||||||
$participant = $dynamic->participants()->where('user_id', $user->id)->firstOrFail();
|
$participant = $dynamic->participants()->where('user_id', $user->id)->firstOrFail();
|
||||||
|
|
||||||
$mutations = $user->mutations()
|
$mutations = $user->mutations()
|
||||||
->whereHas('ledger', fn($query) => $query->where('dynamic_id', $dynamic->id))
|
->whereHas('ledger', fn ($query) => $query->where('dynamic_id', $dynamic->id))
|
||||||
->with('ledger')
|
->with('ledger')
|
||||||
->latest('id')
|
->latest('id')
|
||||||
->take(10)
|
->take(10)
|
||||||
@ -54,5 +54,4 @@ class ParticipantController extends Controller
|
|||||||
'mutations' => $mutations,
|
'mutations' => $mutations,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
|
||||||
use App\Models\PredefinedMutation;
|
use App\Models\PredefinedMutation;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Services\ActivityService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Inertia\Middleware;
|
use Inertia\Middleware;
|
||||||
|
|
||||||
@ -46,8 +47,9 @@ class HandleInertiaRequests extends Middleware
|
|||||||
if (! $request->user()) {
|
if (! $request->user()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$service = app(\App\Services\ActivityService::class);
|
$service = app(ActivityService::class);
|
||||||
|
|
||||||
return count($service->getUnreadDynamicsGrouped($request->user()));
|
return count($service->getUnreadDynamicsGrouped($request->user()));
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@ -5,8 +5,6 @@ namespace App\Http\Requests;
|
|||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
use App\Models\Dynamic;
|
|
||||||
|
|
||||||
class UpdateDynamicRequest extends FormRequest
|
class UpdateDynamicRequest extends FormRequest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -22,7 +20,7 @@ class UpdateDynamicRequest extends FormRequest
|
|||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
|
* @return array<string, ValidationRule|array|string>
|
||||||
*/
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
class BaseResource extends JsonResource
|
class BaseResource extends JsonResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class DynamicResource extends BaseResource
|
class DynamicResource extends BaseResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class LedgerResource extends BaseResource
|
class LedgerResource extends BaseResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class MutationResource extends BaseResource
|
class MutationResource extends BaseResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class PredefinedMutationResource extends BaseResource
|
class PredefinedMutationResource extends BaseResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Resources;
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
|
|
||||||
class UserResource extends BaseResource
|
class UserResource extends BaseResource
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,20 +10,24 @@ use Illuminate\Mail\Mailables\Envelope;
|
|||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
|
|
||||||
class DynamicInvitationMail extends Mailable {
|
class DynamicInvitationMail extends Mailable
|
||||||
|
{
|
||||||
use Queueable, SerializesModels;
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
public function __construct(public DynamicInvitation $invitation, public string $inviterName) {
|
public function __construct(public DynamicInvitation $invitation, public string $inviterName)
|
||||||
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
public function envelope(): Envelope {
|
public function envelope(): Envelope
|
||||||
|
{
|
||||||
return new Envelope(
|
return new Envelope(
|
||||||
subject: 'Invitation to Join Dynamic: ' . $this->invitation->dynamic->name,
|
subject: 'Invitation to Join Dynamic: '.$this->invitation->dynamic->name,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function content(): Content {
|
public function content(): Content
|
||||||
|
{
|
||||||
$acceptUrl = URL::temporarySignedRoute(
|
$acceptUrl = URL::temporarySignedRoute(
|
||||||
'dynamics.invitations.accept',
|
'dynamics.invitations.accept',
|
||||||
$this->invitation->expires_at,
|
$this->invitation->expires_at,
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Dynamic extends Model
|
class Dynamic extends Model
|
||||||
{
|
{
|
||||||
@ -47,7 +48,7 @@ class Dynamic extends Model
|
|||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
$model->uuid = (string) \Illuminate\Support\Str::uuid();
|
$model->uuid = (string) Str::uuid();
|
||||||
});
|
});
|
||||||
|
|
||||||
static::created(function (Dynamic $dynamic) {
|
static::created(function (Dynamic $dynamic) {
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
|
||||||
class DynamicInvitation extends Model {
|
class DynamicInvitation extends Model
|
||||||
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
@ -21,11 +22,13 @@ class DynamicInvitation extends Model {
|
|||||||
'expires_at' => 'datetime',
|
'expires_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function dynamic(): BelongsTo {
|
public function dynamic(): BelongsTo
|
||||||
|
{
|
||||||
return $this->belongsTo(Dynamic::class);
|
return $this->belongsTo(Dynamic::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isExpired(): bool {
|
public function isExpired(): bool
|
||||||
|
{
|
||||||
return $this->expires_at->isPast();
|
return $this->expires_at->isPast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Ledger extends Model
|
class Ledger extends Model
|
||||||
{
|
{
|
||||||
@ -37,7 +39,7 @@ class Ledger extends Model
|
|||||||
return $this->hasMany(PredefinedMutation::class);
|
return $this->hasMany(PredefinedMutation::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function media(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function media(): MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Media::class, 'mediable');
|
return $this->morphMany(Media::class, 'mediable');
|
||||||
}
|
}
|
||||||
@ -45,7 +47,7 @@ class Ledger extends Model
|
|||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
$model->uuid = (string) \Illuminate\Support\Str::uuid();
|
$model->uuid = (string) Str::uuid();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
class Media extends Model {
|
class Media extends Model
|
||||||
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
@ -17,11 +18,13 @@ class Media extends Model {
|
|||||||
|
|
||||||
protected $appends = ['url'];
|
protected $appends = ['url'];
|
||||||
|
|
||||||
public function mediable(): MorphTo {
|
public function mediable(): MorphTo
|
||||||
|
{
|
||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUrlAttribute(): string {
|
public function getUrlAttribute(): string
|
||||||
return asset('storage/' . $this->file_path);
|
{
|
||||||
|
return asset('storage/'.$this->file_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use Database\Factories\MessageFactory;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||||
|
|
||||||
class Message extends Model
|
class Message extends Model
|
||||||
@ -37,7 +37,7 @@ class Message extends Model
|
|||||||
return $this->morphTo();
|
return $this->morphTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function media(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function media(): MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Media::class, 'mediable');
|
return $this->morphMany(Media::class, 'mediable');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Events\MessageSent;
|
||||||
use Database\Factories\MutationFactory;
|
use Database\Factories\MutationFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class Mutation extends Model
|
class Mutation extends Model
|
||||||
{
|
{
|
||||||
@ -43,7 +46,7 @@ class Mutation extends Model
|
|||||||
return $this->morphOne(Chat::class, 'chatable');
|
return $this->morphOne(Chat::class, 'chatable');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function media(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
public function media(): MorphMany
|
||||||
{
|
{
|
||||||
return $this->morphMany(Media::class, 'mediable');
|
return $this->morphMany(Media::class, 'mediable');
|
||||||
}
|
}
|
||||||
@ -51,7 +54,7 @@ class Mutation extends Model
|
|||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
$model->uuid = (string) \Illuminate\Support\Str::uuid();
|
$model->uuid = (string) Str::uuid();
|
||||||
});
|
});
|
||||||
|
|
||||||
static::created(function (Mutation $mutation) {
|
static::created(function (Mutation $mutation) {
|
||||||
@ -71,24 +74,24 @@ class Mutation extends Model
|
|||||||
'subject_id' => $mutation->id,
|
'subject_id' => $mutation->id,
|
||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
broadcast(new \App\Events\MessageSent($mutationMsg));
|
broadcast(new MessageSent($mutationMsg));
|
||||||
|
|
||||||
if ($status === 'approved') {
|
if ($status === 'approved') {
|
||||||
$dynamicMsg = $dynamic->chat->messages()->create([
|
$dynamicMsg = $dynamic->chat->messages()->create([
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'content' => "<user:{$user->id}> added entry \"{$mutation->description}\" for " . ($mutation->amount >= 0 ? '+' : '') . "{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
'content' => "<user:{$user->id}> added entry \"{$mutation->description}\" for ".($mutation->amount >= 0 ? '+' : '')."{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
||||||
'subject_id' => $mutation->id,
|
'subject_id' => $mutation->id,
|
||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$dynamicMsg = $dynamic->chat->messages()->create([
|
$dynamicMsg = $dynamic->chat->messages()->create([
|
||||||
'user_id' => null,
|
'user_id' => null,
|
||||||
'content' => "<user:{$user->id}> suggested \"{$mutation->description}\" for " . ($mutation->amount >= 0 ? '+' : '') . "{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
'content' => "<user:{$user->id}> suggested \"{$mutation->description}\" for ".($mutation->amount >= 0 ? '+' : '')."{$mutation->amount} points on \"{$ledger->name}\" ledger.",
|
||||||
'subject_id' => $mutation->id,
|
'subject_id' => $mutation->id,
|
||||||
'subject_type' => Mutation::class,
|
'subject_type' => Mutation::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
broadcast(new \App\Events\MessageSent($dynamicMsg));
|
broadcast(new MessageSent($dynamicMsg));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class PredefinedMutation extends Model
|
class PredefinedMutation extends Model
|
||||||
{
|
{
|
||||||
@ -26,7 +27,7 @@ class PredefinedMutation extends Model
|
|||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
$model->uuid = (string) \Illuminate\Support\Str::uuid();
|
$model->uuid = (string) Str::uuid();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Laravel\Fortify\Contracts\PasskeyUser;
|
use Laravel\Fortify\Contracts\PasskeyUser;
|
||||||
use Laravel\Fortify\PasskeyAuthenticatable;
|
use Laravel\Fortify\PasskeyAuthenticatable;
|
||||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||||
@ -33,7 +34,7 @@ use NotificationChannels\WebPush\HasPushSubscriptions;
|
|||||||
class User extends Authenticatable implements PasskeyUser
|
class User extends Authenticatable implements PasskeyUser
|
||||||
{
|
{
|
||||||
/** @use HasFactory<UserFactory> */
|
/** @use HasFactory<UserFactory> */
|
||||||
use HasFactory, Notifiable, PasskeyAuthenticatable, TwoFactorAuthenticatable, HasPushSubscriptions;
|
use HasFactory, HasPushSubscriptions, Notifiable, PasskeyAuthenticatable, TwoFactorAuthenticatable;
|
||||||
|
|
||||||
public function dynamics()
|
public function dynamics()
|
||||||
{
|
{
|
||||||
@ -74,7 +75,7 @@ class User extends Authenticatable implements PasskeyUser
|
|||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function ($model) {
|
static::creating(function ($model) {
|
||||||
$model->uuid = (string) \Illuminate\Support\Str::uuid();
|
$model->uuid = (string) Str::uuid();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,10 +3,7 @@
|
|||||||
namespace App\Notifications;
|
namespace App\Notifications;
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
use NotificationChannels\WebPush\WebPushChannel;
|
use NotificationChannels\WebPush\WebPushChannel;
|
||||||
use NotificationChannels\WebPush\WebPushMessage;
|
use NotificationChannels\WebPush\WebPushMessage;
|
||||||
|
|
||||||
|
|||||||
@ -3,9 +3,9 @@
|
|||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
use Illuminate\Support\Facades\Date;
|
use Illuminate\Support\Facades\Date;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Illuminate\Validation\Rules\Password;
|
use Illuminate\Validation\Rules\Password;
|
||||||
|
|
||||||
|
|||||||
@ -2,16 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
use App\Models\ReadCursor;
|
use App\Models\ReadCursor;
|
||||||
use Illuminate\Support\Carbon;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
use App\Notifications\NewActivityNotification;
|
use App\Notifications\NewActivityNotification;
|
||||||
|
use Carbon\CarbonInterface;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
class ActivityService
|
class ActivityService
|
||||||
{
|
{
|
||||||
@ -35,7 +33,7 @@ class ActivityService
|
|||||||
/**
|
/**
|
||||||
* Get the read cursor timestamp for a user on a specific entity.
|
* Get the read cursor timestamp for a user on a specific entity.
|
||||||
*/
|
*/
|
||||||
public function getCursorReadAt(User $user, $entity): \Carbon\CarbonInterface
|
public function getCursorReadAt(User $user, $entity): CarbonInterface
|
||||||
{
|
{
|
||||||
$cursor = ReadCursor::where([
|
$cursor = ReadCursor::where([
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
@ -97,6 +95,7 @@ class ActivityService
|
|||||||
$participants = $dynamic->participants()->withPivot('display_name')->get();
|
$participants = $dynamic->participants()->withPivot('display_name')->get();
|
||||||
$participantsMap = $participants->reduce(function ($acc, $p) {
|
$participantsMap = $participants->reduce(function ($acc, $p) {
|
||||||
$acc[$p->id] = $p->pivot->display_name ?? $p->name;
|
$acc[$p->id] = $p->pivot->display_name ?? $p->name;
|
||||||
|
|
||||||
return $acc;
|
return $acc;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@ -112,6 +111,7 @@ class ActivityService
|
|||||||
// Resolve <user:id> placeholders to actual names/display names
|
// Resolve <user:id> placeholders to actual names/display names
|
||||||
$messageData['content'] = preg_replace_callback('/<user:(\d+)>/', function ($matches) use ($participantsMap) {
|
$messageData['content'] = preg_replace_callback('/<user:(\d+)>/', function ($matches) use ($participantsMap) {
|
||||||
$userId = $matches[1];
|
$userId = $matches[1];
|
||||||
|
|
||||||
return $participantsMap[$userId] ?? "User #{$userId}";
|
return $participantsMap[$userId] ?? "User #{$userId}";
|
||||||
}, $message->content);
|
}, $message->content);
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ class ActivityService
|
|||||||
/**
|
/**
|
||||||
* Partition activities into read and unread, and construct the grouped entity metadata.
|
* Partition activities into read and unread, and construct the grouped entity metadata.
|
||||||
*/
|
*/
|
||||||
private function partitionAndGroupActivities(array $activities, \Carbon\CarbonInterface $readAt, Dynamic $dynamic, array &$groupedDynamics): void
|
private function partitionAndGroupActivities(array $activities, CarbonInterface $readAt, Dynamic $dynamic, array &$groupedDynamics): void
|
||||||
{
|
{
|
||||||
$alreadyRead = [];
|
$alreadyRead = [];
|
||||||
$unread = [];
|
$unread = [];
|
||||||
@ -153,7 +153,7 @@ class ActivityService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($unread)) {
|
if (! empty($unread)) {
|
||||||
$context = array_slice($alreadyRead, 0, 2);
|
$context = array_slice($alreadyRead, 0, 2);
|
||||||
|
|
||||||
$groupedDynamics[] = [
|
$groupedDynamics[] = [
|
||||||
@ -192,4 +192,4 @@ class ActivityService
|
|||||||
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,9 +10,9 @@ use Illuminate\Http\Request;
|
|||||||
|
|
||||||
return Application::configure(basePath: dirname(__DIR__))
|
return Application::configure(basePath: dirname(__DIR__))
|
||||||
->withRouting(
|
->withRouting(
|
||||||
web: __DIR__ . '/../routes/web.php',
|
web: __DIR__.'/../routes/web.php',
|
||||||
commands: __DIR__ . '/../routes/console.php',
|
commands: __DIR__.'/../routes/console.php',
|
||||||
channels: __DIR__ . '/../routes/channels.php',
|
channels: __DIR__.'/../routes/channels.php',
|
||||||
health: '/up',
|
health: '/up',
|
||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware): void {
|
->withMiddleware(function (Middleware $middleware): void {
|
||||||
@ -31,6 +31,6 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
})
|
})
|
||||||
->withExceptions(function (Exceptions $exceptions): void {
|
->withExceptions(function (Exceptions $exceptions): void {
|
||||||
$exceptions->shouldRenderJsonWhen(
|
$exceptions->shouldRenderJsonWhen(
|
||||||
fn(Request $request) => $request->is('api/*'),
|
fn (Request $request) => $request->is('api/*'),
|
||||||
);
|
);
|
||||||
})->create();
|
})->create();
|
||||||
|
|||||||
@ -3,11 +3,13 @@
|
|||||||
use App\Providers\AppServiceProvider;
|
use App\Providers\AppServiceProvider;
|
||||||
use App\Providers\AuthServiceProvider;
|
use App\Providers\AuthServiceProvider;
|
||||||
use App\Providers\FortifyServiceProvider;
|
use App\Providers\FortifyServiceProvider;
|
||||||
|
use Illuminate\Broadcasting\BroadcastServiceProvider;
|
||||||
|
use Tighten\Ziggy\ZiggyServiceProvider;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
AppServiceProvider::class,
|
AppServiceProvider::class,
|
||||||
AuthServiceProvider::class,
|
AuthServiceProvider::class,
|
||||||
FortifyServiceProvider::class,
|
FortifyServiceProvider::class,
|
||||||
\Illuminate\Broadcasting\BroadcastServiceProvider::class,
|
BroadcastServiceProvider::class,
|
||||||
\Tighten\Ziggy\ZiggyServiceProvider::class,
|
ZiggyServiceProvider::class,
|
||||||
];
|
];
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class DynamicFactory extends Factory
|
|||||||
'Obsidian Household Agreement',
|
'Obsidian Household Agreement',
|
||||||
'Crimson Castle Protocol',
|
'Crimson Castle Protocol',
|
||||||
'Dungeon Master-Sub Board',
|
'Dungeon Master-Sub Board',
|
||||||
'Coffee Club Ledger'
|
'Coffee Club Ledger',
|
||||||
]),
|
]),
|
||||||
'rules' => "1. All rules must be strictly adhered to.\n2. Scores must be updated after every task.\n3. Disputed scores can be discussed in the dedicated chat.",
|
'rules' => "1. All rules must be strictly adhered to.\n2. Scores must be updated after every task.\n3. Disputed scores can be discussed in the dedicated chat.",
|
||||||
];
|
];
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Ledger;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
|
use App\Models\Ledger;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +26,7 @@ class LedgerFactory extends Factory
|
|||||||
'Dungeon Cleaning',
|
'Dungeon Cleaning',
|
||||||
'Silence Protocol',
|
'Silence Protocol',
|
||||||
'Task Completion',
|
'Task Completion',
|
||||||
'Tribute Points'
|
'Tribute Points',
|
||||||
]),
|
]),
|
||||||
'rules' => 'Scores are added by Doms and subtracted for protocol breaches.',
|
'rules' => 'Scores are added by Doms and subtracted for protocol breaches.',
|
||||||
'score' => 0,
|
'score' => 0,
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Message;
|
|
||||||
use App\Models\Chat;
|
use App\Models\Chat;
|
||||||
|
use App\Models\Message;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\Mutation;
|
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
|
use App\Models\Mutation;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,10 @@ use Illuminate\Database\Migrations\Migration;
|
|||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration {
|
return new class extends Migration
|
||||||
public function up(): void {
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
Schema::create('media', function (Blueprint $table) {
|
Schema::create('media', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->morphs('mediable'); // mediable_type, mediable_id
|
$table->morphs('mediable'); // mediable_type, mediable_id
|
||||||
@ -16,7 +18,8 @@ return new class extends Migration {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void {
|
public function down(): void
|
||||||
|
{
|
||||||
Schema::dropIfExists('media');
|
Schema::dropIfExists('media');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,8 +4,10 @@ use Illuminate\Database\Migrations\Migration;
|
|||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration {
|
return new class extends Migration
|
||||||
public function up(): void {
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
Schema::create('dynamic_invitations', function (Blueprint $table) {
|
Schema::create('dynamic_invitations', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('dynamic_id')->constrained()->cascadeOnDelete();
|
$table->foreignId('dynamic_id')->constrained()->cascadeOnDelete();
|
||||||
@ -17,7 +19,8 @@ return new class extends Migration {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void {
|
public function down(): void
|
||||||
|
{
|
||||||
Schema::dropIfExists('dynamic_invitations');
|
Schema::dropIfExists('dynamic_invitations');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Dynamic;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing rows with UUIDs
|
// Populate existing rows with UUIDs
|
||||||
\App\Models\Dynamic::all()->each(function ($model) {
|
Dynamic::all()->each(function ($model) {
|
||||||
$model->uuid = \Illuminate\Support\Str::uuid();
|
$model->uuid = Str::uuid();
|
||||||
$model->save();
|
$model->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Ledger;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing rows with UUIDs
|
// Populate existing rows with UUIDs
|
||||||
\App\Models\Ledger::all()->each(function ($model) {
|
Ledger::all()->each(function ($model) {
|
||||||
$model->uuid = \Illuminate\Support\Str::uuid();
|
$model->uuid = Str::uuid();
|
||||||
$model->save();
|
$model->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\Mutation;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing rows with UUIDs
|
// Populate existing rows with UUIDs
|
||||||
\App\Models\Mutation::all()->each(function ($model) {
|
Mutation::all()->each(function ($model) {
|
||||||
$model->uuid = \Illuminate\Support\Str::uuid();
|
$model->uuid = Str::uuid();
|
||||||
$model->save();
|
$model->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\PredefinedMutation;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing rows with UUIDs
|
// Populate existing rows with UUIDs
|
||||||
\App\Models\PredefinedMutation::all()->each(function ($model) {
|
PredefinedMutation::all()->each(function ($model) {
|
||||||
$model->uuid = \Illuminate\Support\Str::uuid();
|
$model->uuid = Str::uuid();
|
||||||
$model->save();
|
$model->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
@ -16,8 +18,8 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Populate existing rows with UUIDs
|
// Populate existing rows with UUIDs
|
||||||
\App\Models\User::all()->each(function ($model) {
|
User::all()->each(function ($model) {
|
||||||
$model->uuid = \Illuminate\Support\Str::uuid();
|
$model->uuid = Str::uuid();
|
||||||
$model->save();
|
$model->save();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
|
use App\Models\Mutation;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
class DatabaseSeeder extends Seeder
|
class DatabaseSeeder extends Seeder
|
||||||
{
|
{
|
||||||
@ -246,7 +246,6 @@ class DatabaseSeeder extends Seeder
|
|||||||
'status' => 'approved',
|
'status' => 'approved',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
// 3. Seed Dynamic 2: Obsidian Household Agreement
|
// 3. Seed Dynamic 2: Obsidian Household Agreement
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
|
|||||||
@ -2,15 +2,20 @@
|
|||||||
|
|
||||||
use App\Http\Controllers\DashboardController;
|
use App\Http\Controllers\DashboardController;
|
||||||
use App\Http\Controllers\DynamicController;
|
use App\Http\Controllers\DynamicController;
|
||||||
|
use App\Http\Controllers\DynamicInvitationController;
|
||||||
use App\Http\Controllers\LedgerController;
|
use App\Http\Controllers\LedgerController;
|
||||||
use App\Http\Controllers\MessageController;
|
use App\Http\Controllers\MessageController;
|
||||||
use App\Http\Controllers\MutationController;
|
use App\Http\Controllers\MutationController;
|
||||||
|
use App\Http\Controllers\ParticipantController;
|
||||||
|
use App\Http\Controllers\PredefinedMutationController;
|
||||||
|
use App\Http\Controllers\WebPushController;
|
||||||
|
use Illuminate\Support\Facades\Broadcast;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::inertia('/', 'Welcome')->name('home');
|
Route::inertia('/', 'Welcome')->name('home');
|
||||||
|
|
||||||
Route::post('subscriptions', [\App\Http\Controllers\WebPushController::class, 'store'])->name('subscriptions.store');
|
Route::post('subscriptions', [WebPushController::class, 'store'])->name('subscriptions.store');
|
||||||
Route::post('subscriptions/delete', [\App\Http\Controllers\WebPushController::class, 'destroy'])->name('subscriptions.destroy');
|
Route::post('subscriptions/delete', [WebPushController::class, 'destroy'])->name('subscriptions.destroy');
|
||||||
|
|
||||||
Route::middleware(['auth', 'verified'])->group(function () {
|
Route::middleware(['auth', 'verified'])->group(function () {
|
||||||
Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
||||||
@ -25,23 +30,23 @@ Route::middleware(['auth', 'verified'])->group(function () {
|
|||||||
Route::put('/dynamics/{dynamic}/ledgers/{ledger}/close', [LedgerController::class, 'close'])->name('dynamics.ledgers.close');
|
Route::put('/dynamics/{dynamic}/ledgers/{ledger}/close', [LedgerController::class, 'close'])->name('dynamics.ledgers.close');
|
||||||
Route::resource('dynamics.ledgers', LedgerController::class)->scoped()->except(['create']);
|
Route::resource('dynamics.ledgers', LedgerController::class)->scoped()->except(['create']);
|
||||||
|
|
||||||
Route::resource('dynamics.predefined-mutations', \App\Http\Controllers\PredefinedMutationController::class)->scoped();
|
Route::resource('dynamics.predefined-mutations', PredefinedMutationController::class)->scoped();
|
||||||
|
|
||||||
Route::put('/dynamics/{dynamic}/ledgers/{ledger}/mutations/{mutation}/void', [\App\Http\Controllers\MutationController::class, 'void'])->name('dynamics.ledgers.mutations.void');
|
Route::put('/dynamics/{dynamic}/ledgers/{ledger}/mutations/{mutation}/void', [MutationController::class, 'void'])->name('dynamics.ledgers.mutations.void');
|
||||||
Route::resource('dynamics.ledgers.mutations', MutationController::class)->scoped();
|
Route::resource('dynamics.ledgers.mutations', MutationController::class)->scoped();
|
||||||
|
|
||||||
Route::get('/dynamics/{dynamic}/invitations/create', [\App\Http\Controllers\DynamicInvitationController::class, 'create'])->name('dynamics.invitations.create');
|
Route::get('/dynamics/{dynamic}/invitations/create', [DynamicInvitationController::class, 'create'])->name('dynamics.invitations.create');
|
||||||
Route::post('/dynamics/{dynamic}/invitations', [\App\Http\Controllers\DynamicInvitationController::class, 'store'])->name('dynamics.invitations.store');
|
Route::post('/dynamics/{dynamic}/invitations', [DynamicInvitationController::class, 'store'])->name('dynamics.invitations.store');
|
||||||
|
|
||||||
Route::post('/chats/{chat}/messages', [MessageController::class, 'store'])->name('chats.messages.store');
|
Route::post('/chats/{chat}/messages', [MessageController::class, 'store'])->name('chats.messages.store');
|
||||||
|
|
||||||
Route::put('/dynamics/{dynamic}/participant', [\App\Http\Controllers\ParticipantController::class, 'update'])->name('dynamics.participant.update');
|
Route::put('/dynamics/{dynamic}/participant', [ParticipantController::class, 'update'])->name('dynamics.participant.update');
|
||||||
Route::get('/dynamics/{dynamic}/users/{user}', [\App\Http\Controllers\ParticipantController::class, 'show'])->name('dynamics.users.show');
|
Route::get('/dynamics/{dynamic}/users/{user}', [ParticipantController::class, 'show'])->name('dynamics.users.show');
|
||||||
});
|
});
|
||||||
|
|
||||||
Route::get('/invitations/accept/{token}', [\App\Http\Controllers\DynamicInvitationController::class, 'accept'])
|
Route::get('/invitations/accept/{token}', [DynamicInvitationController::class, 'accept'])
|
||||||
->middleware(['auth', 'signed'])
|
->middleware(['auth', 'signed'])
|
||||||
->name('dynamics.invitations.accept');
|
->name('dynamics.invitations.accept');
|
||||||
|
|
||||||
\Illuminate\Support\Facades\Broadcast::routes();
|
Broadcast::routes();
|
||||||
require __DIR__.'/settings.php';
|
require __DIR__.'/settings.php';
|
||||||
|
|||||||
@ -4,7 +4,6 @@ namespace Tests\Browser;
|
|||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Laravel\Dusk\Browser;
|
use Laravel\Dusk\Browser;
|
||||||
use Tests\DuskTestCase;
|
|
||||||
|
|
||||||
test('user can register, log in, and log out', function () {
|
test('user can register, log in, and log out', function () {
|
||||||
$this->browse(function (Browser $browser) {
|
$this->browse(function (Browser $browser) {
|
||||||
|
|||||||
@ -2,12 +2,11 @@
|
|||||||
|
|
||||||
namespace Tests\Browser;
|
namespace Tests\Browser;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
use App\Models\Mutation;
|
||||||
|
use App\Models\User;
|
||||||
use Laravel\Dusk\Browser;
|
use Laravel\Dusk\Browser;
|
||||||
use Tests\DuskTestCase;
|
|
||||||
|
|
||||||
test('access control and actions are enforced for owners and participants', function () {
|
test('access control and actions are enforced for owners and participants', function () {
|
||||||
// Create database state
|
// Create database state
|
||||||
@ -46,7 +45,7 @@ test('access control and actions are enforced for owners and participants', func
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->browse(function (Browser $sessionOwner, Browser $sessionParticipant, Browser $sessionOutsider) use ($dynamic, $ledger, $owner, $participant, $outsider) {
|
$this->browse(function (Browser $sessionOwner, Browser $sessionParticipant, Browser $sessionOutsider) use ($dynamic, $ledger, $owner, $participant, $outsider) {
|
||||||
|
|
||||||
// 1. Test Outsider trying to access dynamic they DO NOT belong to (should be forbidden / 403)
|
// 1. Test Outsider trying to access dynamic they DO NOT belong to (should be forbidden / 403)
|
||||||
$sessionOutsider->loginAs($outsider)
|
$sessionOutsider->loginAs($outsider)
|
||||||
->visit(route('dynamics.show', $dynamic))
|
->visit(route('dynamics.show', $dynamic))
|
||||||
|
|||||||
@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
namespace Tests\Browser;
|
namespace Tests\Browser;
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\User;
|
||||||
use Laravel\Dusk\Browser;
|
use Laravel\Dusk\Browser;
|
||||||
use Tests\DuskTestCase;
|
|
||||||
|
|
||||||
test('multiple sessions can communicate in real time through websockets', function () {
|
test('multiple sessions can communicate in real time through websockets', function () {
|
||||||
// 1. Create realistic database state
|
// 1. Create realistic database state
|
||||||
@ -15,7 +13,7 @@ test('multiple sessions can communicate in real time through websockets', functi
|
|||||||
'email' => 'test-owner@example.com',
|
'email' => 'test-owner@example.com',
|
||||||
'password' => bcrypt('password'),
|
'password' => bcrypt('password'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$participant = User::factory()->create([
|
$participant = User::factory()->create([
|
||||||
'name' => 'Submissive Bob',
|
'name' => 'Submissive Bob',
|
||||||
'email' => 'test-sub@example.com',
|
'email' => 'test-sub@example.com',
|
||||||
@ -32,7 +30,7 @@ test('multiple sessions can communicate in real time through websockets', functi
|
|||||||
|
|
||||||
// 2. Spawn two separate browser sessions/browsers in parallel
|
// 2. Spawn two separate browser sessions/browsers in parallel
|
||||||
$this->browse(function (Browser $sessionA, Browser $sessionB) use ($dynamic, $owner, $participant) {
|
$this->browse(function (Browser $sessionA, Browser $sessionB) use ($dynamic, $owner, $participant) {
|
||||||
|
|
||||||
// --- SESSION A: Owner ---
|
// --- SESSION A: Owner ---
|
||||||
$sessionA->loginAs($owner)
|
$sessionA->loginAs($owner)
|
||||||
->visit(route('dynamics.show', $dynamic))
|
->visit(route('dynamics.show', $dynamic))
|
||||||
|
|||||||
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
|
|
||||||
use Laravel\Dusk\TestCase as BaseTestCase;
|
|
||||||
use Facebook\WebDriver\Chrome\ChromeOptions;
|
use Facebook\WebDriver\Chrome\ChromeOptions;
|
||||||
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
|
||||||
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||||
|
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||||
|
use Laravel\Dusk\TestCase as BaseTestCase;
|
||||||
|
|
||||||
abstract class DuskTestCase extends BaseTestCase
|
abstract class DuskTestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
|
||||||
use App\Models\Message;
|
use App\Models\Message;
|
||||||
|
use App\Models\User;
|
||||||
use App\Services\ActivityService;
|
use App\Services\ActivityService;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ test('dashboard groups and filters unread entities correctly based on cursor', f
|
|||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
'content' => 'Old message context',
|
'content' => 'Old message context',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Artificially advance cursor to after past message
|
// Artificially advance cursor to after past message
|
||||||
Carbon::setTestNow(Carbon::now()->addMinutes(5));
|
Carbon::setTestNow(Carbon::now()->addMinutes(5));
|
||||||
$service = app(ActivityService::class);
|
$service = app(ActivityService::class);
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Mail\DynamicInvitationMail;
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\DynamicInvitation;
|
use App\Models\DynamicInvitation;
|
||||||
use App\Mail\DynamicInvitationMail;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
test('dynamic owners can view ledger creation form and create ledgers', function () {
|
test('dynamic owners can view ledger creation form and create ledgers', function () {
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
|
||||||
use App\Models\Message;
|
|
||||||
use App\Models\Media;
|
use App\Models\Media;
|
||||||
|
use App\Models\Message;
|
||||||
|
use App\Models\Mutation;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
use App\Models\Mutation;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
test('owner can create a mutation which is automatically approved and does not say Approved', function () {
|
test('owner can create a mutation which is automatically approved and does not say Approved', function () {
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
use App\Models\Ledger;
|
||||||
use App\Models\Mutation;
|
use App\Models\Mutation;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
test('authenticated participant can view another participant detail page in dynamic', function () {
|
test('authenticated participant can view another participant detail page in dynamic', function () {
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
$participant = User::factory()->create();
|
$participant = User::factory()->create();
|
||||||
$dynamic = Dynamic::factory()->create();
|
$dynamic = Dynamic::factory()->create();
|
||||||
|
|
||||||
$dynamic->participants()->attach($owner->id, ['role' => 'owner', 'display_name' => 'The Boss']);
|
$dynamic->participants()->attach($owner->id, ['role' => 'owner', 'display_name' => 'The Boss']);
|
||||||
$dynamic->participants()->attach($participant->id, ['role' => 'participant']);
|
$dynamic->participants()->attach($participant->id, ['role' => 'participant']);
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ test('non-participant cannot view participant detail page in dynamic', function
|
|||||||
$participant = User::factory()->create();
|
$participant = User::factory()->create();
|
||||||
$outsider = User::factory()->create();
|
$outsider = User::factory()->create();
|
||||||
$dynamic = Dynamic::factory()->create();
|
$dynamic = Dynamic::factory()->create();
|
||||||
|
|
||||||
$dynamic->participants()->attach($owner->id, ['role' => 'owner']);
|
$dynamic->participants()->attach($owner->id, ['role' => 'owner']);
|
||||||
$dynamic->participants()->attach($participant->id, ['role' => 'participant']);
|
$dynamic->participants()->attach($participant->id, ['role' => 'participant']);
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ test('participant detail page displays their recent mutations in dynamic', funct
|
|||||||
$participant = User::factory()->create();
|
$participant = User::factory()->create();
|
||||||
$dynamic = Dynamic::factory()->create();
|
$dynamic = Dynamic::factory()->create();
|
||||||
$ledger = Ledger::factory()->create(['dynamic_id' => $dynamic->id]);
|
$ledger = Ledger::factory()->create(['dynamic_id' => $dynamic->id]);
|
||||||
|
|
||||||
$dynamic->participants()->attach($owner->id, ['role' => 'owner']);
|
$dynamic->participants()->attach($owner->id, ['role' => 'owner']);
|
||||||
$dynamic->participants()->attach($participant->id, ['role' => 'participant', 'display_name' => 'Bitch']);
|
$dynamic->participants()->attach($participant->id, ['role' => 'participant', 'display_name' => 'Bitch']);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ test('participant detail page displays their recent mutations in dynamic', funct
|
|||||||
'amount' => 10,
|
'amount' => 10,
|
||||||
'description' => 'Chore 1',
|
'description' => 'Chore 1',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$mutation2 = Mutation::factory()->create([
|
$mutation2 = Mutation::factory()->create([
|
||||||
'ledger_id' => $ledger->id,
|
'ledger_id' => $ledger->id,
|
||||||
'user_id' => $participant->id,
|
'user_id' => $participant->id,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
test('user displayNameFor returns user name by default', function () {
|
test('user displayNameFor returns user name by default', function () {
|
||||||
$user = User::factory()->create(['name' => 'Alice']);
|
$user = User::factory()->create(['name' => 'Alice']);
|
||||||
@ -34,7 +34,7 @@ test('participant can update their display name', function () {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$response->assertRedirect();
|
$response->assertRedirect();
|
||||||
|
|
||||||
// Check database
|
// Check database
|
||||||
$this->assertDatabaseHas('participants', [
|
$this->assertDatabaseHas('participants', [
|
||||||
'user_id' => $user->id,
|
'user_id' => $user->id,
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Dynamic;
|
use App\Models\Dynamic;
|
||||||
use App\Models\Ledger;
|
|
||||||
use App\Models\PredefinedMutation;
|
use App\Models\PredefinedMutation;
|
||||||
|
use App\Models\User;
|
||||||
|
|
||||||
test('owner can view predefined mutations for dynamic', function () {
|
test('owner can view predefined mutations for dynamic', function () {
|
||||||
$owner = User::factory()->create();
|
$owner = User::factory()->create();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user