mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-02-08 11:19:36 +03:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5ae524c25a | ||
|
|
0d7287fc8b | ||
|
|
219da9da9b | ||
|
|
38ce54ea0c | ||
|
|
97ec560282 | ||
|
|
06b5a83d8f | ||
|
|
45dc28ba2a | ||
|
|
6e0a7344fa | ||
|
|
7fa934e7f2 | ||
|
|
a90446796a | ||
|
|
4209f27f1a | ||
|
|
89ec9a5081 | ||
|
|
e77c96f6b7 | ||
|
|
9b8a10dd3a | ||
|
|
42f4c9afae | ||
|
|
8d6071cb84 |
1
.github/translators.txt
vendored
1
.github/translators.txt
vendored
@@ -267,3 +267,4 @@ Filip Antala (AntalaFilip) :: Slovak
|
||||
mcgong (GongMingCai) :: Chinese Simplified; Chinese Traditional
|
||||
Nanang Setia Budi (sefidananang) :: Indonesian
|
||||
Андрей Павлов (andrei.pavlov) :: Russian
|
||||
Alex Navarro (alex.n.navarro) :: Portuguese, Brazilian
|
||||
|
||||
@@ -29,6 +29,9 @@ class ActivityType
|
||||
const COMMENTED_ON = 'commented_on';
|
||||
const PERMISSIONS_UPDATE = 'permissions_update';
|
||||
|
||||
const REVISION_RESTORE = 'revision_restore';
|
||||
const REVISION_DELETE = 'revision_delete';
|
||||
|
||||
const SETTINGS_UPDATE = 'settings_update';
|
||||
const MAINTENANCE_ACTION_RUN = 'maintenance_action_run';
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace BookStack\Entities\Models;
|
||||
|
||||
use BookStack\Auth\User;
|
||||
use BookStack\Interfaces\Loggable;
|
||||
use BookStack\Model;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
@@ -27,7 +28,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
* @property Page $page
|
||||
* @property-read ?User $createdBy
|
||||
*/
|
||||
class PageRevision extends Model
|
||||
class PageRevision extends Model implements Loggable
|
||||
{
|
||||
protected $fillable = ['name', 'text', 'summary'];
|
||||
protected $hidden = ['html', 'markdown', 'restricted', 'text'];
|
||||
@@ -83,4 +84,9 @@ class PageRevision extends Model
|
||||
{
|
||||
return $type === 'revision';
|
||||
}
|
||||
|
||||
public function logDescriptor(): string
|
||||
{
|
||||
return "Revision #{$this->revision_number} (ID: {$this->id}) for page ID {$this->page_id}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ class PageRepo
|
||||
$this->savePageRevision($page, $summary);
|
||||
|
||||
Activity::add(ActivityType::PAGE_RESTORE, $page);
|
||||
Activity::add(ActivityType::REVISION_RESTORE, $revision);
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace BookStack\Facades;
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @see \BookStack\Actions\ActivityLogger
|
||||
* @mixin \BookStack\Actions\ActivityLogger
|
||||
*/
|
||||
class Activity extends Facade
|
||||
{
|
||||
|
||||
@@ -36,26 +36,26 @@ class UserApiController extends ApiController
|
||||
{
|
||||
return [
|
||||
'create' => [
|
||||
'name' => ['required', 'min:2'],
|
||||
'name' => ['required', 'min:2', 'max:100'],
|
||||
'email' => [
|
||||
'required', 'min:2', 'email', new Unique('users', 'email'),
|
||||
],
|
||||
'external_auth_id' => ['string'],
|
||||
'language' => ['string'],
|
||||
'language' => ['string', 'max:15', 'alpha_dash'],
|
||||
'password' => [Password::default()],
|
||||
'roles' => ['array'],
|
||||
'roles.*' => ['integer'],
|
||||
'send_invite' => ['boolean'],
|
||||
],
|
||||
'update' => [
|
||||
'name' => ['min:2'],
|
||||
'name' => ['min:2', 'max:100'],
|
||||
'email' => [
|
||||
'min:2',
|
||||
'email',
|
||||
(new Unique('users', 'email'))->ignore($userId ?? null),
|
||||
],
|
||||
'external_auth_id' => ['string'],
|
||||
'language' => ['string'],
|
||||
'language' => ['string', 'max:15', 'alpha_dash'],
|
||||
'password' => [Password::default()],
|
||||
'roles' => ['array'],
|
||||
'roles.*' => ['integer'],
|
||||
|
||||
@@ -30,9 +30,9 @@ class RegisterController extends Controller
|
||||
|
||||
use RegistersUsers;
|
||||
|
||||
protected $socialAuthService;
|
||||
protected $registrationService;
|
||||
protected $loginService;
|
||||
protected SocialAuthService $socialAuthService;
|
||||
protected RegistrationService $registrationService;
|
||||
protected LoginService $loginService;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login / registration.
|
||||
@@ -69,7 +69,7 @@ class RegisterController extends Controller
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
'name' => ['required', 'min:2', 'max:255'],
|
||||
'name' => ['required', 'min:2', 'max:100'],
|
||||
'email' => ['required', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', Password::default()],
|
||||
]);
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
namespace BookStack\Http\Controllers;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Facades\Activity;
|
||||
use Ssddanbrown\HtmlDiff\Diff;
|
||||
|
||||
class PageRevisionController extends Controller
|
||||
@@ -132,6 +134,7 @@ class PageRevisionController extends Controller
|
||||
}
|
||||
|
||||
$revision->delete();
|
||||
Activity::add(ActivityType::REVISION_DELETE, $revision);
|
||||
$this->showSuccessNotification(trans('entities.revision_delete_success'));
|
||||
|
||||
return redirect($page->getUrl('/revisions'));
|
||||
|
||||
@@ -18,8 +18,8 @@ use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
protected $userRepo;
|
||||
protected $imageRepo;
|
||||
protected UserRepo $userRepo;
|
||||
protected ImageRepo $imageRepo;
|
||||
|
||||
/**
|
||||
* UserController constructor.
|
||||
@@ -81,9 +81,9 @@ class UserController extends Controller
|
||||
$passwordRequired = ($authMethod === 'standard' && !$sendInvite);
|
||||
|
||||
$validationRules = [
|
||||
'name' => ['required'],
|
||||
'name' => ['required', 'max:100'],
|
||||
'email' => ['required', 'email', 'unique:users,email'],
|
||||
'language' => ['string'],
|
||||
'language' => ['string', 'max:15', 'alpha_dash'],
|
||||
'roles' => ['array'],
|
||||
'roles.*' => ['integer'],
|
||||
'password' => $passwordRequired ? ['required', Password::default()] : null,
|
||||
@@ -139,11 +139,11 @@ class UserController extends Controller
|
||||
$this->checkPermissionOrCurrentUser('users-manage', $id);
|
||||
|
||||
$validated = $this->validate($request, [
|
||||
'name' => ['min:2'],
|
||||
'name' => ['min:2', 'max:100'],
|
||||
'email' => ['min:2', 'email', 'unique:users,email,' . $id],
|
||||
'password' => ['required_with:password_confirm', Password::default()],
|
||||
'password-confirm' => ['same:password', 'required_with:password'],
|
||||
'language' => ['string'],
|
||||
'language' => ['string', 'max:15', 'alpha_dash'],
|
||||
'roles' => ['array'],
|
||||
'roles.*' => ['integer'],
|
||||
'external_auth_id' => ['string'],
|
||||
|
||||
@@ -171,7 +171,7 @@ return [
|
||||
'chapters_permissions_active' => 'Hoofdstuk Machtigingen Actief',
|
||||
'chapters_permissions_success' => 'Hoofdstuk Machtigingen Bijgewerkt',
|
||||
'chapters_search_this' => 'Doorzoek dit hoofdstuk',
|
||||
'chapter_sort_book' => 'Sort Book',
|
||||
'chapter_sort_book' => 'Sorteer Boek',
|
||||
|
||||
// Pages
|
||||
'page' => 'Pagina',
|
||||
|
||||
@@ -77,7 +77,7 @@ return [
|
||||
'status_active' => 'Aktywny',
|
||||
'status_inactive' => 'Nieaktywny',
|
||||
'never' => 'Nigdy',
|
||||
'none' => 'Żaden',
|
||||
'none' => 'Brak',
|
||||
|
||||
// Header
|
||||
'header_menu_expand' => 'Rozwiń menu nagłówka',
|
||||
|
||||
@@ -157,7 +157,7 @@ return [
|
||||
'about' => 'O edytorze',
|
||||
'about_title' => 'O edytorze WYSIWYG',
|
||||
'editor_license' => 'Licencja edytora i prawa autorskie',
|
||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
||||
'editor_tiny_license' => 'Ten edytor jest zbudowany przy użyciu :tinyLink, który jest udostępniany na licencji MIT.',
|
||||
'editor_tiny_license_link' => 'Szczegóły dotyczące praw autorskich i licencji TinyMCE można znaleźć tutaj.',
|
||||
'save_continue' => 'Zapisz stronę i kontynuuj',
|
||||
'callouts_cycle' => '(Naciskaj dalej, aby przełączyć przez typy)',
|
||||
|
||||
@@ -24,7 +24,7 @@ return [
|
||||
'meta_updated_name' => 'Zaktualizowano :timeLength przez :user',
|
||||
'meta_owned_name' => 'Właściciel: :user',
|
||||
'entity_select' => 'Wybór obiektu',
|
||||
'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item',
|
||||
'entity_select_lack_permission' => 'Nie masz wymaganych uprawnień do wybrania tej pozycji',
|
||||
'images' => 'Obrazki',
|
||||
'my_recent_drafts' => 'Moje ostatnie wersje robocze',
|
||||
'my_recently_viewed' => 'Moje ostatnio wyświetlane',
|
||||
@@ -88,7 +88,7 @@ return [
|
||||
'shelves_save' => 'Zapisz półkę',
|
||||
'shelves_books' => 'Książki na tej półce',
|
||||
'shelves_add_books' => 'Dodaj książkę do tej półki',
|
||||
'shelves_drag_books' => 'Drag books below to add them to this shelf',
|
||||
'shelves_drag_books' => 'Przeciągnij książki poniżej, aby dodać je do tej półki',
|
||||
'shelves_empty_contents' => 'Ta półka nie ma przypisanych żadnych książek',
|
||||
'shelves_edit_and_assign' => 'Edytuj półkę aby przypisać książki',
|
||||
'shelves_edit_named' => 'Edytuj półkę :name',
|
||||
@@ -171,7 +171,7 @@ return [
|
||||
'chapters_permissions_active' => 'Uprawnienia rozdziału są aktywne',
|
||||
'chapters_permissions_success' => 'Zaktualizowano uprawnienia rozdziału',
|
||||
'chapters_search_this' => 'Przeszukaj ten rozdział',
|
||||
'chapter_sort_book' => 'Sort Book',
|
||||
'chapter_sort_book' => 'Sortuj książkę',
|
||||
|
||||
// Pages
|
||||
'page' => 'Strona',
|
||||
|
||||
@@ -28,8 +28,8 @@ return [
|
||||
// Books
|
||||
'book_create' => 'criou o livro',
|
||||
'book_create_notification' => 'Livro criado com sucesso',
|
||||
'book_create_from_chapter' => 'converted chapter to book',
|
||||
'book_create_from_chapter_notification' => 'Chapter successfully converted to a book',
|
||||
'book_create_from_chapter' => 'capítulo convertido em livro',
|
||||
'book_create_from_chapter_notification' => 'Capítulo convertido com sucesso em um livro',
|
||||
'book_update' => 'atualizou o livro',
|
||||
'book_update_notification' => 'Livro atualizado com sucesso',
|
||||
'book_delete' => 'excluiu o livro',
|
||||
@@ -40,8 +40,8 @@ return [
|
||||
// Bookshelves
|
||||
'bookshelf_create' => 'prateleira criada',
|
||||
'bookshelf_create_notification' => 'Prateleira criada com sucesso',
|
||||
'bookshelf_create_from_book' => 'converted book to bookshelf',
|
||||
'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf',
|
||||
'bookshelf_create_from_book' => 'livro convertido em estante',
|
||||
'bookshelf_create_from_book_notification' => 'Capítulo convertido com sucesso em um livro',
|
||||
'bookshelf_update' => 'atualizou a prateleira',
|
||||
'bookshelf_update_notification' => 'Prateleira atualizada com sucesso',
|
||||
'bookshelf_delete' => 'excluiu a prateleira',
|
||||
|
||||
@@ -157,7 +157,7 @@ return [
|
||||
'about' => 'О редакторе',
|
||||
'about_title' => 'О редакторе WYSIWYG',
|
||||
'editor_license' => 'Лицензия редактора и авторские права',
|
||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
||||
'editor_tiny_license' => 'Этот редактор собран с помощью :tinyLink, который предоставляется под MIT лицензией.',
|
||||
'editor_tiny_license_link' => 'Авторские права и подробности лицензии TinyMCE вы можете найти здесь.',
|
||||
'save_continue' => 'Сохранить страницу и продолжить',
|
||||
'callouts_cycle' => '(Держите нажатым для переключения типов)',
|
||||
|
||||
@@ -24,7 +24,7 @@ return [
|
||||
'meta_updated_name' => ':user обновил :timeLength',
|
||||
'meta_owned_name' => 'Владелец :user',
|
||||
'entity_select' => 'Выбор объекта',
|
||||
'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item',
|
||||
'entity_select_lack_permission' => 'У вас нет разрешения на выбор этого элемента',
|
||||
'images' => 'Изображения',
|
||||
'my_recent_drafts' => 'Мои последние черновики',
|
||||
'my_recently_viewed' => 'Мои недавние просмотры',
|
||||
@@ -88,7 +88,7 @@ return [
|
||||
'shelves_save' => 'Сохранить полку',
|
||||
'shelves_books' => 'Книги из этой полки',
|
||||
'shelves_add_books' => 'Добавить книгу в эту полку',
|
||||
'shelves_drag_books' => 'Drag books below to add them to this shelf',
|
||||
'shelves_drag_books' => 'Перетащите книги ниже, чтобы добавить их на эту полку',
|
||||
'shelves_empty_contents' => 'На этой полке нет книг',
|
||||
'shelves_edit_and_assign' => 'Изменить полку для привязки книг',
|
||||
'shelves_edit_named' => 'Редактировать полку :name',
|
||||
@@ -171,7 +171,7 @@ return [
|
||||
'chapters_permissions_active' => 'Действующие разрешения главы',
|
||||
'chapters_permissions_success' => 'Разрешения главы обновлены',
|
||||
'chapters_search_this' => 'Искать в этой главе',
|
||||
'chapter_sort_book' => 'Sort Book',
|
||||
'chapter_sort_book' => 'Сортировать книгу',
|
||||
|
||||
// Pages
|
||||
'page' => 'Страница',
|
||||
|
||||
@@ -157,7 +157,7 @@ return [
|
||||
'about' => '关于编辑器',
|
||||
'about_title' => '关于所见即所得(WYSIWYG)编辑器',
|
||||
'editor_license' => '编辑器许可证与版权信息',
|
||||
'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.',
|
||||
'editor_tiny_license' => '此编辑器是用 :tinyLink 构建的,基于 MIT 许可证。',
|
||||
'editor_tiny_license_link' => 'TinyMCE 的版权和许可证详细信息可以在这里找到。',
|
||||
'save_continue' => '保存页面并继续',
|
||||
'callouts_cycle' => '(继续按下以切换类型)',
|
||||
|
||||
@@ -88,7 +88,7 @@ return [
|
||||
'shelves_save' => '保存书架',
|
||||
'shelves_books' => '书籍已在此书架里',
|
||||
'shelves_add_books' => '将书籍加入此书架',
|
||||
'shelves_drag_books' => 'Drag books below to add them to this shelf',
|
||||
'shelves_drag_books' => '拖动下面的图书将其添加到此书架',
|
||||
'shelves_empty_contents' => '这个书架没有分配图书',
|
||||
'shelves_edit_and_assign' => '编辑书架以分配图书',
|
||||
'shelves_edit_named' => '编辑书架 :name',
|
||||
@@ -171,7 +171,7 @@ return [
|
||||
'chapters_permissions_active' => '有效的章节权限',
|
||||
'chapters_permissions_success' => '章节权限已更新',
|
||||
'chapters_search_this' => '从本章节搜索',
|
||||
'chapter_sort_book' => 'Sort Book',
|
||||
'chapter_sort_book' => '排序图书',
|
||||
|
||||
// Pages
|
||||
'page' => '页面',
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
@include('exports.parts.custom-head')
|
||||
</head>
|
||||
<body class="export export-format-{{ $format }} export-engine-{{ $engine ?? 'none' }}">
|
||||
@include('layouts.parts.export-body-start')
|
||||
<div class="page-content">
|
||||
@yield('content')
|
||||
</div>
|
||||
@include('layouts.parts.export-body-end')
|
||||
</body>
|
||||
</html>
|
||||
2
resources/views/layouts/parts/export-body-end.blade.php
Normal file
2
resources/views/layouts/parts/export-body-end.blade.php
Normal file
@@ -0,0 +1,2 @@
|
||||
{{-- This is a placeholder template file provided as a --}}
|
||||
{{-- convenience to users of the visual theme system. --}}
|
||||
@@ -0,0 +1,2 @@
|
||||
{{-- This is a placeholder template file provided as a --}}
|
||||
{{-- convenience to users of the visual theme system. --}}
|
||||
@@ -1,5 +1,5 @@
|
||||
@push('head')
|
||||
<script src="{{ url('/libs/tinymce/tinymce.min.js?ver=5.10.2') }}" nonce="{{ $cspNonce }}"></script>
|
||||
<script src="{{ versioned_asset('libs/tinymce/tinymce.min.js') }}" nonce="{{ $cspNonce }}"></script>
|
||||
@endpush
|
||||
|
||||
<div component="wysiwyg-editor"
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
|
||||
<div component="dropdown" class="list-sort-type dropdown-container">
|
||||
<label for="">{{ trans('settings.audit_event_filter') }}</label>
|
||||
<button refs="dropdown@toggle" aria-haspopup="true" aria-expanded="false" aria-label="{{ trans('common.sort_options') }}" class="input-base text-left">{{ $listDetails['event'] ?: trans('settings.audit_event_filter_no_filter') }}</button>
|
||||
<button refs="dropdown@toggle"
|
||||
type="button"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="false"
|
||||
aria-label="{{ trans('common.sort_options') }}"
|
||||
class="input-base text-left">{{ $listDetails['event'] ?: trans('settings.audit_event_filter_no_filter') }}</button>
|
||||
<ul refs="dropdown@menu" class="dropdown-menu">
|
||||
<li @if($listDetails['event'] === '') class="active" @endif><a href="{{ sortUrl('/settings/audit', $listDetails, ['event' => '']) }}" class="text-item">{{ trans('settings.audit_event_filter_no_filter') }}</a></li>
|
||||
@foreach($activityTypes as $type)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\Entity;
|
||||
|
||||
use BookStack\Actions\ActivityType;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Repos\PageRepo;
|
||||
use Tests\TestCase;
|
||||
@@ -117,6 +118,9 @@ class PageRevisionTest extends TestCase
|
||||
'type' => 'version',
|
||||
'summary' => "Restored from #{$revToRestore->id}; My first update",
|
||||
]);
|
||||
|
||||
$detail = "Revision #{$revToRestore->revision_number} (ID: {$revToRestore->id}) for page ID {$revToRestore->page_id}";
|
||||
$this->assertActivityExists(ActivityType::REVISION_RESTORE, null, $detail);
|
||||
}
|
||||
|
||||
public function test_page_revision_count_increments_on_update()
|
||||
@@ -164,6 +168,9 @@ class PageRevisionTest extends TestCase
|
||||
|
||||
$this->assertTrue($beforeRevisionCount === ($afterRevisionCount + 1));
|
||||
|
||||
$detail = "Revision #{$revision->revision_number} (ID: {$revision->id}) for page ID {$revision->page_id}";
|
||||
$this->assertActivityExists(ActivityType::REVISION_DELETE, null, $detail);
|
||||
|
||||
// Try to delete the latest revision
|
||||
$beforeRevisionCount = $page->revisions->count();
|
||||
$resp = $this->asEditor()->delete($page->currentRevision->getUrl('/delete/'));
|
||||
|
||||
@@ -272,7 +272,7 @@ class ThemeTest extends TestCase
|
||||
$this->assertStringContainsString('Command ran!', $output);
|
||||
}
|
||||
|
||||
public function test_body_start_and_end_template_files_can_be_used()
|
||||
public function test_base_body_start_and_end_template_files_can_be_used()
|
||||
{
|
||||
$bodyStartStr = 'barry-fought-against-the-panther';
|
||||
$bodyEndStr = 'barry-lost-his-fight-with-grace';
|
||||
@@ -289,6 +289,25 @@ class ThemeTest extends TestCase
|
||||
});
|
||||
}
|
||||
|
||||
public function test_export_body_start_and_end_template_files_can_be_used()
|
||||
{
|
||||
$bodyStartStr = 'barry-fought-against-the-panther';
|
||||
$bodyEndStr = 'barry-lost-his-fight-with-grace';
|
||||
/** @var Page $page */
|
||||
$page = Page::query()->first();
|
||||
|
||||
$this->usingThemeFolder(function (string $folder) use ($bodyStartStr, $bodyEndStr, $page) {
|
||||
$viewDir = theme_path('layouts/parts');
|
||||
mkdir($viewDir, 0777, true);
|
||||
file_put_contents($viewDir . '/export-body-start.blade.php', $bodyStartStr);
|
||||
file_put_contents($viewDir . '/export-body-end.blade.php', $bodyEndStr);
|
||||
|
||||
$resp = $this->asEditor()->get($page->getUrl('/export/html'));
|
||||
$resp->assertSee($bodyStartStr);
|
||||
$resp->assertSee($bodyEndStr);
|
||||
});
|
||||
}
|
||||
|
||||
protected function usingThemeFolder(callable $callback)
|
||||
{
|
||||
// Create a folder and configure a theme
|
||||
|
||||
@@ -234,4 +234,28 @@ class UserManagementTest extends TestCase
|
||||
|
||||
$this->assertDatabaseMissing('activities', ['type' => 'USER_CREATE']);
|
||||
}
|
||||
|
||||
public function test_user_create_update_fails_if_locale_is_invalid()
|
||||
{
|
||||
$user = $this->getEditor();
|
||||
|
||||
// Too long
|
||||
$resp = $this->asAdmin()->put($user->getEditUrl(), ['language' => 'this_is_too_long']);
|
||||
$resp->assertSessionHasErrors(['language' => 'The language may not be greater than 15 characters.']);
|
||||
session()->flush();
|
||||
|
||||
// Invalid characters
|
||||
$resp = $this->put($user->getEditUrl(), ['language' => 'en<GB']);
|
||||
$resp->assertSessionHasErrors(['language' => 'The language may only contain letters, numbers, dashes and underscores.']);
|
||||
session()->flush();
|
||||
|
||||
// Both on create
|
||||
$resp = $this->post('/settings/users/create', [
|
||||
'language' => 'en<GB_and_this_is_longer',
|
||||
'name' => 'My name',
|
||||
'email' => 'jimmy@example.com',
|
||||
]);
|
||||
$resp->assertSessionHasErrors(['language' => 'The language may not be greater than 15 characters.']);
|
||||
$resp->assertSessionHasErrors(['language' => 'The language may only contain letters, numbers, dashes and underscores.']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user