2
0
Fork 0
mirror of https://github.com/koel/koel synced 2025-02-20 15:28:29 +00:00

chore: use Laravel' original structure

This commit is contained in:
Phan An 2020-09-12 17:01:48 +02:00
parent 8c7ea708a5
commit 860ec4648f
32 changed files with 98 additions and 134 deletions

View file

@ -1,3 +1,3 @@
FROM gitpod/workspace-mysql:latest FROM gitpod/workspace-mysql:latest
ENV APACHE_DOCROOT_IN_REPO="" ENV APACHE_DOCROOT_IN_REPO="public"

View file

@ -2163,7 +2163,7 @@ fetch(url, {
<p>Example response (200):</p> <p>Example response (200):</p>
</blockquote> </blockquote>
<pre><code class="language-json">{ <pre><code class="language-json">{
"artistUrl": "https:\/\/koel.host\/images\/artists\/new-cover.jpg" "artistUrl": "https:\/\/koel.host\/img\/artists\/new-cover.jpg"
}</code></pre> }</code></pre>
<h3>HTTP Request</h3> <h3>HTTP Request</h3>
<p><code>PUT api/artist/{artist}/image</code></p> <p><code>PUT api/artist/{artist}/image</code></p>

View file

@ -2236,7 +2236,7 @@ fetch(url, {
```json ```json
{ {
"artistUrl": "https:\/\/koel.host\/images\/artists\/new-cover.jpg" "artistUrl": "https:\/\/koel.host\/img\/artists\/new-cover.jpg"
} }
``` ```

View file

@ -17,16 +17,6 @@ class Application extends IlluminateApplication
*/ */
public const KOEL_VERSION = 'v4.4.0'; public const KOEL_VERSION = 'v4.4.0';
/**
* We have merged public path and base path.
*
* @return string
*/
public function publicPath()
{
return $this->basePath;
}
/** /**
* Loads a revision'ed asset file, making use of gulp-rev * Loads a revision'ed asset file, making use of gulp-rev
* This is a copycat of L5's Elixir, but catered to our directory structure. * This is a copycat of L5's Elixir, but catered to our directory structure.
@ -37,16 +27,16 @@ class Application extends IlluminateApplication
{ {
static $manifest = null; static $manifest = null;
$manifestFile = $manifestFile ?: public_path('public/mix-manifest.json'); $manifestFile = $manifestFile ?: public_path('mix-manifest.json');
if ($manifest === null) { if ($manifest === null) {
$manifest = json_decode(file_get_contents($manifestFile), true); $manifest = json_decode(file_get_contents($manifestFile), true);
} }
if (isset($manifest[$file])) { if (isset($manifest[$file])) {
return file_exists(public_path('public/hot')) return file_exists(public_path('hot'))
? "http://localhost:8080/public{$manifest[$file]}" ? "http://localhost:8080{$manifest[$file]}"
: $this->staticUrl("public{$manifest[$file]}"); : $this->staticUrl("{$manifest[$file]}");
} }
throw new InvalidArgumentException("File {$file} not defined in asset manifest."); throw new InvalidArgumentException("File {$file} not defined in asset manifest.");

View file

@ -24,7 +24,7 @@ class AlbumThumbnailController extends Controller
* Get an album's thumbnail (a 48px-wide blurry version of the album's cover). * Get an album's thumbnail (a 48px-wide blurry version of the album's cover).
* Returns the full URL to the thumbnail or NULL if the album has no cover. * Returns the full URL to the thumbnail or NULL if the album has no cover.
* *
* @response ["thumbnailUrl", "https://localhost/public/img/covers/a146d01afb742b01f28ab8b556f9a75d_thumbnail.jpg"] * @response ["thumbnailUrl", "https://localhost/img/covers/a146d01afb742b01f28ab8b556f9a75d_thumbnail.jpg"]
*/ */
public function get(Album $album): JsonResponse public function get(Album $album): JsonResponse
{ {

View file

@ -21,7 +21,7 @@ class RedirectIfAuthenticated
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next)
{ {
if ($this->auth->check()) { if ($this->auth->check()) {
return redirect('/'); return redirect('/');
} }
return $next($request); return $next($request);

View file

@ -1,25 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
/**
* Check if the app is running in an E2E session and use the proper data settings.
*/
class UseDifferentConfigIfE2E
{
/**
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if (Arr::get($_SERVER, 'SERVER_PORT') === '8081') {
config(['database.default' => 'sqlite-e2e']);
}
return $next($request);
}
}

View file

@ -11,7 +11,7 @@
| |
*/ */
$app = new App\Application(__DIR__.'/../'); $app = new App\Application(dirname(__DIR__));
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View file

@ -1,7 +1,5 @@
<?php <?php
define('LARAVEL_START', microtime(true));
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Register The Composer Auto Loader | Register The Composer Auto Loader

View file

@ -19,10 +19,10 @@ return [
'media_path' => env('MEDIA_PATH'), 'media_path' => env('MEDIA_PATH'),
// The *relative* path to the directory to store album covers and thumbnails, *with* a trailing slash. // The *relative* path to the directory to store album covers and thumbnails, *with* a trailing slash.
'album_cover_dir' => 'public/img/covers/', 'album_cover_dir' => 'img/covers/',
// The *relative* path to the directory to store artist images, *with* a trailing slash. // The *relative* path to the directory to store artist images, *with* a trailing slash.
'artist_image_dir' => 'public/img/artists/', 'artist_image_dir' => 'img/artists/',
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View file

@ -1,18 +1,13 @@
server { server {
listen *:80; listen *:80;
server_name koel.dev; server_name koel.dev;
root /var/www/koel; root /var/www/koel/public;
index index.php; index index.php;
gzip on; gzip on;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json; gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json;
gzip_comp_level 9; gzip_comp_level 9;
# Whitelist only index.php, robots.txt, and some special routes
if ($request_uri !~ ^/$|index\.php|robots\.txt|(public|api|web)/|remote|api-docs|sw\.js) {
return 404;
}
location /media/ { location /media/ {
internal; internal;

12
public/.gitignore vendored
View file

@ -1,5 +1,7 @@
* css
!.gitignore fonts
!manifest.json.example img
!manifest-remote.json.example js
!browserconfig.xml manifest.json
manifest-remote.json
hot

View file

@ -6,26 +6,24 @@
<IfModule mod_rewrite.c> <IfModule mod_rewrite.c>
<IfModule mod_negotiation.c> <IfModule mod_negotiation.c>
Options -MultiViews Options -MultiViews -Indexes
</IfModule> </IfModule>
RewriteEngine On RewriteEngine On
RewriteBase /
# Redirect Trailing Slashes... # Handle Authorization Header
RewriteRule ^(.*)/$ /$1 [L,R=301] RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Whitelist only index.php, robots.txt, and some special routes # Redirect Trailing Slashes If Not A Folder...
RewriteRule ^(?!($|index\.php|robots\.txt|(public|api|web)/|remote|api-docs|sw\.js)) - [R=404,L] RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller... # Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php [L] RewriteRule ^ index.php [L]
# https://github.com/tymondesigns/jwt-auth/wiki/Authentication
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
</IfModule> </IfModule>
<IfModule mod_expires.c> <IfModule mod_expires.c>
@ -52,7 +50,7 @@
<IfModule mod_deflate.c> <IfModule mod_deflate.c>
# Disable deflation for media files. # Disable deflation for media files.
SetEnvIfNoCase Request_URI "^/api/play/" no-gzip dont-vary SetEnvIfNoCase Request_URI "^/play/" no-gzip dont-vary
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Gzip compression. # Gzip compression.

View file

@ -3,10 +3,10 @@
<browserconfig> <browserconfig>
<msapplication> <msapplication>
<tile> <tile>
<square70x70logo src="public/img/tile.png"/> <square70x70logo src="img/tile.png"/>
<square150x150logo src="public/img/tile.png"/> <square150x150logo src="img/tile.png"/>
<wide310x150logo src="public/img/tile-wide.png"/> <wide310x150logo src="img/tile-wide.png"/>
<square310x310logo src="public/img/tile.png"/> <square310x310logo src="img/tile.png"/>
</tile> </tile>
</msapplication> </msapplication>
</browserconfig> </browserconfig>

View file

@ -18,7 +18,12 @@
| |
*/ */
require __DIR__.'/bootstrap/autoload.php'; use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
require __DIR__.'/../bootstrap/autoload.php';
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -32,7 +37,7 @@ require __DIR__.'/bootstrap/autoload.php';
| |
*/ */
$app = require_once __DIR__.'/bootstrap/app.php'; $app = require_once __DIR__.'/../bootstrap/app.php';
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -46,12 +51,10 @@ $app = require_once __DIR__.'/bootstrap/app.php';
| |
*/ */
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $kernel = $app->make(Kernel::class);
$response = $kernel->handle( $response = tap($kernel->handle(
$request = Illuminate\Http\Request::capture() $request = Request::capture()
); ))->send();
$response->send();
$kernel->terminate($request, $response); $kernel->terminate($request, $response);

View file

@ -4,7 +4,7 @@
"display": "standalone", "display": "standalone",
"orientation": "portrait", "orientation": "portrait",
"icons": [{ "icons": [{
"src": "/public/img/icon.png", "src": "/img/icon.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png" "type": "image/png"
}], }],

View file

@ -4,7 +4,7 @@
"display": "standalone", "display": "standalone",
"orientation": "portrait", "orientation": "portrait",
"icons": [{ "icons": [{
"src": "/public/img/icon.png", "src": "/img/icon.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png" "type": "image/png"
}], }],

6
public/mix-manifest.json Normal file
View file

@ -0,0 +1,6 @@
{
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css",
"/css/remote.css": "/css/remote.css",
"/js/remote/app.js": "/js/remote/app.js"
}

View file

View file

@ -12,11 +12,11 @@
<meta name="msapplication-navbutton-color" content="#282828"> <meta name="msapplication-navbutton-color" content="#282828">
<base href="{{ asset('') }}"> <base href="{{ asset('') }}">
<link rel="manifest" href="{{ App::staticUrl('public/manifest.json') }}" /> <link rel="manifest" href="{{ App::staticUrl('manifest.json') }}" />
<meta name="msapplication-config" content="{{ App::staticUrl('public/browserconfig.xml') }}" /> <meta name="msapplication-config" content="{{ App::staticUrl('browserconfig.xml') }}" />
<link rel="icon" type="image/x-icon" href="{{ App::staticUrl('public/img/favicon.ico') }}" /> <link rel="icon" type="image/x-icon" href="{{ App::staticUrl('img/favicon.ico') }}" />
<link rel="icon" href="{{ App::staticUrl('public/img/icon.png') }}"> <link rel="icon" href="{{ App::staticUrl('img/icon.png') }}">
<link rel="apple-touch-icon" href="{{ App::staticUrl('public/img/icon.png') }}"> <link rel="apple-touch-icon" href="{{ App::staticUrl('img/icon.png') }}">
<link rel="stylesheet" href="{{ App::rev('/css/app.css') }}"> <link rel="stylesheet" href="{{ App::rev('/css/app.css') }}">
</head> </head>

View file

@ -13,11 +13,11 @@
<meta name="msapplication-navbutton-color" content="#282828"> <meta name="msapplication-navbutton-color" content="#282828">
<base href="{{ asset('') }}"> <base href="{{ asset('') }}">
<link rel="manifest" href="{{ App::staticUrl('public/manifest-remote.json') }}" /> <link rel="manifest" href="{{ App::staticUrl('manifest-remote.json') }}" />
<meta name="msapplication-config" content="{{ App::staticUrl('public/browserconfig.xml') }}" /> <meta name="msapplication-config" content="{{ App::staticUrl('browserconfig.xml') }}" />
<link rel="icon" type="image/x-icon" href="{{ App::staticUrl('public/img/favicon.ico') }}" /> <link rel="icon" type="image/x-icon" href="{{ App::staticUrl('img/favicon.ico') }}" />
<link rel="icon" href="{{ App::staticUrl('public/img/icon.png') }}"> <link rel="icon" href="{{ App::staticUrl('img/icon.png') }}">
<link rel="apple-touch-icon" href="{{ App::staticUrl('public/img/icon.png') }}"> <link rel="apple-touch-icon" href="{{ App::staticUrl('img/icon.png') }}">
<link rel="stylesheet" href="{{ App::rev('/css/remote.css') }}"> <link rel="stylesheet" href="{{ App::rev('/css/remote.css') }}">
</head> </head>

View file

@ -11,8 +11,8 @@ Route::get('/remote', static function () {
return view('remote'); return view('remote');
}); });
Route::group(['middleware' => 'auth', 'prefix' => 'web'], static function (): void { Route::group(['middleware' => 'auth'], static function (): void {
Route::get('/{song}/play/{transcode?}/{bitrate?}', 'PlayController@show') Route::get('play/{song}/{transcode?}/{bitrate?}', 'PlayController@show')
->name('song.play'); ->name('song.play');
Route::group(['prefix' => 'lastfm'], static function (): void { Route::group(['prefix' => 'lastfm'], static function (): void {

View file

@ -12,8 +12,8 @@ $uri = urldecode(
// This file allows us to emulate Apache's "mod_rewrite" functionality from the // This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel // built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here. // application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.$uri)) { if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false; return false;
} }
require_once __DIR__.'/index.php'; require_once __DIR__.'/public/index.php';

View file

@ -1,3 +1,3 @@
{ {
"coverUrl": "https://koel.host/images/albums/new-cover.jpg" "coverUrl": "https://koel.host/img/albums/new-cover.jpg"
} }

View file

@ -1,3 +1,3 @@
{ {
"imageUrl": "https://koel.host/images/artists/new-cover.jpg" "imageUrl": "https://koel.host/img/artists/new-cover.jpg"
} }

View file

@ -18,7 +18,7 @@ class AlbumThumbnailTest extends TestCase
public function provideAlbumThumbnailData(): array public function provideAlbumThumbnailData(): array
{ {
return [['http://localhost/public/img/covers/foo_thumbnail.jpg'], [null]]; return [['http://localhost/img/covers/foo_thumbnail.jpg'], [null]];
} }
/** @dataProvider provideAlbumThumbnailData */ /** @dataProvider provideAlbumThumbnailData */

View file

@ -41,7 +41,7 @@ class DownloadTest extends TestCase
->shouldReceive('from') ->shouldReceive('from')
->never(); ->never();
$this->get("web/download/songs?songs[]={$song->id}") $this->get("download/songs?songs[]={$song->id}")
->assertRedirect('/'); ->assertRedirect('/');
} }
@ -60,7 +60,7 @@ class DownloadTest extends TestCase
})) }))
->andReturn($this->mediaPath.'/blank.mp3'); ->andReturn($this->mediaPath.'/blank.mp3');
$this->get("web/download/songs?songs[]={$song->id}&api_token=".$user->createToken('Koel')->plainTextToken) $this->get("download/songs?songs[]={$song->id}&api_token=".$user->createToken('Koel')->plainTextToken)
->assertOk(); ->assertOk();
} }
@ -83,7 +83,7 @@ class DownloadTest extends TestCase
->andReturn($this->mediaPath.'/blank.mp3'); // should be a zip file, but we're testing here… ->andReturn($this->mediaPath.'/blank.mp3'); // should be a zip file, but we're testing here…
$this->get( $this->get(
"web/download/songs?songs[]={$songs[0]->id}&songs[]={$songs[1]->id}&api_token=" "download/songs?songs[]={$songs[0]->id}&songs[]={$songs[1]->id}&api_token="
.$user->createToken('Koel')->plainTextToken .$user->createToken('Koel')->plainTextToken
) )
->assertOk(); ->assertOk();
@ -104,7 +104,7 @@ class DownloadTest extends TestCase
})) }))
->andReturn($this->mediaPath.'/blank.mp3'); ->andReturn($this->mediaPath.'/blank.mp3');
$this->get("web/download/album/{$album->id}?api_token=".$user->createToken('Koel')->plainTextToken) $this->get("download/album/{$album->id}?api_token=".$user->createToken('Koel')->plainTextToken)
->assertOk(); ->assertOk();
} }
@ -123,7 +123,7 @@ class DownloadTest extends TestCase
})) }))
->andReturn($this->mediaPath.'/blank.mp3'); ->andReturn($this->mediaPath.'/blank.mp3');
$this->get("web/download/artist/{$artist->id}?api_token=".$user->createToken('Koel')->plainTextToken) $this->get("download/artist/{$artist->id}?api_token=".$user->createToken('Koel')->plainTextToken)
->assertOk(); ->assertOk();
} }
@ -145,7 +145,7 @@ class DownloadTest extends TestCase
->once() ->once()
->andReturn($this->mediaPath.'/blank.mp3'); ->andReturn($this->mediaPath.'/blank.mp3');
$this->get("web/download/playlist/{$playlist->id}?api_token=".$user->createToken('Koel')->plainTextToken) $this->get("download/playlist/{$playlist->id}?api_token=".$user->createToken('Koel')->plainTextToken)
->assertOk(); ->assertOk();
} }
@ -157,7 +157,7 @@ class DownloadTest extends TestCase
/** @var User $user */ /** @var User $user */
$user = factory(User::class)->create(); $user = factory(User::class)->create();
$this->get("web/download/playlist/{$playlist->id}?api_token=".$user->createToken('Koel')->plainTextToken) $this->get("download/playlist/{$playlist->id}?api_token=".$user->createToken('Koel')->plainTextToken)
->assertStatus(Response::HTTP_FORBIDDEN); ->assertStatus(Response::HTTP_FORBIDDEN);
} }
@ -181,7 +181,7 @@ class DownloadTest extends TestCase
->once() ->once()
->andReturn($this->mediaPath.'/blank.mp3'); ->andReturn($this->mediaPath.'/blank.mp3');
$this->get('web/download/favorites?api_token='.$user->createToken('Koel')->plainTextToken) $this->get('download/favorites?api_token='.$user->createToken('Koel')->plainTextToken)
->assertOk(); ->assertOk();
} }
} }

