Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Http/Controllers/CP/Navigation/NavigationPagesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public function create(Request $request, $nav)
{
$nav = Nav::find($nav);

$this->authorize('view', $nav->in($request->site));

$blueprint = $nav->blueprint();

$page = (new Page)
Expand All @@ -27,6 +29,8 @@ public function create(Request $request, $nav)
[$values, $meta] = $this->extractValuesAndMeta($page, $blueprint);

if ($entry = $page->entry()) {
$this->authorize('view', $entry);

[$originValues, $originMeta] = $this->extractValuesAndMeta($entry, $blueprint);
}

Expand All @@ -48,13 +52,17 @@ public function edit(Request $request, $nav, $page)
{
$nav = Nav::find($nav);

$this->authorize('view', $nav->in($request->site));

$blueprint = $nav->blueprint();

$page = $nav->in($request->site)->find($page);

[$values, $meta, $extraValues] = $this->extractValuesAndMeta($page, $blueprint);

if ($entry = $page->entry()) {
$this->authorize('view', $entry);

[$originValues, $originMeta] = $this->extractValuesAndMeta($entry, $blueprint);
}

Expand Down Expand Up @@ -160,6 +168,8 @@ public function update(Request $request, $nav)

$nav = Nav::find($nav);

$this->authorize('view', $nav);

$blueprint = $this->ensureFields($nav->blueprint(), $request);

$blueprint->fields()
Expand Down
105 changes: 105 additions & 0 deletions tests/Feature/Navigation/CreateNavigationPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,4 +159,109 @@ public function it_gets_the_values_for_an_entry_nav_item()
],
]);
}

#[Test]
public function it_denies_access_without_permission_to_view_the_nav()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [])->save();
$blueprint = Blueprint::makeFromFields(['foo' => ['type' => 'text']]);
BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($blueprint);

$this
->actingAs($user)
->request($nav)
->assertForbidden();
}

#[Test]
public function it_denies_access_to_an_entry_the_user_cannot_view()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp', 'view test nav']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [])->save();

$entryBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

$navBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($navBlueprint);
BlueprintRepository::shouldReceive('in')->with('collections/articles')->andReturn(collect(['articles' => $entryBlueprint]));

tap(Collection::make('articles'))->save();

EntryFactory::id('123')
->collection('articles')
->data([
'title' => 'entry title',
'foo' => 'entry foo',
'bar' => 'entry bar',
])
->create();

$this
->actingAs($user)
->request($nav, ['entry' => '123'])
->assertForbidden();
}

#[Test]
public function it_allows_access_to_an_entry_the_user_can_view()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp', 'view test nav', 'view articles entries']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [])->save();

$entryBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

$navBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($navBlueprint);
BlueprintRepository::shouldReceive('in')->with('collections/articles')->andReturn(collect(['articles' => $entryBlueprint]));

tap(Collection::make('articles'))->save();

EntryFactory::id('123')
->collection('articles')
->data([
'title' => 'entry title',
'foo' => 'entry foo',
'bar' => 'entry bar',
])
->create();

$this
->actingAs($user)
->request($nav, ['entry' => '123'])
->assertOk()
->assertJson([
'originValues' => [
'title' => 'entry title (preprocessed)',
'foo' => 'entry foo (preprocessed)',
'bar' => 'entry bar (preprocessed)',
],
]);
}
}
126 changes: 126 additions & 0 deletions tests/Feature/Navigation/EditNavigationPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,130 @@ public function it_gets_the_values_for_an_entry_nav_item()
],
]);
}

#[Test]
public function it_denies_access_without_permission_to_view_the_nav()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [
[
'id' => 'id7',
'title' => 'The title',
'url' => 'http://example.com',
'data' => ['foo' => 'bar'],
],
])->save();
$blueprint = Blueprint::makeFromFields(['foo' => ['type' => 'text']]);
BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($blueprint);

