Skip to content

Commit

Permalink
GH #2870: Launch the LTI tool if it's the only one
Browse files Browse the repository at this point in the history
  • Loading branch information
chrieinv committed Jan 10, 2025
1 parent 66f63d8 commit 9997805
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 6 deletions.
30 changes: 30 additions & 0 deletions sourcecode/hub/app/Http/Middleware/LaunchCreateIfSingleTool.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware;

use App\Models\LtiTool;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* Launch the tool if it's the only tool, and it does not have any non-admin extras
*/
final readonly class LaunchCreateIfSingleTool
{
public function handle(Request $request, Closure $next): Response
{
if (LtiTool::count() === 1) {
$ltiTool = LtiTool::first();
if ($ltiTool->extras()->forAdmins(false)->count() === 0) {

Check failure on line 21 in sourcecode/hub/app/Http/Middleware/LaunchCreateIfSingleTool.php

View workflow job for this annotation

GitHub Actions / phpstan

Cannot call method extras() on App\Models\LtiTool|null.
return redirect(
route('content.launch-creator', $ltiTool)
);
}
}

return $next($request);
}
}
10 changes: 6 additions & 4 deletions sourcecode/hub/routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
use App\Http\Middleware\EnsureFrameCookies;
use App\Http\Middleware\LtiSessionRequired;
use App\Http\Middleware\LtiValidatedRequest;
use App\Http\Middleware\LaunchCreateIfSingleTool;
use App\Http\Middleware\StartScopedLtiSession;
use App\Models\Content;
use App\Models\User;
use Illuminate\Support\Facades\Route;

Expand Down Expand Up @@ -136,8 +138,8 @@
->scopeBindings();

Route::get('/content/create', 'create')
->middleware('auth')
->can('create', \App\Models\Content::class)
->middleware(['auth', LaunchCreateIfSingleTool::class])
->can('create', Content::class)
->name('content.create');

Route::post('/content/{content}/copy')
Expand Down Expand Up @@ -168,7 +170,7 @@
Route::get('/content/create/{tool:slug}/{extra:slug?}', 'launchCreator')
->uses([ContentController::class, 'launchCreator'])
->name('content.launch-creator')
->can('create', \App\Models\Content::class)
->can('create', Content::class)
->can('launchCreator', ['tool', 'extra'])
->scopeBindings();
});
Expand All @@ -180,7 +182,7 @@
Route::post('/tool/{tool}/content/create')
->uses([ContentController::class, 'ltiStore'])
->name('content.lti-store')
->can('create', \App\Models\Content::class)
->can('create', Content::class)
->whereUlid('tool');

Route::post('/tool/{tool}/content/{content}/version/{version}/update')
Expand Down
1 change: 0 additions & 1 deletion sourcecode/hub/tests/Browser/AdminTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ public function testCreatesToolsWithSlug(): void
->press('Add')
->assertSee('LTI tool added')
->clickLink('Create')
->clickLink('The tool')
->assertUrlIs('https://hub-test.edlib.test/content/create/the-tool')
->assertPresent('.lti-launch')
);
Expand Down
103 changes: 102 additions & 1 deletion sourcecode/hub/tests/Browser/ContentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Models\Context;
use App\Models\LtiPlatform;
use App\Models\LtiTool;
use App\Models\LtiToolExtra;
use App\Models\User;
use Carbon\Carbon;
use Facebook\WebDriver\Chrome\ChromeDevToolsDriver;
Expand Down Expand Up @@ -1074,7 +1075,6 @@ public function testContentCreatedInLtiContextInheritsPlatformRoles(): void
'iframe',
fn (Browser $frame) => $frame
->clickLink('Create')
->clickLink('My tool')
->withinFrame(
'iframe',
fn (Browser $tool) => $tool
Expand Down Expand Up @@ -1202,4 +1202,105 @@ public function testCannotEditContentInContextsOneIsNotPartOf(): void
)
);
}

public function testDoesNotListToolsOnCreateIfOneTool(): void
{
$platform = LtiPlatform::factory()->create();
LtiTool::factory()
->withName('Only Tool')
->slug('only-tool')
->launchUrl('https://hub-test.edlib.test/lti/samples/deep-link')
->withCredentials($platform->getOauth1Credentials())
->create();
$user = User::factory()->admin()->create();

$this->browse(
fn (Browser $browser) => $browser
->loginAs($user->email)
->assertAuthenticated()
->visit('/')
->clickLink('Create')
->assertUrlIs('https://hub-test.edlib.test/content/create/only-tool')
->assertPresent('.lti-launch')
);
}

public function testDoesNotListToolsOnCreateIfOneToolWithOnlyAdminExtra(): void
{
$platform = LtiPlatform::factory()->create();
LtiTool::factory()
->withName('Only Tool')
->slug('only-tool')
->launchUrl('https://hub-test.edlib.test/lti/samples/deep-link')
->withCredentials($platform->getOauth1Credentials())
->extra(
LtiToolExtra::factory()
->state([
'name' => 'Tool Admin',
'admin' => true,
])
)
->create();
$user = User::factory()->admin()->create();

$this->browse(
fn (Browser $browser) => $browser
->loginAs($user->email)
->assertAuthenticated()
->visit('/')
->clickLink('Create')
->assertUrlIs('https://hub-test.edlib.test/content/create/only-tool')
->assertPresent('.lti-launch')
);
}

public function testListToolsOnCreateIfMoreThanOneTool(): void
{
$platform = LtiPlatform::factory()->create();
LtiTool::factory()
->withName('First Tool')
->withCredentials($platform->getOauth1Credentials())
->create();
LtiTool::factory()
->withName('Second Tool')
->withCredentials($platform->getOauth1Credentials())
->create();
$user = User::factory()->admin()->create();

$this->browse(
fn (Browser $browser) => $browser
->loginAs($user->email)
->assertAuthenticated()
->visit('/')
->clickLink('Create')
->assertSeeLink('First Tool')
->assertSeeLink('Second Tool')
);
}

public function testListToolsOnCreateIfOneToolWithExtra(): void
{
$platform = LtiPlatform::factory()->create();
LtiTool::factory()
->withName('Only Tool')
->withCredentials($platform->getOauth1Credentials())
->extra(
LtiToolExtra::factory()
->state([
'name' => 'Tool Extra',
'admin' => false,
])
)
->create();
$user = User::factory()->admin()->create();

$this->browse(
fn (Browser $browser) => $browser
->loginAs($user->email)
->assertAuthenticated()
->clickLink('Create')
->assertSeeLink('Only Tool')
->assertSeeLink('Tool Extra')
);
}
}

0 comments on commit 9997805

Please sign in to comment.