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