$this
->actingAs($user)
->request($nav, 'id7')
->assertForbidden();
}

#[Test]
public function it_denies_access_to_an_entry_the_user_cannot_view()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp', 'view test nav']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [
[
'id' => 'id7',
'entry' => '123',
'title' => 'The page title',
'data' => ['foo' => 'page foo'],
],
])->save();

$entryBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

$navBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($navBlueprint);
BlueprintRepository::shouldReceive('in')->with('collections/articles')->andReturn(collect(['articles' => $entryBlueprint]));

tap(Collection::make('articles'))->save();

EntryFactory::id('123')
->collection('articles')
->data([
'title' => 'entry title',
'foo' => 'entry foo',
'bar' => 'entry bar',
])
->create();

$this
->actingAs($user)
->request($nav, 'id7')
->assertForbidden();
}

#[Test]
public function it_allows_access_to_an_entry_the_user_can_view()
{
$this->mockTextFieldtype();
$this->setTestRoles(['test' => ['access cp', 'view test nav', 'view articles entries']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [
[
'id' => 'id7',
'entry' => '123',
'title' => 'The page title',
'data' => ['foo' => 'page foo'],
],
])->save();

$entryBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

$navBlueprint = Blueprint::makeFromFields([
'foo' => ['type' => 'text'],
'bar' => ['type' => 'text'],
]);

BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.test')->andReturn($navBlueprint);
BlueprintRepository::shouldReceive('in')->with('collections/articles')->andReturn(collect(['articles' => $entryBlueprint]));

tap(Collection::make('articles'))->save();

EntryFactory::id('123')
->collection('articles')
->data([
'title' => 'entry title',
'foo' => 'entry foo',
'bar' => 'entry bar',
])
->create();

$this
->actingAs($user)
->request($nav, 'id7')
->assertOk()
->assertJson([
'originValues' => [
'title' => 'entry title (preprocessed)',
'foo' => 'entry foo (preprocessed)',
'bar' => 'entry bar (preprocessed)',
],
]);
}
}
68 changes: 68 additions & 0 deletions tests/Feature/Navigation/UpdateNavigationPageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Tests\Feature\Navigation;

use Facades\Statamic\Fields\BlueprintRepository;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Facades\Blueprint;
use Statamic\Facades\Nav;
use Statamic\Facades\User;
use Tests\FakesRoles;
use Tests\PreventSavingStacheItemsToDisk;
use Tests\TestCase;

class UpdateNavigationPageTest extends TestCase
{
use FakesRoles;
use PreventSavingStacheItemsToDisk;

private function request($nav, $params = [], $site = 'en')
{
$url = cp_route('navigation.pages.update', $nav->handle());

return $this->postJson($url, array_merge(['site' => $site], $params));
}

private function setNavBlueprint($nav)
{
$blueprint = Blueprint::makeFromFields([]);
BlueprintRepository::partialMock();
BlueprintRepository::shouldReceive('find')->with('navigation.'.$nav->handle())->andReturn($blueprint);
}

#[Test]
public function it_denies_access_without_permission_to_view_the_nav()
{
$this->setTestRoles(['test' => ['access cp']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [])->save();
$this->setNavBlueprint($nav);

$this
->actingAs($user)
->request($nav, [
'type' => 'url',
'values' => ['title' => 'The title', 'url' => 'http://example.com'],
])
->assertForbidden();
}

#[Test]
public function it_allows_access_with_permission_to_view_the_nav()
{
$this->setTestRoles(['test' => ['access cp', 'view test nav']]);
$user = tap(User::make()->assignRole('test'))->save();
$nav = tap(Nav::make('test'))->save();
$nav->makeTree('en', [])->save();
$this->setNavBlueprint($nav);

$this
->actingAs($user)
->request($nav, [
'type' => 'url',
'values' => ['title' => 'The title', 'url' => 'http://example.com'],
])
->assertOk();
}
}
Loading