View file

@ -56,9 +56,9 @@ class LastfmTest extends TestCase
->with($user) ->with($user)
->andReturn($temporaryToken); ->andReturn($temporaryToken);
$this->get('web/lastfm/connect?api_token='.$token) $this->get('lastfm/connect?api_token='.$token)
->assertRedirect( ->assertRedirect(
'https://www.last.fm/api/auth/?api_key=foo&cb=http%3A%2F%2Flocalhost%2Fweb%2Flastfm%2Fcallback%3Fapi_token%3Dtmp-token' 'https://www.last.fm/api/auth/?api_key=foo&cb=http%3A%2F%2Flocalhost%2Flastfm%2Fcallback%3Fapi_token%3Dtmp-token'
); );
} }
@ -77,7 +77,7 @@ class LastfmTest extends TestCase
->once() ->once()
->andReturn('my-session-key'); ->andReturn('my-session-key');
$this->get('web/lastfm/callback?token=lastfm-token&api_token='.urlencode($token)) $this->get('lastfm/callback?token=lastfm-token&api_token='.urlencode($token))
->assertOk(); ->assertOk();
self::assertSame('my-session-key', $user->refresh()->lastfm_session_key); self::assertSame('my-session-key', $user->refresh()->lastfm_session_key);
@ -102,7 +102,7 @@ class LastfmTest extends TestCase
->with('my-token') ->with('my-token')
->andReturn($user); ->andReturn($user);
$this->get('web/lastfm/callback?token=foo&api_token=my-token'); $this->get('lastfm/callback?token=foo&api_token=my-token');
self::assertEquals('bar', $user->refresh()->lastfm_session_key); self::assertEquals('bar', $user->refresh()->lastfm_session_key);
} }

