1
0
mirror of https://github.com/flarum/core.git synced 2025-07-30 21:20:24 +02:00

Slug Driver Support (#2456)

- Support slug drivers for core's sluggable models, easily extends to other models
- Add automated testing for affected single-model API routes
- Fix nickname selection UI
- Serialize slugs as `slug` attribute
- Make min search length a constant
This commit is contained in:
Matt Kilgore
2020-12-07 13:33:42 -05:00
committed by GitHub
parent 0df35e8796
commit 0fcbca8f4a
27 changed files with 671 additions and 58 deletions

View File

@@ -66,6 +66,24 @@ class ShowTest extends TestCase
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function author_can_see_discussion_via_slug()
{
// Note that here, the slug doesn't actually have to match the real slug
// since the default slugging strategy only takes the numerical part into account
$response = $this->send(
$this->request('GET', '/api/discussions/1-fdsafdsajfsakf', [
'authenticatedAs' => 2,
])->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/

View File

@@ -25,9 +25,10 @@ class CreateTest extends TestCase
$this->prepareDatabase([
'users' => [
$this->adminUser(),
$this->normalUser(),
],
'groups' => [
$this->adminGroup(),
$this->adminGroup()
],
'group_user' => [
['user_id' => 1, 'group_id' => 1],

View File

@@ -0,0 +1,197 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Tests\integration\api\users;
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
use Flarum\Tests\integration\TestCase;
class ShowTest extends TestCase
{
use RetrievesAuthorizedUsers;
protected function setUp(): void
{
parent::setUp();
$this->prepareDatabase([
'users' => [
$this->adminUser(),
$this->normalUser(),
],
'groups' => [
$this->adminGroup()
],
'group_user' => [
['user_id' => 1, 'group_id' => 1],
],
'settings' => [
['key' => 'mail_driver', 'value' => 'log'],
],
]);
}
/**
* @test
*/
public function admin_can_see_user()
{
$response = $this->send(
$this->request('GET', '/api/users/2', [
'authenticatedAs' => 1,
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function admin_can_see_user_via_slug()
{
$response = $this->send(
$this->request('GET', '/api/users/normal', [
'authenticatedAs' => 1,
])->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function guest_cannot_see_user()
{
$response = $this->send(
$this->request('GET', '/api/users/2')
);
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @test
*/
public function guest_cannot_see_user_by_slug()
{
$response = $this->send(
$this->request('GET', '/api/users/2')->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @test
*/
public function user_can_see_themselves()
{
$response = $this->send(
$this->request('GET', '/api/users/2', [
'authenticatedAs' => 2,
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function user_can_see_themselves_via_slug()
{
$response = $this->send(
$this->request('GET', '/api/users/normal', [
'authenticatedAs' => 2,
])->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function user_cant_see_others_by_default()
{
$response = $this->send(
$this->request('GET', '/api/users/1', [
'authenticatedAs' => 2,
])
);
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @test
*/
public function user_cant_see_others_by_default_via_slug()
{
$response = $this->send(
$this->request('GET', '/api/users/admin', [
'authenticatedAs' => 2,
])->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(404, $response->getStatusCode());
}
/**
* @test
*/
public function user_can_see_others_if_allowed()
{
$this->prepareDatabase([
'group_permission' => [
['permission' => 'viewDiscussions', 'group_id' => 3],
]
]);
$response = $this->send(
$this->request('GET', '/api/users/1', [
'authenticatedAs' => 2,
])
);
$this->assertEquals(200, $response->getStatusCode());
}
/**
* @test
*/
public function user_can_see_others_if_allowed_via_slug()
{
$this->prepareDatabase([
'group_permission' => [
['permission' => 'viewDiscussions', 'group_id' => 3],
]
]);
$response = $this->send(
$this->request('GET', '/api/users/admin', [
'authenticatedAs' => 2,
])->withQueryParams([
'bySlug' => true
])
);
$this->assertEquals(200, $response->getStatusCode());
}
}

View File

@@ -0,0 +1,82 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Tests\integration\extenders;
use Flarum\Database\AbstractModel;
use Flarum\Extend;
use Flarum\Http\SlugDriverInterface;
use Flarum\Http\SlugManager;
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
use Flarum\Tests\integration\TestCase;
use Flarum\User\User;
class ModelUrlTest extends TestCase
{
use RetrievesAuthorizedUsers;
protected function prepDb()
{
$userClass = User::class;
$this->prepareDatabase([
'users' => [
$this->adminUser(),
$this->normalUser(),
],
'settings' => [
['key' => "slug_driver_$userClass", 'value' => 'testDriver'],
]
]);
}
/**
* @test
*/
public function uses_default_driver_by_default()
{
$this->prepDb();
$slugManager = $this->app()->getContainer()->make(SlugManager::class);
$testUser = User::find(1);
$this->assertEquals('admin', $slugManager->forResource(User::class)->toSlug($testUser));
$this->assertEquals('1', $slugManager->forResource(User::class)->fromSlug('admin', $testUser)->id);
}
/**
* @test
*/
public function custom_slug_driver_has_effect_if_added()
{
$this->extend((new Extend\ModelUrl(User::class))->addSlugDriver('testDriver', TestSlugDriver::class));
$this->prepDb();
$slugManager = $this->app()->getContainer()->make(SlugManager::class);
$testUser = User::find(1);
$this->assertEquals('test-slug', $slugManager->forResource(User::class)->toSlug($testUser));
$this->assertEquals('1', $slugManager->forResource(User::class)->fromSlug('random-gibberish', $testUser)->id);
}
}
class TestSlugDriver implements SlugDriverInterface
{
public function toSlug(AbstractModel $instance): string
{
return 'test-slug';
}
public function fromSlug(string $slug, User $actor): AbstractModel
{
return User::find(1);
}
}