Browse Source

Merge branch 'feature-outlet'

pull/3/head
Nafies Luthfi 7 years ago
parent
commit
281e913e8d
  1. 124
      app/Http/Controllers/OutletController.php
  2. 31
      app/Outlet.php
  3. 64
      app/Policies/OutletPolicy.php
  4. 1
      app/Providers/AuthServiceProvider.php
  5. 18
      database/factories/OutletFactory.php
  6. 38
      database/migrations/2018_12_10_125521_create_outlets_table.php
  7. 18
      resources/lang/en/app.php
  8. 35
      resources/lang/en/outlet.php
  9. 5
      resources/views/layouts/app.blade.php
  10. 48
      resources/views/outlets/create.blade.php
  11. 74
      resources/views/outlets/edit.blade.php
  12. 60
      resources/views/outlets/index.blade.php
  13. 29
      resources/views/outlets/show.blade.php
  14. 5
      routes/web.php
  15. 32
      tests/BrowserKitTest.php
  16. 21
      tests/Feature/ExampleTest.php
  17. 166
      tests/Feature/ManageOutletTest.php
  18. 19
      tests/Unit/ExampleTest.php
  19. 38
      tests/Unit/Models/OutletTest.php
  20. 43
      tests/Unit/Policies/OutletPolicyTest.php

124
app/Http/Controllers/OutletController.php

@ -0,0 +1,124 @@
<?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',
'address' => 'nullable|max:255',
'latitude' => 'nullable|required_with:longitude|max:15',
'longitude' => 'nullable|required_with:latitude|max:15',
]);
$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',
'address' => 'nullable|max:255',
'latitude' => 'nullable|required_with:longitude|max:15',
'longitude' => 'nullable|required_with:latitude|max:15',
]);
$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();
}
}

31
app/Outlet.php

@ -0,0 +1,31 @@
<?php
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Outlet extends Model
{
protected $fillable = [
'name', 'address', 'latitude', 'longitude', '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);
}
}

64
app/Policies/OutletPolicy.php

@ -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;
}
}

1
app/Providers/AuthServiceProvider.php

@ -13,6 +13,7 @@ class AuthServiceProvider extends ServiceProvider
* @var array * @var array
*/ */
protected $policies = [ protected $policies = [
'App\Outlet' => 'App\Policies\OutletPolicy',
'App\Model' => 'App\Policies\ModelPolicy', 'App\Model' => 'App\Policies\ModelPolicy',
]; ];

18
database/factories/OutletFactory.php

@ -0,0 +1,18 @@
<?php
use App\User;
use App\Outlet;
use Faker\Generator as Faker;
$factory->define(Outlet::class, function (Faker $faker) {
return [
'name' => ucwords($faker->words(2, true)),
'address' => $faker->address,
'latitude' => $faker->latitude(-3.29, -3.35),
'longitude' => $faker->longitude(114.56, 114.63),
'creator_id' => function () {
return factory(User::class)->create()->id;
},
];
});

38
database/migrations/2018_12_10_125521_create_outlets_table.php

@ -0,0 +1,38 @@
<?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('address')->nullable();
$table->string('latitude', 15)->nullable();
$table->string('longitude', 15)->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');
}
}

18
resources/lang/en/app.php

@ -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!',
];

35
resources/lang/en/outlet.php

@ -0,0 +1,35 @@
<?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',
'address' => 'Outlet Address',
'latitude' => 'Latitude',
'longitude' => 'Longitude',
];

5
resources/views/layouts/app.blade.php

@ -49,6 +49,9 @@
@endif @endif
</li> </li>
@else @else
<li class="nav-item">
<a class="nav-link" href="{{ route('outlets.index') }}">{{ __('outlet.list') }}</a>
</li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre> <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }} <span class="caret"></span> {{ Auth::user()->name }} <span class="caret"></span>
@ -72,7 +75,7 @@
</div> </div>
</nav> </nav>
<main class="py-4">
<main class="py-4 container">
@yield('content') @yield('content')
</main> </main>
</div> </div>

48
resources/views/outlets/create.blade.php

@ -0,0 +1,48 @@
@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="address" class="control-label">{{ __('outlet.address') }}</label>
<textarea id="address" class="form-control{{ $errors->has('address') ? ' is-invalid' : '' }}" name="address" rows="4">{{ old('address') }}</textarea>
{!! $errors->first('address', '<span class="invalid-feedback" role="alert">:message</span>') !!}
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="latitude" class="control-label">{{ __('outlet.latitude') }}</label>
<input id="latitude" type="text" class="form-control{{ $errors->has('latitude') ? ' is-invalid' : '' }}" name="latitude" value="{{ old('latitude') }}" required>
{!! $errors->first('latitude', '<span class="invalid-feedback" role="alert">:message</span>') !!}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="longitude" class="control-label">{{ __('outlet.longitude') }}</label>
<input id="longitude" type="text" class="form-control{{ $errors->has('longitude') ? ' is-invalid' : '' }}" name="longitude" value="{{ old('longitude') }}" required>
{!! $errors->first('longitude', '<span class="invalid-feedback" role="alert">:message</span>') !!}
</div>
</div>
</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

74
resources/views/outlets/edit.blade.php

@ -0,0 +1,74 @@
@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.address') }}</label>
<p>{{ $outlet->address }}</p>
<label class="control-label text-primary">{{ __('outlet.latitude') }}</label>
<p>{{ $outlet->latitude }}</p>
<label class="control-label text-primary">{{ __('outlet.longitude') }}</label>
<p>{{ $outlet->longitude }}</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(&quot;{{ __('app.delete_confirm') }}&quot;)" 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="address" class="control-label">{{ __('outlet.address') }}</label>
<textarea id="address" class="form-control{{ $errors->has('address') ? ' is-invalid' : '' }}" name="address" rows="4">{{ old('address', $outlet->address) }}</textarea>
{!! $errors->first('address', '<span class="invalid-feedback" role="alert">:message</span>') !!}
</div>
<div class="form-group">
<label for="latitude" class="control-label">{{ __('outlet.latitude') }}</label>
<input id="latitude" type="text" class="form-control{{ $errors->has('latitude') ? ' is-invalid' : '' }}" name="latitude" value="{{ old('latitude', $outlet->latitude) }}" required>
{!! $errors->first('latitude', '<span class="invalid-feedback" role="alert">:message</span>') !!}
</div>
<div class="form-group">
<label for="longitude" class="control-label">{{ __('outlet.longitude') }}</label>
<input id="longitude" type="text" class="form-control{{ $errors->has('longitude') ? ' is-invalid' : '' }}" name="longitude" value="{{ old('longitude', $outlet->longitude) }}" required>
{!! $errors->first('longitude', '<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

60
resources/views/outlets/index.blade.php

@ -0,0 +1,60 @@
@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.address') }}</th>
<th>{{ __('outlet.latitude') }}</th>
<th>{{ __('outlet.longitude') }}</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->address }}</td>
<td>{{ $outlet->latitude }}</td>
<td>{{ $outlet->longitude }}</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

29
resources/views/outlets/show.blade.php

@ -0,0 +1,29 @@
@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.address') }}</td><td>{{ $outlet->address }}</td></tr>
<tr><td>{{ __('outlet.latitude') }}</td><td>{{ $outlet->latitude }}</td></tr>
<tr><td>{{ __('outlet.longitude') }}</td><td>{{ $outlet->longitude }}</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

5
routes/web.php

@ -18,3 +18,8 @@ Route::get('/', function () {
Auth::routes(); Auth::routes();
Route::get('/home', 'HomeController@index')->name('home'); Route::get('/home', 'HomeController@index')->name('home');
/*
* Outlets Routes
*/
Route::resource('outlets', 'OutletController');

32
tests/BrowserKitTest.php

@ -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();
}
}

21
tests/Feature/ExampleTest.php

@ -1,21 +0,0 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}

166
tests/Feature/ManageOutletTest.php

@ -0,0 +1,166 @@
<?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',
'address' => 'Outlet 1 address',
'latitude' => '-3.333333',
'longitude' => '114.583333',
], $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_address_is_not_more_than_255_characters()
{
$this->loginAsUser();
// address 256 characters
$this->post(route('outlets.store'), $this->getCreateFields([
'address' => str_repeat('Long outlet address', 16),
]));
$this->assertSessionHasErrors('address');
}
private function getEditFields(array $overrides = [])
{
return array_merge([
'name' => 'Outlet 1 name',
'address' => 'Outlet 1 address',
'latitude' => '-3.333333',
'longitude' => '114.583333',
], $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_address_update_is_not_more_than_255_characters()
{
$this->loginAsUser();
$outlet = factory(Outlet::class)->create(['name' => 'Testing 123']);
// address 256 characters
$this->patch(route('outlets.update', $outlet), $this->getEditFields([
'address' => str_repeat('Long outlet address', 16),
]));
$this->assertSessionHasErrors('address');
}
/** @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,
]);
}
}

19
tests/Unit/ExampleTest.php

@ -1,19 +0,0 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
}

38
tests/Unit/Models/OutletTest.php

@ -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);
}
}

43
tests/Unit/Policies/OutletPolicyTest.php

@ -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));
}
}
Loading…
Cancel
Save