feat: Add export import
This commit is contained in:
parent
2ee5d07e48
commit
bb5a078f35
20 changed files with 505 additions and 21 deletions
31
app/Http/Controllers/ImportController.php
Normal file
31
app/Http/Controllers/ImportController.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\View\View;
|
||||||
|
|
||||||
|
class ImportController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Instantiate a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware('allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the incoming request.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return View
|
||||||
|
*/
|
||||||
|
public function __invoke(Request $request): View
|
||||||
|
{
|
||||||
|
return view('items.import');
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,9 +12,9 @@ use GuzzleHttp\Exception\ConnectException;
|
||||||
use GuzzleHttp\Exception\GuzzleException;
|
use GuzzleHttp\Exception\GuzzleException;
|
||||||
use GuzzleHttp\Exception\ServerException;
|
use GuzzleHttp\Exception\ServerException;
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Http\RedirectResponse;
|
use Illuminate\Http\RedirectResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Routing\Redirector;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
|
@ -191,10 +191,10 @@ class ItemController extends Controller
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Request $request
|
* @param Request $request
|
||||||
* @param $id
|
* @param null $id
|
||||||
* @return void
|
* @return Item
|
||||||
*/
|
*/
|
||||||
public function storelogic(Request $request, $id = null)
|
public static function storelogic(Request $request, $id = null): Item
|
||||||
{
|
{
|
||||||
$application = Application::single($request->input('appid'));
|
$application = Application::single($request->input('appid'));
|
||||||
$validatedData = $request->validate([
|
$validatedData = $request->validate([
|
||||||
|
@ -275,6 +275,7 @@ class ItemController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
$item->parents()->sync($request->tags);
|
$item->parents()->sync($request->tags);
|
||||||
|
return $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,7 +286,7 @@ class ItemController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(Request $request): RedirectResponse
|
public function store(Request $request): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->storelogic($request);
|
self::storelogic($request);
|
||||||
|
|
||||||
$route = route('dash', []);
|
$route = route('dash', []);
|
||||||
|
|
||||||
|
@ -313,7 +314,7 @@ class ItemController extends Controller
|
||||||
*/
|
*/
|
||||||
public function update(Request $request, int $id): RedirectResponse
|
public function update(Request $request, int $id): RedirectResponse
|
||||||
{
|
{
|
||||||
$this->storelogic($request, $id);
|
self::storelogic($request, $id);
|
||||||
$route = route('dash', []);
|
$route = route('dash', []);
|
||||||
|
|
||||||
return redirect($route)
|
return redirect($route)
|
||||||
|
|
111
app/Http/Controllers/ItemRestController.php
Normal file
111
app/Http/Controllers/ItemRestController.php
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Item;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Response;
|
||||||
|
|
||||||
|
class ItemRestController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->middleware('allowed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$columns = [
|
||||||
|
'title',
|
||||||
|
'colour',
|
||||||
|
'url',
|
||||||
|
'description',
|
||||||
|
'appid',
|
||||||
|
'appdescription',
|
||||||
|
];
|
||||||
|
|
||||||
|
return Item::select($columns)
|
||||||
|
->where('deleted_at', null)
|
||||||
|
->where('type', '0')
|
||||||
|
->orderBy('order', 'asc')
|
||||||
|
->get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function store(Request $request): object
|
||||||
|
{
|
||||||
|
$item = ItemController::storelogic($request);
|
||||||
|
|
||||||
|
if ($item) {
|
||||||
|
return (object) ['status' => 'OK'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (object) ['status' => 'FAILED'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*
|
||||||
|
* @param Item $item
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function show(Item $item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*
|
||||||
|
* @param Item $item
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function edit(Item $item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Item $item
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function update(Request $request, Item $item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*
|
||||||
|
* @param Item $item
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
public function destroy(Item $item)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ namespace App;
|
||||||
|
|
||||||
use Illuminate\Contracts\Routing\UrlGenerator;
|
use Illuminate\Contracts\Routing\UrlGenerator;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
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\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
@ -15,6 +16,8 @@ class Item extends Model
|
||||||
{
|
{
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
30
database/factories/ItemFactory.php
Normal file
30
database/factories/ItemFactory.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Item;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class ItemFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name of the factory's corresponding model.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $model = Item::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function definition()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'title' => $this->faker->unique()->text(),
|
||||||
|
'url' => $this->faker->unique()->url(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
2
public/js/app.js
vendored
2
public/js/app.js
vendored
File diff suppressed because one or more lines are too long
2
public/mix-manifest.json
generated
2
public/mix-manifest.json
generated
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"/css/app.css": "/css/app.css?id=9a25947db63214edd4e6f459200dfa62",
|
"/css/app.css": "/css/app.css?id=9a25947db63214edd4e6f459200dfa62",
|
||||||
"/js/app.js": "/js/app.js?id=894c631b0c521ca3e5df669b4220f77b"
|
"/js/app.js": "/js/app.js?id=50647209eddf7eb990cfe03fcc6652ed"
|
||||||
}
|
}
|
||||||
|
|
48
resources/assets/js/itemExport.js
vendored
Normal file
48
resources/assets/js/itemExport.js
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
const EXPORT_FILE_NAME = "HeimdallExport.json";
|
||||||
|
const EXPORT_API_URL = "api/item";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} fileName
|
||||||
|
* @param {string} data
|
||||||
|
*/
|
||||||
|
function triggerFileDownload(fileName, data) {
|
||||||
|
const a = document.createElement("a");
|
||||||
|
|
||||||
|
const file = new Blob([data], {
|
||||||
|
type: "text/plain",
|
||||||
|
});
|
||||||
|
|
||||||
|
a.href = URL.createObjectURL(file);
|
||||||
|
a.download = EXPORT_FILE_NAME;
|
||||||
|
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
const exportItems = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
fetch(EXPORT_API_URL)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
window.alert("An error occurred while exporting...");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
const exportedJson = JSON.stringify(data, null, 2);
|
||||||
|
|
||||||
|
triggerFileDownload(EXPORT_FILE_NAME, exportedJson);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const exportButton = document.querySelector("#item-export");
|
||||||
|
|
||||||
|
if (exportButton) {
|
||||||
|
exportButton.addEventListener("click", exportItems);
|
||||||
|
}
|
128
resources/assets/js/itemImport.js
vendored
Normal file
128
resources/assets/js/itemImport.js
vendored
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
const IMPORT_API_URL = "api/item";
|
||||||
|
const APP_LOAD_URL = "appload";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string|null} appId
|
||||||
|
* @returns {Promise<{}>|Promise<any>}
|
||||||
|
*/
|
||||||
|
const fetchAppDetails = (appId) => {
|
||||||
|
if (appId === null) {
|
||||||
|
return Promise.resolve({});
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetch(APP_LOAD_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ app: appId }),
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.catch(() => ({}));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
const getCSRFToken = () => {
|
||||||
|
const tokenSelector = 'input[name="_token"]';
|
||||||
|
return document.querySelector(tokenSelector).value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} data
|
||||||
|
* @param {string} csrfToken
|
||||||
|
*/
|
||||||
|
const postToApi = (data, csrfToken) =>
|
||||||
|
fetch(IMPORT_API_URL, {
|
||||||
|
method: "POST",
|
||||||
|
cache: "no-cache",
|
||||||
|
redirect: "follow",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-CSRF-TOKEN": csrfToken,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} item
|
||||||
|
* @param {object} appDetails
|
||||||
|
* @returns {undefined}
|
||||||
|
*/
|
||||||
|
const mergeItemWithAppDetails = (item, appDetails) => ({
|
||||||
|
pinned: 1,
|
||||||
|
tags: [0],
|
||||||
|
|
||||||
|
appid: item.appid,
|
||||||
|
title: item.title,
|
||||||
|
colour: item.colour,
|
||||||
|
url: item.url,
|
||||||
|
appdescription: item.appdescription
|
||||||
|
? item.appdescription
|
||||||
|
: appDetails.description,
|
||||||
|
|
||||||
|
website: appDetails.website,
|
||||||
|
|
||||||
|
icon: appDetails.iconview,
|
||||||
|
config: item.description ? JSON.parse(item.description) : null,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {array} items
|
||||||
|
*/
|
||||||
|
const importItems = (items) => {
|
||||||
|
items.forEach((item) => {
|
||||||
|
fetchAppDetails(item.appid)
|
||||||
|
.then((appDetails) => {
|
||||||
|
const itemWithAppDetails = mergeItemWithAppDetails(item, appDetails);
|
||||||
|
const csrfToken = getCSRFToken();
|
||||||
|
|
||||||
|
return postToApi(itemWithAppDetails, csrfToken);
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
console.log(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Blob} file
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
const readJSON = (file) =>
|
||||||
|
new Promise((resolve) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = (e) => {
|
||||||
|
const contents = e.target.result;
|
||||||
|
resolve(JSON.parse(contents));
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsText(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Event} event
|
||||||
|
*/
|
||||||
|
const openFileForImport = (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (!file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
readJSON(file).then(importItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileInput = document.querySelector("input[name='import']");
|
||||||
|
|
||||||
|
if (fileInput) {
|
||||||
|
fileInput.addEventListener("change", openFileForImport, false);
|
||||||
|
}
|
|
@ -86,6 +86,8 @@ return array (
|
||||||
'delete' => 'Delete',
|
'delete' => 'Delete',
|
||||||
'optional' => 'Optional',
|
'optional' => 'Optional',
|
||||||
'restore' => 'Restore',
|
'restore' => 'Restore',
|
||||||
|
'export' => 'Export',
|
||||||
|
'import' => 'Import',
|
||||||
'alert.success.item_created' => 'Item created successfully',
|
'alert.success.item_created' => 'Item created successfully',
|
||||||
'alert.success.item_updated' => 'Item updated successfully',
|
'alert.success.item_updated' => 'Item updated successfully',
|
||||||
'alert.success.item_deleted' => 'Item deleted successfully',
|
'alert.success.item_deleted' => 'Item deleted successfully',
|
||||||
|
|
32
resources/views/items/import.blade.php
Normal file
32
resources/views/items/import.blade.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
@extends('layouts.app')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<section class="module-container">
|
||||||
|
<header>
|
||||||
|
<div class="section-title">{{ __('import.title') }}</div>
|
||||||
|
<div class="module-actions">
|
||||||
|
<button type="submit"class="button"><i class="fa fa-save"></i><span>{{ __('import.save') }}</span></button>
|
||||||
|
<a href="{{ route('settings.index', []) }}" class="button"><i class="fa fa-ban"></i><span>{{ __('app.buttons.cancel') }}</span></a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="create">
|
||||||
|
{!! csrf_field() !!}
|
||||||
|
|
||||||
|
<div class="input">
|
||||||
|
<input class="form-control" name="import" type="file">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<div class="section-title"> </div>
|
||||||
|
<div class="module-actions">
|
||||||
|
<button type="submit"class="button"><i class="fa fa-save"></i><span>{{ __('import.save') }}</span></button>
|
||||||
|
<a href="{{ route('settings.index', []) }}" class="button"><i class="fa fa-ban"></i><span>{{ __('app.buttons.cancel') }}</span></a>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
@endsection
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="module-actions">
|
<div class="module-actions">
|
||||||
|
{{-- <a href="import" id="item-import" class="button"><i class="fa fa-upload"></i><span>{{ __('import') }}</span></a>--}}
|
||||||
|
<a href="#export" id="item-export" class="button"><i class="fa fa-download"></i><span>{{ __('export') }}</span></a>
|
||||||
<a href="{{ route('applist', []) }}" class="button"><i class="fa fa-cloud-download"></i><span>{{ __('app.buttons.downloadapps') }}</span></a>
|
<a href="{{ route('applist', []) }}" class="button"><i class="fa fa-cloud-download"></i><span>{{ __('app.buttons.downloadapps') }}</span></a>
|
||||||
<a href="{{ route('items.create', []) }}" title="" class="button"><i class="fa fa-plus"></i><span>{{ __('app.buttons.add') }}</span></a>
|
<a href="{{ route('items.create', []) }}" title="" class="button"><i class="fa fa-plus"></i><span>{{ __('app.buttons.add') }}</span></a>
|
||||||
<a href="{{ route('dash', []) }}" class="button"><i class="fa fa-ban"></i><span>{{ __('app.buttons.cancel') }}</span></a>
|
<a href="{{ route('dash', []) }}" class="button"><i class="fa fa-ban"></i><span>{{ __('app.buttons.cancel') }}</span></a>
|
||||||
|
|
|
@ -81,3 +81,6 @@ Route::group([
|
||||||
Auth::routes();
|
Auth::routes();
|
||||||
|
|
||||||
Route::get('/home', 'HomeController@index')->name('home');
|
Route::get('/home', 'HomeController@index')->name('home');
|
||||||
|
|
||||||
|
Route::resource('api/item', 'ItemRestController');
|
||||||
|
Route::get('import', 'ImportController')->name('items.import');
|
||||||
|
|
|
@ -7,12 +7,14 @@ use Tests\TestCase;
|
||||||
|
|
||||||
class ExampleTest extends TestCase
|
class ExampleTest extends TestCase
|
||||||
{
|
{
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic test example.
|
* A basic test example.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testBasicTest()
|
public function test_app_loads()
|
||||||
{
|
{
|
||||||
$response = $this->get('/');
|
$response = $this->get('/');
|
||||||
|
|
||||||
|
|
81
tests/Feature/ItemExportTest.php
Normal file
81
tests/Feature/ItemExportTest.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use App\Item;
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
|
use Illuminate\Support\Facades\Date;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
class ItemExportTest extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
use RefreshDatabase;
|
||||||
|
|
||||||
|
public function test_returns_empty_jsonarray_when_there_are_no_items_in_the_db()
|
||||||
|
{
|
||||||
|
$response = $this->get('api/item');
|
||||||
|
|
||||||
|
$response->assertJsonCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_returns_exactly_the_defined_fields()
|
||||||
|
{
|
||||||
|
$exampleItem = [
|
||||||
|
"appdescription" => "Description",
|
||||||
|
"appid" => "123",
|
||||||
|
"colour" => "#000",
|
||||||
|
"description" => "Description",
|
||||||
|
"title" => "Item Title",
|
||||||
|
"url" => "http://gorczany.com/nihil-rerum-distinctio-voluptate-assumenda-accusantium-exercitationem"
|
||||||
|
];
|
||||||
|
|
||||||
|
Item::factory()
|
||||||
|
->create($exampleItem);
|
||||||
|
|
||||||
|
$response = $this->get('api/item');
|
||||||
|
|
||||||
|
$response->assertExactJson([(object)$exampleItem]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_returns_all_items()
|
||||||
|
{
|
||||||
|
Item::factory()
|
||||||
|
->count(3)
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$response = $this->get('api/item');
|
||||||
|
|
||||||
|
$response->assertJsonCount(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_does_not_return_deleted_item()
|
||||||
|
{
|
||||||
|
Item::factory()
|
||||||
|
->create([
|
||||||
|
'deleted_at' => Date::create('1970')
|
||||||
|
]);
|
||||||
|
|
||||||
|
Item::factory()
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$response = $this->get('api/item');
|
||||||
|
|
||||||
|
$response->assertJsonCount(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_does_not_return_tags()
|
||||||
|
{
|
||||||
|
Item::factory()
|
||||||
|
->create([
|
||||||
|
'type' => 1
|
||||||
|
]);
|
||||||
|
|
||||||
|
Item::factory()
|
||||||
|
->create();
|
||||||
|
|
||||||
|
$response = $this->get('api/item');
|
||||||
|
|
||||||
|
$response->assertJsonCount(1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ class SettingsSeederTest extends TestCase
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testReturnsAJSONMapWithSameAmountOfItemsAsLanguageDirectoriesPresent()
|
public function test_returns_a_jsonmap_with_same_amount_of_items_as_language_directories_present()
|
||||||
{
|
{
|
||||||
$languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir');
|
$languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir');
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ class LangTest extends TestCase
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testAllLanguageKeysAreDefined()
|
public function test_all_language_keys_are_defined()
|
||||||
{
|
{
|
||||||
$this->markTestSkipped('2022-11-14 Lot of keys missing. Enable this test to see them all.');
|
$this->markTestSkipped('2022-11-14 Lot of keys missing. Enable this test to see them all.');
|
||||||
$languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir');
|
$languageDirectories = array_filter(glob(resource_path().'/lang/*'), 'is_dir');
|
||||||
|
|
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
|
@ -18,6 +18,7 @@ return array(
|
||||||
'App\\Http\\Controllers\\Controller' => $baseDir . '/app/Http/Controllers/Controller.php',
|
'App\\Http\\Controllers\\Controller' => $baseDir . '/app/Http/Controllers/Controller.php',
|
||||||
'App\\Http\\Controllers\\HomeController' => $baseDir . '/app/Http/Controllers/HomeController.php',
|
'App\\Http\\Controllers\\HomeController' => $baseDir . '/app/Http/Controllers/HomeController.php',
|
||||||
'App\\Http\\Controllers\\ItemController' => $baseDir . '/app/Http/Controllers/ItemController.php',
|
'App\\Http\\Controllers\\ItemController' => $baseDir . '/app/Http/Controllers/ItemController.php',
|
||||||
|
'App\\Http\\Controllers\\ItemRestController' => $baseDir . '/app/Http/Controllers/ItemRestController.php',
|
||||||
'App\\Http\\Controllers\\SearchController' => $baseDir . '/app/Http/Controllers/SearchController.php',
|
'App\\Http\\Controllers\\SearchController' => $baseDir . '/app/Http/Controllers/SearchController.php',
|
||||||
'App\\Http\\Controllers\\SettingsController' => $baseDir . '/app/Http/Controllers/SettingsController.php',
|
'App\\Http\\Controllers\\SettingsController' => $baseDir . '/app/Http/Controllers/SettingsController.php',
|
||||||
'App\\Http\\Controllers\\TagController' => $baseDir . '/app/Http/Controllers/TagController.php',
|
'App\\Http\\Controllers\\TagController' => $baseDir . '/app/Http/Controllers/TagController.php',
|
||||||
|
|
1
vendor/composer/autoload_static.php
vendored
1
vendor/composer/autoload_static.php
vendored
|
@ -616,6 +616,7 @@ class ComposerStaticInitb2555e5ff7197b9e020da74bbd3b7cfa
|
||||||
'App\\Http\\Controllers\\Controller' => __DIR__ . '/../..' . '/app/Http/Controllers/Controller.php',
|
'App\\Http\\Controllers\\Controller' => __DIR__ . '/../..' . '/app/Http/Controllers/Controller.php',
|
||||||
'App\\Http\\Controllers\\HomeController' => __DIR__ . '/../..' . '/app/Http/Controllers/HomeController.php',
|
'App\\Http\\Controllers\\HomeController' => __DIR__ . '/../..' . '/app/Http/Controllers/HomeController.php',
|
||||||
'App\\Http\\Controllers\\ItemController' => __DIR__ . '/../..' . '/app/Http/Controllers/ItemController.php',
|
'App\\Http\\Controllers\\ItemController' => __DIR__ . '/../..' . '/app/Http/Controllers/ItemController.php',
|
||||||
|
'App\\Http\\Controllers\\ItemRestController' => __DIR__ . '/../..' . '/app/Http/Controllers/ItemRestController.php',
|
||||||
'App\\Http\\Controllers\\SearchController' => __DIR__ . '/../..' . '/app/Http/Controllers/SearchController.php',
|
'App\\Http\\Controllers\\SearchController' => __DIR__ . '/../..' . '/app/Http/Controllers/SearchController.php',
|
||||||
'App\\Http\\Controllers\\SettingsController' => __DIR__ . '/../..' . '/app/Http/Controllers/SettingsController.php',
|
'App\\Http\\Controllers\\SettingsController' => __DIR__ . '/../..' . '/app/Http/Controllers/SettingsController.php',
|
||||||
'App\\Http\\Controllers\\TagController' => __DIR__ . '/../..' . '/app/Http/Controllers/TagController.php',
|
'App\\Http\\Controllers\\TagController' => __DIR__ . '/../..' . '/app/Http/Controllers/TagController.php',
|
||||||
|
|
28
webpack.mix.js
vendored
28
webpack.mix.js
vendored
|
@ -1,4 +1,4 @@
|
||||||
let mix = require('laravel-mix');
|
const mix = require("laravel-mix");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -11,12 +11,20 @@ let mix = require('laravel-mix');
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mix.babel([
|
mix
|
||||||
//'resources/assets/js/jquery-ui.min.js',
|
.babel(
|
||||||
'resources/assets/js/huebee.js',
|
[
|
||||||
'resources/assets/js/app.js',
|
// 'resources/assets/js/jquery-ui.min.js',
|
||||||
'resources/assets/js/keyBindings.js',
|
"resources/assets/js/huebee.js",
|
||||||
], 'public/js/app.js')
|
"resources/assets/js/app.js",
|
||||||
.sass('resources/assets/sass/app.scss', 'public/css').options({
|
"resources/assets/js/keyBindings.js",
|
||||||
processCssUrls: false
|
"resources/assets/js/itemExport.js",
|
||||||
}).version();
|
"resources/assets/js/itemImport.js",
|
||||||
|
],
|
||||||
|
"public/js/app.js"
|
||||||
|
)
|
||||||
|
.sass("resources/assets/sass/app.scss", "public/css")
|
||||||
|
.options({
|
||||||
|
processCssUrls: false,
|
||||||
|
})
|
||||||
|
.version();
|
||||||
|
|
Loading…
Reference in a new issue