17 changed files with 772 additions and 0 deletions
-
120app/Http/Controllers/OutletController.php
-
29app/Outlet.php
-
64app/Policies/OutletPolicy.php
-
1app/Providers/AuthServiceProvider.php
-
16database/factories/OutletFactory.php
-
36database/migrations/2018_12_10_125521_create_outlets_table.php
-
18resources/lang/en/app.php
-
33resources/lang/en/outlet.php
-
32resources/views/outlets/create.blade.php
-
60resources/views/outlets/edit.blade.php
-
56resources/views/outlets/index.blade.php
-
27resources/views/outlets/show.blade.php
-
5routes/web.php
-
32tests/BrowserKitTest.php
-
162tests/Feature/ManageOutletTest.php
-
38tests/Unit/Models/OutletTest.php
-
43tests/Unit/Policies/OutletPolicyTest.php
@ -0,0 +1,120 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers; |
|||
|
|||
use App\Outlet; |
|||
use Illuminate\Http\Request; |
|||
|
|||
class OutletController extends Controller |
|||
{ |
|||
/** |
|||
* Display a listing of the outlet. |
|||
* |
|||
* @return \Illuminate\View\View |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$outletQuery = Outlet::query(); |
|||
$outletQuery->where('name', 'like', '%'.request('q').'%'); |
|||
$outlets = $outletQuery->paginate(25); |
|||
|
|||
return view('outlets.index', compact('outlets')); |
|||
} |
|||
|
|||
/** |
|||
* Show the form for creating a new outlet. |
|||
* |
|||
* @return \Illuminate\View\View |
|||
*/ |
|||
public function create() |
|||
{ |
|||
$this->authorize('create', new Outlet); |
|||
|
|||
return view('outlets.create'); |
|||
} |
|||
|
|||
/** |
|||
* Store a newly created outlet in storage. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @return \Illuminate\Routing\Redirector |
|||
*/ |
|||
public function store(Request $request) |
|||
{ |
|||
$this->authorize('create', new Outlet); |
|||
|
|||
$newOutlet = $request->validate([ |
|||
'name' => 'required|max:60', |
|||
'description' => 'nullable|max:255', |
|||
]); |
|||
$newOutlet['creator_id'] = auth()->id(); |
|||
|
|||
$outlet = Outlet::create($newOutlet); |
|||
|
|||
return redirect()->route('outlets.show', $outlet); |
|||
} |
|||
|
|||
/** |
|||
* Display the specified outlet. |
|||
* |
|||
* @param \App\Outlet $outlet |
|||
* @return \Illuminate\View\View |
|||
*/ |
|||
public function show(Outlet $outlet) |
|||
{ |
|||
return view('outlets.show', compact('outlet')); |
|||
} |
|||
|
|||
/** |
|||
* Show the form for editing the specified outlet. |
|||
* |
|||
* @param \App\Outlet $outlet |
|||
* @return \Illuminate\View\View |
|||
*/ |
|||
public function edit(Outlet $outlet) |
|||
{ |
|||
$this->authorize('update', $outlet); |
|||
|
|||
return view('outlets.edit', compact('outlet')); |
|||
} |
|||
|
|||
/** |
|||
* Update the specified outlet in storage. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @param \App\Outlet $outlet |
|||
* @return \Illuminate\Routing\Redirector |
|||
*/ |
|||
public function update(Request $request, Outlet $outlet) |
|||
{ |
|||
$this->authorize('update', $outlet); |
|||
|
|||
$outletData = $request->validate([ |
|||
'name' => 'required|max:60', |
|||
'description' => 'nullable|max:255', |
|||
]); |
|||
$outlet->update($outletData); |
|||
|
|||
return redirect()->route('outlets.show', $outlet); |
|||
} |
|||
|
|||
/** |
|||
* Remove the specified outlet from storage. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @param \App\Outlet $outlet |
|||
* @return \Illuminate\Routing\Redirector |
|||
*/ |
|||
public function destroy(Request $request, Outlet $outlet) |
|||
{ |
|||
$this->authorize('delete', $outlet); |
|||
|
|||
$request->validate(['outlet_id' => 'required']); |
|||
|
|||
if ($request->get('outlet_id') == $outlet->id && $outlet->delete()) { |
|||
return redirect()->route('outlets.index'); |
|||
} |
|||
|
|||
return back(); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
<?php |
|||
|
|||
namespace App; |
|||
|
|||
use App\User; |
|||
use Illuminate\Database\Eloquent\Model; |
|||
|
|||
class Outlet extends Model |
|||
{ |
|||
protected $fillable = ['name', 'description', 'creator_id']; |
|||
|
|||
public function getNameLinkAttribute() |
|||
{ |
|||
$title = __('app.show_detail_title', [ |
|||
'name' => $this->name, 'type' => __('outlet.outlet'), |
|||
]); |
|||
$link = '<a href="'.route('outlets.show', $this).'"'; |
|||
$link .= ' title="'.$title.'">'; |
|||
$link .= $this->name; |
|||
$link .= '</a>'; |
|||
|
|||
return $link; |
|||
} |
|||
|
|||
public function creator() |
|||
{ |
|||
return $this->belongsTo(User::class); |
|||
} |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
<?php |
|||
|
|||
namespace App\Policies; |
|||
|
|||
use App\User; |
|||
use App\Outlet; |
|||
use Illuminate\Auth\Access\HandlesAuthorization; |
|||
|
|||
class OutletPolicy |
|||
{ |
|||
use HandlesAuthorization; |
|||
|
|||
/** |
|||
* Determine whether the user can view the outlet. |
|||
* |
|||
* @param \App\User $user |
|||
* @param \App\Outlet $outlet |
|||
* @return mixed |
|||
*/ |
|||
public function view(User $user, Outlet $outlet) |
|||
{ |
|||
// Update $user authorization to view $outlet here.
|
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* Determine whether the user can create outlet. |
|||
* |
|||
* @param \App\User $user |
|||
* @param \App\Outlet $outlet |
|||
* @return mixed |
|||
*/ |
|||
public function create(User $user, Outlet $outlet) |
|||
{ |
|||
// Update $user authorization to create $outlet here.
|
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* Determine whether the user can update the outlet. |
|||
* |
|||
* @param \App\User $user |
|||
* @param \App\Outlet $outlet |
|||
* @return mixed |
|||
*/ |
|||
public function update(User $user, Outlet $outlet) |
|||
{ |
|||
// Update $user authorization to update $outlet here.
|
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* Determine whether the user can delete the outlet. |
|||
* |
|||
* @param \App\User $user |
|||
* @param \App\Outlet $outlet |
|||
* @return mixed |
|||
*/ |
|||
public function delete(User $user, Outlet $outlet) |
|||
{ |
|||
// Update $user authorization to delete $outlet here.
|
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<?php |
|||
|
|||
use App\User; |
|||
use App\Outlet; |
|||
use Faker\Generator as Faker; |
|||
|
|||
$factory->define(Outlet::class, function (Faker $faker) { |
|||
|
|||
return [ |
|||
'name' => $faker->word, |
|||
'description' => $faker->sentence, |
|||
'creator_id' => function () { |
|||
return factory(User::class)->create()->id; |
|||
}, |
|||
]; |
|||
}); |
|||
@ -0,0 +1,36 @@ |
|||
<?php |
|||
|
|||
use Illuminate\Support\Facades\Schema; |
|||
use Illuminate\Database\Schema\Blueprint; |
|||
use Illuminate\Database\Migrations\Migration; |
|||
|
|||
class CreateOutletsTable extends Migration |
|||
{ |
|||
/** |
|||
* Run the migrations. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function up() |
|||
{ |
|||
Schema::create('outlets', function (Blueprint $table) { |
|||
$table->increments('id'); |
|||
$table->string('name', 60); |
|||
$table->string('description')->nullable(); |
|||
$table->unsignedInteger('creator_id'); |
|||
$table->timestamps(); |
|||
|
|||
$table->foreign('creator_id')->references('id')->on('users')->onDelete('restrict'); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* Reverse the migrations. |
|||
* |
|||
* @return void |
|||
*/ |
|||
public function down() |
|||
{ |
|||
Schema::dropIfExists('outlets'); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
// Labels
|
|||
'table_no' => '#', |
|||
'total' => 'Total', |
|||
'action' => 'Actions', |
|||
'show_detail_title' => 'View :name :type detail', |
|||
|
|||
// Actions
|
|||
'show' => 'View Detail', |
|||
'edit' => 'Edit', |
|||
'delete' => 'Delete', |
|||
'cancel' => 'Cancel', |
|||
'reset' => 'Reset', |
|||
'delete_confirm' => 'Are you sure to delete this?', |
|||
'delete_confirm_button' => 'YES, delete it!', |
|||
]; |
|||
@ -0,0 +1,33 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
// Labels
|
|||
'outlet' => 'Outlet', |
|||
'list' => 'Outlet List', |
|||
'search' => 'Search Outlet', |
|||
'search_text' => 'Name ...', |
|||
'all' => 'All Outlet', |
|||
'select' => 'Select Outlet', |
|||
'detail' => 'Outlet Detail', |
|||
'not_found' => 'Outlet not found.', |
|||
'empty' => 'Outlet is empty.', |
|||
'back_to_show' => 'Back to Outlet Detail', |
|||
'back_to_index' => 'Back to Outlet List', |
|||
|
|||
// Actions
|
|||
'create' => 'Create new Outlet', |
|||
'created' => 'A new Outlet has been created.', |
|||
'show' => 'View Outlet Detail', |
|||
'edit' => 'Edit Outlet', |
|||
'update' => 'Update Outlet', |
|||
'updated' => 'Outlet data has been updated.', |
|||
'delete' => 'Delete Outlet', |
|||
'delete_confirm' => 'Are you sure to delete this Outlet?', |
|||
'deleted' => 'Outlet has been deleted.', |
|||
'undeleted' => 'Outlet not deleted.', |
|||
'undeleteable' => 'Outlet data cannot be deleted.', |
|||
|
|||
// Attributes
|
|||
'name' => 'Outlet Name', |
|||
'description' => 'Outlet Description', |
|||
]; |
|||
@ -0,0 +1,32 @@ |
|||
@extends('layouts.app') |
|||
|
|||
@section('title', __('outlet.create')) |
|||
|
|||
@section('content') |
|||
<div class="row justify-content-center"> |
|||
<div class="col-md-6"> |
|||
<div class="card"> |
|||
<div class="card-header">{{ __('outlet.create') }}</div> |
|||
<form method="POST" action="{{ route('outlets.store') }}" accept-charset="UTF-8"> |
|||
{{ csrf_field() }} |
|||
<div class="card-body"> |
|||
<div class="form-group"> |
|||
<label for="name" class="control-label">{{ __('outlet.name') }}</label> |
|||
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name') }}" required> |
|||
{!! $errors->first('name', '<span class="invalid-feedback" role="alert">:message</span>') !!} |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="description" class="control-label">{{ __('outlet.description') }}</label> |
|||
<textarea id="description" class="form-control{{ $errors->has('description') ? ' is-invalid' : '' }}" name="description" rows="4">{{ old('description') }}</textarea> |
|||
{!! $errors->first('description', '<span class="invalid-feedback" role="alert">:message</span>') !!} |
|||
</div> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<input type="submit" value="{{ __('outlet.create') }}" class="btn btn-success"> |
|||
<a href="{{ route('outlets.index') }}" class="btn btn-link">{{ __('app.cancel') }}</a> |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@endsection |
|||
@ -0,0 +1,60 @@ |
|||
@extends('layouts.app') |
|||
|
|||
@section('title', __('outlet.edit')) |
|||
|
|||
@section('content') |
|||
<div class="row justify-content-center"> |
|||
<div class="col-md-6"> |
|||
@if (request('action') == 'delete' && $outlet) |
|||
@can('delete', $outlet) |
|||
<div class="card"> |
|||
<div class="card-header">{{ __('outlet.delete') }}</div> |
|||
<div class="card-body"> |
|||
<label class="control-label text-primary">{{ __('outlet.name') }}</label> |
|||
<p>{{ $outlet->name }}</p> |
|||
<label class="control-label text-primary">{{ __('outlet.description') }}</label> |
|||
<p>{{ $outlet->description }}</p> |
|||
{!! $errors->first('outlet_id', '<span class="invalid-feedback" role="alert">:message</span>') !!} |
|||
</div> |
|||
<hr style="margin:0"> |
|||
<div class="card-body text-danger">{{ __('outlet.delete_confirm') }}</div> |
|||
<div class="card-footer"> |
|||
<form method="POST" action="{{ route('outlets.destroy', $outlet) }}" accept-charset="UTF-8" onsubmit="return confirm("{{ __('app.delete_confirm') }}")" class="del-form float-right" style="display: inline;"> |
|||
{{ csrf_field() }} {{ method_field('delete') }} |
|||
<input name="outlet_id" type="hidden" value="{{ $outlet->id }}"> |
|||
<button type="submit" class="btn btn-danger">{{ __('app.delete_confirm_button') }}</button> |
|||
</form> |
|||
<a href="{{ route('outlets.edit', $outlet) }}" class="btn btn-link">{{ __('app.cancel') }}</a> |
|||
</div> |
|||
</div> |
|||
@endcan |
|||
@else |
|||
<div class="card"> |
|||
<div class="card-header">{{ __('outlet.edit') }}</div> |
|||
<form method="POST" action="{{ route('outlets.update', $outlet) }}" accept-charset="UTF-8"> |
|||
{{ csrf_field() }} {{ method_field('patch') }} |
|||
<div class="card-body"> |
|||
<div class="form-group"> |
|||
<label for="name" class="control-label">{{ __('outlet.name') }}</label> |
|||
<input id="name" type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" name="name" value="{{ old('name', $outlet->name) }}" required> |
|||
{!! $errors->first('name', '<span class="invalid-feedback" role="alert">:message</span>') !!} |
|||
</div> |
|||
<div class="form-group"> |
|||
<label for="description" class="control-label">{{ __('outlet.description') }}</label> |
|||
<textarea id="description" class="form-control{{ $errors->has('description') ? ' is-invalid' : '' }}" name="description" rows="4">{{ old('description', $outlet->description) }}</textarea> |
|||
{!! $errors->first('description', '<span class="invalid-feedback" role="alert">:message</span>') !!} |
|||
</div> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<input type="submit" value="{{ __('outlet.update') }}" class="btn btn-success"> |
|||
<a href="{{ route('outlets.show', $outlet) }}" class="btn btn-link">{{ __('app.cancel') }}</a> |
|||
@can('delete', $outlet) |
|||
<a href="{{ route('outlets.edit', [$outlet, 'action' => 'delete']) }}" id="del-outlet-{{ $outlet->id }}" class="btn btn-danger float-right">{{ __('app.delete') }}</a> |
|||
@endcan |
|||
</div> |
|||
</form> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@endif |
|||
@endsection |
|||
@ -0,0 +1,56 @@ |
|||
@extends('layouts.app') |
|||
|
|||
@section('title', __('outlet.list')) |
|||
|
|||
@section('content') |
|||
<div class="mb-3"> |
|||
<div class="float-right"> |
|||
@can('create', new App\Outlet) |
|||
<a href="{{ route('outlets.create') }}" class="btn btn-success">{{ __('outlet.create') }}</a> |
|||
@endcan |
|||
</div> |
|||
<h1 class="page-title">{{ __('outlet.list') }} <small>{{ __('app.total') }} : {{ $outlets->total() }} {{ __('outlet.outlet') }}</small></h1> |
|||
</div> |
|||
|
|||
<div class="row"> |
|||
<div class="col-md-12"> |
|||
<div class="card"> |
|||
<div class="card-header"> |
|||
<form method="GET" action="" accept-charset="UTF-8" class="form-inline"> |
|||
<div class="form-group"> |
|||
<label for="q" class="control-label">{{ __('outlet.search') }}</label> |
|||
<input placeholder="{{ __('outlet.search_text') }}" name="q" type="text" id="q" class="form-control mx-sm-2" value="{{ request('q') }}"> |
|||
</div> |
|||
<input type="submit" value="{{ __('outlet.search') }}" class="btn btn-secondary"> |
|||
<a href="{{ route('outlets.index') }}" class="btn btn-link">{{ __('app.reset') }}</a> |
|||
</form> |
|||
</div> |
|||
<table class="table table-sm table-responsive-sm"> |
|||
<thead> |
|||
<tr> |
|||
<th class="text-center">{{ __('app.table_no') }}</th> |
|||
<th>{{ __('outlet.name') }}</th> |
|||
<th>{{ __('outlet.description') }}</th> |
|||
<th class="text-center">{{ __('app.action') }}</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
@foreach($outlets as $key => $outlet) |
|||
<tr> |
|||
<td class="text-center">{{ $outlets->firstItem() + $key }}</td> |
|||
<td>{!! $outlet->name_link !!}</td> |
|||
<td>{{ $outlet->description }}</td> |
|||
<td class="text-center"> |
|||
@can('view', $outlet) |
|||
<a href="{{ route('outlets.show', $outlet) }}" id="show-outlet-{{ $outlet->id }}">{{ __('app.show') }}</a> |
|||
@endcan |
|||
</td> |
|||
</tr> |
|||
@endforeach |
|||
</tbody> |
|||
</table> |
|||
<div class="card-body">{{ $outlets->appends(Request::except('page'))->render() }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@endsection |
|||
@ -0,0 +1,27 @@ |
|||
@extends('layouts.app') |
|||
|
|||
@section('title', __('outlet.detail')) |
|||
|
|||
@section('content') |
|||
<div class="row justify-content-center"> |
|||
<div class="col-md-6"> |
|||
<div class="card"> |
|||
<div class="card-header">{{ __('outlet.detail') }}</div> |
|||
<div class="card-body"> |
|||
<table class="table table-sm"> |
|||
<tbody> |
|||
<tr><td>{{ __('outlet.name') }}</td><td>{{ $outlet->name }}</td></tr> |
|||
<tr><td>{{ __('outlet.description') }}</td><td>{{ $outlet->description }}</td></tr> |
|||
</tbody> |
|||
</table> |
|||
</div> |
|||
<div class="card-footer"> |
|||
@can('update', $outlet) |
|||
<a href="{{ route('outlets.edit', $outlet) }}" id="edit-outlet-{{ $outlet->id }}" class="btn btn-warning">{{ __('outlet.edit') }}</a> |
|||
@endcan |
|||
<a href="{{ route('outlets.index') }}" class="btn btn-link">{{ __('outlet.back_to_index') }}</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
@endsection |
|||
@ -0,0 +1,32 @@ |
|||
<?php |
|||
|
|||
namespace Tests; |
|||
|
|||
use App\User; |
|||
use Laravel\BrowserKitTesting\TestCase as BaseTestCase; |
|||
|
|||
abstract class BrowserKitTest extends BaseTestCase |
|||
{ |
|||
use CreatesApplication; |
|||
|
|||
protected $baseUrl = 'http://localhost'; |
|||
|
|||
protected function setUp() |
|||
{ |
|||
parent::setUp(); |
|||
\Hash::setRounds(5); |
|||
} |
|||
|
|||
protected function loginAsUser() |
|||
{ |
|||
$user = $this->createUser(); |
|||
$this->actingAs($user); |
|||
|
|||
return $user; |
|||
} |
|||
|
|||
protected function createUser() |
|||
{ |
|||
return factory(User::class)->create(); |
|||
} |
|||
} |
|||
@ -0,0 +1,162 @@ |
|||
<?php |
|||
|
|||
namespace Tests\Feature; |
|||
|
|||
use App\Outlet; |
|||
use Tests\BrowserKitTest as TestCase; |
|||
use Illuminate\Foundation\Testing\DatabaseMigrations; |
|||
|
|||
class ManageOutletTest extends TestCase |
|||
{ |
|||
use DatabaseMigrations; |
|||
|
|||
/** @test */ |
|||
public function user_can_see_outlet_list_in_outlet_index_page() |
|||
{ |
|||
$outlet = factory(Outlet::class)->create(); |
|||
|
|||
$this->loginAsUser(); |
|||
$this->visitRoute('outlets.index'); |
|||
$this->see($outlet->name); |
|||
} |
|||
|
|||
private function getCreateFields(array $overrides = []) |
|||
{ |
|||
return array_merge([ |
|||
'name' => 'Outlet 1 name', |
|||
'description' => 'Outlet 1 description', |
|||
], $overrides); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_create_a_outlet() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$this->visitRoute('outlets.index'); |
|||
|
|||
$this->click(__('outlet.create')); |
|||
$this->seeRouteIs('outlets.create'); |
|||
|
|||
$this->submitForm(__('outlet.create'), $this->getCreateFields()); |
|||
|
|||
$this->seeRouteIs('outlets.show', Outlet::first()); |
|||
|
|||
$this->seeInDatabase('outlets', $this->getCreateFields()); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_name_is_required() |
|||
{ |
|||
$this->loginAsUser(); |
|||
|
|||
// name empty
|
|||
$this->post(route('outlets.store'), $this->getCreateFields(['name' => ''])); |
|||
$this->assertSessionHasErrors('name'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_name_is_not_more_than_60_characters() |
|||
{ |
|||
$this->loginAsUser(); |
|||
|
|||
// name 70 characters
|
|||
$this->post(route('outlets.store'), $this->getCreateFields([ |
|||
'name' => str_repeat('Test Title', 7), |
|||
])); |
|||
$this->assertSessionHasErrors('name'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_description_is_not_more_than_255_characters() |
|||
{ |
|||
$this->loginAsUser(); |
|||
|
|||
// description 256 characters
|
|||
$this->post(route('outlets.store'), $this->getCreateFields([ |
|||
'description' => str_repeat('Long description', 16), |
|||
])); |
|||
$this->assertSessionHasErrors('description'); |
|||
} |
|||
|
|||
private function getEditFields(array $overrides = []) |
|||
{ |
|||
return array_merge([ |
|||
'name' => 'Outlet 1 name', |
|||
'description' => 'Outlet 1 description', |
|||
], $overrides); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_edit_a_outlet() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$outlet = factory(Outlet::class)->create(['name' => 'Testing 123']); |
|||
|
|||
$this->visitRoute('outlets.show', $outlet); |
|||
$this->click('edit-outlet-'.$outlet->id); |
|||
$this->seeRouteIs('outlets.edit', $outlet); |
|||
|
|||
$this->submitForm(__('outlet.update'), $this->getEditFields()); |
|||
|
|||
$this->seeRouteIs('outlets.show', $outlet); |
|||
|
|||
$this->seeInDatabase('outlets', $this->getEditFields([ |
|||
'id' => $outlet->id, |
|||
])); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_name_update_is_required() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$outlet = factory(Outlet::class)->create(['name' => 'Testing 123']); |
|||
|
|||
// name empty
|
|||
$this->patch(route('outlets.update', $outlet), $this->getEditFields(['name' => ''])); |
|||
$this->assertSessionHasErrors('name'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_name_update_is_not_more_than_60_characters() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$outlet = factory(Outlet::class)->create(['name' => 'Testing 123']); |
|||
|
|||
// name 70 characters
|
|||
$this->patch(route('outlets.update', $outlet), $this->getEditFields([ |
|||
'name' => str_repeat('Test Title', 7), |
|||
])); |
|||
$this->assertSessionHasErrors('name'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function validate_outlet_description_update_is_not_more_than_255_characters() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$outlet = factory(Outlet::class)->create(['name' => 'Testing 123']); |
|||
|
|||
// description 256 characters
|
|||
$this->patch(route('outlets.update', $outlet), $this->getEditFields([ |
|||
'description' => str_repeat('Long description', 16), |
|||
])); |
|||
$this->assertSessionHasErrors('description'); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_delete_a_outlet() |
|||
{ |
|||
$this->loginAsUser(); |
|||
$outlet = factory(Outlet::class)->create(); |
|||
factory(Outlet::class)->create(); |
|||
|
|||
$this->visitRoute('outlets.edit', $outlet); |
|||
$this->click('del-outlet-'.$outlet->id); |
|||
$this->seeRouteIs('outlets.edit', [$outlet, 'action' => 'delete']); |
|||
|
|||
$this->press(__('app.delete_confirm_button')); |
|||
|
|||
$this->dontSeeInDatabase('outlets', [ |
|||
'id' => $outlet->id, |
|||
]); |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
<?php |
|||
|
|||
namespace Tests\Unit\Models; |
|||
|
|||
use App\User; |
|||
use App\Outlet; |
|||
use Illuminate\Foundation\Testing\DatabaseMigrations; |
|||
use Tests\BrowserKitTest as TestCase; |
|||
|
|||
class OutletTest extends TestCase |
|||
{ |
|||
use DatabaseMigrations; |
|||
|
|||
/** @test */ |
|||
public function a_outlet_has_name_link_attribute() |
|||
{ |
|||
$outlet = factory(Outlet::class)->create(); |
|||
|
|||
$title = __('app.show_detail_title', [ |
|||
'name' => $outlet->name, 'type' => __('outlet.outlet'), |
|||
]); |
|||
$link = '<a href="'.route('outlets.show', $outlet).'"'; |
|||
$link .= ' title="'.$title.'">'; |
|||
$link .= $outlet->name; |
|||
$link .= '</a>'; |
|||
|
|||
$this->assertEquals($link, $outlet->name_link); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function a_outlet_has_belongs_to_creator_relation() |
|||
{ |
|||
$outlet = factory(Outlet::class)->make(); |
|||
|
|||
$this->assertInstanceOf(User::class, $outlet->creator); |
|||
$this->assertEquals($outlet->creator_id, $outlet->creator->id); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
<?php |
|||
|
|||
namespace Tests\Unit\Policies; |
|||
|
|||
use App\Outlet; |
|||
use Illuminate\Foundation\Testing\DatabaseMigrations; |
|||
use Tests\BrowserKitTest as TestCase; |
|||
|
|||
class OutletPolicyTest extends TestCase |
|||
{ |
|||
use DatabaseMigrations; |
|||
|
|||
/** @test */ |
|||
public function user_can_create_outlet() |
|||
{ |
|||
$user = $this->createUser(); |
|||
$this->assertTrue($user->can('create', new Outlet)); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_view_outlet() |
|||
{ |
|||
$user = $this->createUser(); |
|||
$outlet = factory(Outlet::class)->create(); |
|||
$this->assertTrue($user->can('view', $outlet)); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_update_outlet() |
|||
{ |
|||
$user = $this->createUser(); |
|||
$outlet = factory(Outlet::class)->create(); |
|||
$this->assertTrue($user->can('update', $outlet)); |
|||
} |
|||
|
|||
/** @test */ |
|||
public function user_can_delete_outlet() |
|||
{ |
|||
$user = $this->createUser(); |
|||
$outlet = factory(Outlet::class)->create(); |
|||
$this->assertTrue($user->can('delete', $outlet)); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue