first commit
This commit is contained in:
305
tests/Feature/Teams/TeamTest.php
Normal file
305
tests/Feature/Teams/TeamTest.php
Normal file
@@ -0,0 +1,305 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\TeamRole;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
|
||||
test('the teams index page can be rendered', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->get(route('teams.index'));
|
||||
|
||||
$response->assertOk();
|
||||
});
|
||||
|
||||
test('teams can be created', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->post(route('teams.store'), [
|
||||
'name' => 'Test Team',
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
$this->assertDatabaseHas('teams', [
|
||||
'name' => 'Test Team',
|
||||
'is_personal' => false,
|
||||
]);
|
||||
});
|
||||
|
||||
test('team slug uses next available suffix', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
Team::factory()->create(['name' => 'Acme', 'slug' => 'acme']);
|
||||
Team::factory()->create(['name' => 'Acme One', 'slug' => 'acme-1']);
|
||||
Team::factory()->create(['name' => 'Acme Ten', 'slug' => 'acme-10']);
|
||||
|
||||
$this
|
||||
->actingAs($user)
|
||||
->post(route('teams.store'), [
|
||||
'name' => 'Acme',
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('teams', [
|
||||
'name' => 'Acme',
|
||||
'slug' => 'acme-11',
|
||||
]);
|
||||
});
|
||||
|
||||
test('the team edit page can be rendered', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->get(route('teams.edit', $team));
|
||||
|
||||
$response->assertOk();
|
||||
});
|
||||
|
||||
test('teams can be updated by owners', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create(['name' => 'Original Name']);
|
||||
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->patch(route('teams.update', $team), [
|
||||
'name' => 'Updated Name',
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('teams.edit', $team->fresh()));
|
||||
|
||||
$this->assertDatabaseHas('teams', [
|
||||
'id' => $team->id,
|
||||
'name' => 'Updated Name',
|
||||
]);
|
||||
});
|
||||
|
||||
test('teams cannot be updated by members', function () {
|
||||
$owner = User::factory()->create();
|
||||
$member = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($owner, ['role' => TeamRole::Owner->value]);
|
||||
$team->members()->attach($member, ['role' => TeamRole::Member->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($member)
|
||||
->patch(route('teams.update', $team), [
|
||||
'name' => 'Updated Name',
|
||||
]);
|
||||
|
||||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
test('teams can be deleted by owners', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => $team->name,
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
$this->assertSoftDeleted('teams', [
|
||||
'id' => $team->id,
|
||||
]);
|
||||
});
|
||||
|
||||
test('team deletion requires name confirmation', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => 'Wrong Name',
|
||||
]);
|
||||
|
||||
$response->assertSessionHasErrors('name');
|
||||
|
||||
$this->assertDatabaseHas('teams', [
|
||||
'id' => $team->id,
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
});
|
||||
|
||||
test('deleting current team switches to alphabetically first remaining team', function () {
|
||||
$user = User::factory()->create(['name' => 'Mike']);
|
||||
|
||||
$zuluTeam = Team::factory()->create(['name' => 'Zulu Team']);
|
||||
$zuluTeam->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$alphaTeam = Team::factory()->create(['name' => 'Alpha Team']);
|
||||
$alphaTeam->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$betaTeam = Team::factory()->create(['name' => 'Beta Team']);
|
||||
$betaTeam->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$user->update(['current_team_id' => $zuluTeam->id]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $zuluTeam), [
|
||||
'name' => $zuluTeam->name,
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
$this->assertSoftDeleted('teams', [
|
||||
'id' => $zuluTeam->id,
|
||||
]);
|
||||
|
||||
expect($user->fresh()->current_team_id)->toEqual($alphaTeam->id);
|
||||
});
|
||||
|
||||
test('deleting current team falls back to personal team when alphabetically first', function () {
|
||||
$user = User::factory()->create();
|
||||
$personalTeam = $user->personalTeam();
|
||||
$team = Team::factory()->create(['name' => 'Zulu Team']);
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$user->update(['current_team_id' => $team->id]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => $team->name,
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
$this->assertSoftDeleted('teams', [
|
||||
'id' => $team->id,
|
||||
]);
|
||||
|
||||
expect($user->fresh()->current_team_id)->toEqual($personalTeam->id);
|
||||
});
|
||||
|
||||
test('deleting non current team leaves current team unchanged', function () {
|
||||
$user = User::factory()->create();
|
||||
$personalTeam = $user->personalTeam();
|
||||
$team = Team::factory()->create();
|
||||
$team->members()->attach($user, ['role' => TeamRole::Owner->value]);
|
||||
|
||||
$user->update(['current_team_id' => $personalTeam->id]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => $team->name,
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
$this->assertSoftDeleted('teams', [
|
||||
'id' => $team->id,
|
||||
]);
|
||||
|
||||
expect($user->fresh()->current_team_id)->toEqual($personalTeam->id);
|
||||
});
|
||||
|
||||
test('deleting team switches other affected users to their personal team', function () {
|
||||
$owner = User::factory()->create();
|
||||
$member = User::factory()->create();
|
||||
|
||||
$team = Team::factory()->create();
|
||||
$team->members()->attach($owner, ['role' => TeamRole::Owner->value]);
|
||||
$team->members()->attach($member, ['role' => TeamRole::Member->value]);
|
||||
|
||||
$owner->update(['current_team_id' => $team->id]);
|
||||
$member->update(['current_team_id' => $team->id]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($owner)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => $team->name,
|
||||
]);
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
expect($member->fresh()->current_team_id)->toEqual($member->personalTeam()->id);
|
||||
});
|
||||
|
||||
test('personal teams cannot be deleted', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$personalTeam = $user->personalTeam();
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->delete(route('teams.destroy', $personalTeam), [
|
||||
'name' => $personalTeam->name,
|
||||
]);
|
||||
|
||||
$response->assertForbidden();
|
||||
|
||||
$this->assertDatabaseHas('teams', [
|
||||
'id' => $personalTeam->id,
|
||||
'deleted_at' => null,
|
||||
]);
|
||||
});
|
||||
|
||||
test('teams cannot be deleted by non owners', function () {
|
||||
$owner = User::factory()->create();
|
||||
$member = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($owner, ['role' => TeamRole::Owner->value]);
|
||||
$team->members()->attach($member, ['role' => TeamRole::Member->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($member)
|
||||
->delete(route('teams.destroy', $team), [
|
||||
'name' => $team->name,
|
||||
]);
|
||||
|
||||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
test('users can switch teams', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$team->members()->attach($user, ['role' => TeamRole::Member->value]);
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->post(route('teams.switch', $team));
|
||||
|
||||
$response->assertRedirect();
|
||||
|
||||
expect($user->fresh()->current_team_id)->toEqual($team->id);
|
||||
});
|
||||
|
||||
test('users cannot switch to team they dont belong to', function () {
|
||||
$user = User::factory()->create();
|
||||
$team = Team::factory()->create();
|
||||
|
||||
$response = $this
|
||||
->actingAs($user)
|
||||
->post(route('teams.switch', $team));
|
||||
|
||||
$response->assertForbidden();
|
||||
});
|
||||
|
||||
test('guests cannot access teams', function () {
|
||||
$response = $this->get(route('teams.index'));
|
||||
|
||||
$response->assertRedirect(route('login'));
|
||||
});
|
||||
Reference in New Issue
Block a user