View file

@ -8,15 +8,15 @@ trait SandboxesTests
{ {
private static function createSandbox(): void private static function createSandbox(): void
{ {
config(['koel.album_cover_dir' => 'public/sandbox/img/covers/']); config(['koel.album_cover_dir' => 'sandbox/img/covers/']);
config(['koel.artist_image_dir' => 'public/sandbox/img/artists/']); config(['koel.artist_image_dir' => 'sandbox/img/artists/']);
@mkdir(base_path(config('koel.album_cover_dir')), 0755, true); @mkdir(public_path(config('koel.album_cover_dir')), 0755, true);
@mkdir(base_path(config('koel.artist_image_dir')), 0755, true); @mkdir(public_path(config('koel.artist_image_dir')), 0755, true);
} }
private static function destroySandbox(): void private static function destroySandbox(): void
{ {
File::deleteDirectory(base_path('public/sandbox')); File::deleteDirectory(public_path('sandbox'));
} }
} }

View file

@ -9,7 +9,8 @@ class ApplicationTest extends TestCase
public function setUp(): void public function setUp(): void
{ {
parent::setUp(); parent::setUp();
@unlink(app()->publicPath().'/public/hot');
@unlink(public_path('hot'));
} }
/** @test */ /** @test */
@ -55,7 +56,7 @@ class ApplicationTest extends TestCase
$assetURL = app()->rev('/foo.css', $manifestFile); $assetURL = app()->rev('/foo.css', $manifestFile);
// Then I see they're constructed correctly // Then I see they're constructed correctly
self::assertEquals('http://localhost/public/foo00.css', $assetURL); self::assertEquals('http://localhost/foo00.css', $assetURL);
} }
/** @test */ /** @test */
@ -71,6 +72,6 @@ class ApplicationTest extends TestCase
$assetURL = app()->rev('/foo.css', $manifestFile); $assetURL = app()->rev('/foo.css', $manifestFile);
// Then I see they're constructed correctly // Then I see they're constructed correctly
self::assertEquals('http://cdn.tld/public/foo00.css', $assetURL); self::assertEquals('http://cdn.tld/foo00.css', $assetURL);
} }
} }

View file

@ -34,12 +34,12 @@ class MediaMetadataServiceTest extends TestCase
/** @var Album $album */ /** @var Album $album */
$album = factory(Album::class)->create(); $album = factory(Album::class)->create();
$coverContent = 'dummy'; $coverContent = 'dummy';
$coverPath = '/koel/public/images/album/foo.jpg'; $coverPath = '/koel/public/img/album/foo.jpg';
$this->imageWriter $this->imageWriter
->shouldReceive('writeFromBinaryData') ->shouldReceive('writeFromBinaryData')
->once() ->once()
->with('/koel/public/images/album/foo.jpg', 'dummy'); ->with('/koel/public/img/album/foo.jpg', 'dummy');
$this->mediaMetadataService->writeAlbumCover($album, $coverContent, 'jpg', $coverPath); $this->mediaMetadataService->writeAlbumCover($album, $coverContent, 'jpg', $coverPath);
self::assertEquals(album_cover_url('foo.jpg'), Album::find($album->id)->cover); self::assertEquals(album_cover_url('foo.jpg'), Album::find($album->id)->cover);
@ -50,12 +50,12 @@ class MediaMetadataServiceTest extends TestCase
/** @var Artist $artist */ /** @var Artist $artist */
$artist = factory(Artist::class)->create(); $artist = factory(Artist::class)->create();
$imageContent = 'dummy'; $imageContent = 'dummy';
$imagePath = '/koel/public/images/artist/foo.jpg'; $imagePath = '/koel/public/img/artist/foo.jpg';
$this->imageWriter $this->imageWriter
->shouldReceive('writeFromBinaryData') ->shouldReceive('writeFromBinaryData')
->once() ->once()
->with('/koel/public/images/artist/foo.jpg', 'dummy'); ->with('/koel/public/img/artist/foo.jpg', 'dummy');
$this->mediaMetadataService->writeArtistImage($artist, $imageContent, 'jpg', $imagePath); $this->mediaMetadataService->writeArtistImage($artist, $imageContent, 'jpg', $imagePath);
self::assertEquals(artist_image_url('foo.jpg'), Artist::find($artist->id)->image); self::assertEquals(artist_image_url('foo.jpg'), Artist::find($artist->id)->image);

View file

@ -8,7 +8,7 @@ mix.webpackConfig({
plugins, plugins,
output: { output: {
chunkFilename: mix.config.production ? 'js/[name].[chunkhash].js' : 'js/[name].js', chunkFilename: mix.config.production ? 'js/[name].[chunkhash].js' : 'js/[name].js',
publicPath: '/public/' publicPath: '/'
}, },
devServer: { devServer: {
port: 8080, port: 8080,
@ -18,13 +18,9 @@ mix.webpackConfig({
} }
}) })
mix.setResourceRoot('./public/') mix.setResourceRoot('./')
if (mix.config.hmr) { if (mix.config.hmr) {
// There's a bug with Mix/copy plugin which prevents HMR from working:
// https://github.com/JeffreyWay/laravel-mix/issues/150
console.log('In HMR mode. If assets are missing, Ctr+C and run `yarn dev` first.')
// Somehow public/hot isn't being removed by Mix. We'll handle it ourselves. // Somehow public/hot isn't being removed by Mix. We'll handle it ourselves.
process.on('SIGINT', () => { process.on('SIGINT', () => {
try { try {