['#3c8dbc'], 'hex 3-digit' => ['#fff'], 'rgb' => ['rgb(10,20,30)'], 'rgba' => ['rgba(10,20,30,0.5)'], 'hsl' => ['hsl(120,50%,50%)'], 'hsla' => ['hsla(120,50%,50%,0.8)'], ]; } public static function invalidColorProvider(): array { return [ 'named color' => ['red'], 'css injection payload' => ['red; }body{background:url(//evil.com)} .x{color: #'], 'url()' => ['url(http://evil.com)'], 'value with semicolon' => ['#3c8dbc; color: red'], ]; } #[DataProvider('validColorProvider')] public function test_valid_header_color_can_be_saved(string $color): void { $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save'), ['header_color' => $color]) ->assertValid('header_color') ->assertSessionHasNoErrors(); $this->assertDatabaseHas('settings', ['header_color' => $color]); } #[DataProvider('invalidColorProvider')] public function test_invalid_header_color_is_rejected(string $color): void { $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save'), ['header_color' => $color]) ->assertInvalid(['header_color']) ->assertSessionHasErrors(['header_color']); } #[DataProvider('validColorProvider')] public function test_valid_link_colors_can_be_saved(string $color): void { $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save'), [ 'link_light_color' => $color, 'link_dark_color' => $color, 'nav_link_color' => $color, ]) ->assertValid(['link_light_color', 'link_dark_color', 'nav_link_color']) ->assertSessionHasNoErrors(); } #[DataProvider('invalidColorProvider')] public function test_invalid_link_colors_are_rejected(string $color): void { $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save'), [ 'link_light_color' => $color, 'link_dark_color' => $color, 'nav_link_color' => $color, ]) ->assertInvalid(['link_light_color', 'link_dark_color', 'nav_link_color']) ->assertSessionHasErrors(['link_light_color', 'link_dark_color', 'nav_link_color']); } public function test_setting_model_sanitizes_corrupt_header_color(): void { $setting = Setting::factory()->create(); $setting->setRawAttributes(['header_color' => 'red; }body{color:red}']); $this->assertSame('#3c8dbc', $setting->header_color); } public function test_setting_model_passes_through_valid_header_color(): void { $setting = Setting::factory()->create(['header_color' => '#5fa4cc']); $this->assertSame('#5fa4cc', $setting->header_color); } public function test_site_name_is_required() { $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['site_name' => ''])) ->assertSessionHasErrors(['site_name']) ->assertInvalid(['site_name']) ->assertStatus(302) ->assertRedirect(route('settings.branding.index')); $this->followRedirects($response)->assertSee(trans('general.error')); } public function test_site_name_can_be_saved() { $response = $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save', ['site_name' => 'My Awesome Site'])) ->assertStatus(302) ->assertValid('site_name') ->assertRedirect(route('settings.index')) ->assertSessionHasNoErrors(); $this->followRedirects($response)->assertSee('alert-success'); } public function test_logo_can_be_uploaded() { Storage::fake('public'); $setting = Setting::factory()->create(['logo' => null]); $response = $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save', ['logo' => UploadedFile::fake()->image('test_logo.png')] )) ->assertValid('logo') ->assertStatus(302) ->assertRedirect(route('settings.index')) ->assertSessionHasNoErrors(); // Assert files was stored... Storage::disk('public')->assertExists($setting->logo); $this->followRedirects($response)->assertSee('alert-success'); $setting->refresh(); } public function test_logo_can_be_deleted() { Storage::fake('public'); UploadedFile::fake()->image('new_test_logo.png')->storeAs('uploads', 'new_test_logo.png', 'public'); $setting = Setting::factory()->create(['logo' => 'new_test_logo.png']); Storage::disk('public')->assertExists('uploads/'.$setting->logo); $this->assertNotNull($setting->logo); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['clear_logo' => '1'] )) ->assertValid('logo') ->assertStatus(302) ->assertRedirect(route('settings.index')); $this->followRedirects($response)->assertSee(trans('alert-success')); $this->assertDatabaseHas('settings', ['logo' => null]); Storage::disk('public')->assertMissing($setting->logo); } public function test_email_logo_can_be_uploaded() { Storage::fake('public'); Setting::factory()->create(['email_logo' => null]); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', [ 'email_logo' => UploadedFile::fake()->image('new_test_email_logo.png')->storeAs('', 'new_test_email_logo.png', 'public'), ] )) ->assertValid('email_logo') ->assertStatus(302) ->assertRedirect(route('settings.index')); $this->followRedirects($response)->assertSee(trans('alert-success')); Storage::disk('public')->assertExists('new_test_email_logo.png'); } public function test_email_logo_can_be_deleted() { Storage::fake('public'); UploadedFile::fake()->image('new_test_logo.png')->storeAs('uploads', 'new_test_logo.png', 'public'); $setting = Setting::factory()->create(['email_logo' => 'new_test_logo.png']); Storage::disk('public')->assertExists('uploads/'.$setting->email_logo); $this->assertNotNull($setting->email_logo); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['clear_email_logo' => '1'] )) ->assertValid('email_logo') ->assertStatus(302) ->assertRedirect(route('settings.index')); $setting->refresh(); $this->followRedirects($response)->assertSee(trans('alert-success')); $this->assertDatabaseHas('settings', ['email_logo' => null]); Storage::disk('public')->assertMissing('new_test_email_logo.png'); } public function test_label_logo_can_be_uploaded() { Storage::fake('public'); $original_file = UploadedFile::fake()->image('before_test_label_logo.png')->storeAs('', 'before_test_label_logo.png', 'public'); Storage::disk('public')->assertExists($original_file); Setting::factory()->create(['label_logo' => $original_file]); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', [ 'label_logo' => UploadedFile::fake()->image('new_test_label_logo.png')->storeAs('', 'new_test_label_logo.png', 'public'), ] )) ->assertValid('label_logo') ->assertStatus(302) ->assertRedirect(route('settings.index')); $this->followRedirects($response)->assertSee(trans('alert-success')); Storage::disk('public')->assertExists('new_test_label_logo.png'); // Storage::disk('public')->assertMissing($original_file); } public function test_label_logo_can_be_deleted() { Storage::fake('public'); UploadedFile::fake()->image('new_test_label_logo.png')->storeAs('uploads', 'new_test_label_logo.png', 'public'); $setting = Setting::factory()->create(['label_logo' => 'new_test_label_logo.png']); Storage::disk('public')->assertExists('uploads/'.$setting->label_logo); $this->assertNotNull($setting->label_logo); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['label_logo' => '1'] )) ->assertValid('label_logo') ->assertStatus(302) ->assertRedirect(route('settings.index')); $setting->refresh(); $this->followRedirects($response)->assertSee(trans('alert-success')); Storage::disk('public')->assertMissing('new_test_label_logo.png'); } public function test_default_avatar_can_be_uploaded() { Storage::fake('public'); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', [ 'default_avatar' => UploadedFile::fake()->image('default_avatar.png')->storeAs('', 'default_avatar.png', 'public'), ] )) ->assertValid('default_avatar') ->assertStatus(302) ->assertRedirect(route('settings.index')) ->assertSessionHasNoErrors(); $this->followRedirects($response)->assertSee(trans('alert-success')); Storage::disk('public')->assertExists('default_avatar.png'); // Storage::disk('public')->assertMissing($original_file); } public function test_default_avatar_can_be_deleted() { Storage::fake('public'); $setting = Setting::factory()->create(['default_avatar' => 'new_test_label_logo.png']); $original_file = UploadedFile::fake()->image('default_avatar.png')->storeAs('', 'default_avatar.png', 'public'); Storage::disk('public')->assertExists($original_file); $this->assertNotNull($setting->default_avatar); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['clear_default_avatar' => '1'] )) ->assertValid('default_avatar') ->assertStatus(302) ->assertRedirect(route('settings.index')); $setting->refresh(); $this->followRedirects($response)->assertSee(trans('alert-success')); // $this->assertNull($setting->refresh()->default_avatar); // Storage::disk('public')->assertMissing($original_file); } public function test_snipe_default_avatar_can_be_deleted() { $setting = Setting::getSettings()->first(); Storage::fake('public'); $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save', ['default_avatar' => UploadedFile::fake()->image('default.png')->storeAs('avatars', 'default.png', 'public')] )); Storage::disk('public')->assertExists('avatars/default.png'); $this->actingAs(User::factory()->superuser()->create()) ->post(route('settings.branding.save', ['clear_default_avatar' => '1'] )); $this->assertNull($setting->refresh()->default_avatar); $this->assertDatabaseHas('settings', ['default_avatar' => null]); Storage::disk('public')->assertExists('avatars/default.png'); } public function test_favicon_can_be_uploaded() { $this->markTestIncomplete('This fails mimetype validation on the mock'); Storage::fake('public'); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', [ 'favicon' => UploadedFile::fake()->image('favicon.svg')->storeAs('', 'favicon.svg', 'public'), ] )) ->assertValid('favicon') ->assertStatus(302) ->assertRedirect(route('settings.index')); $this->followRedirects($response)->assertSee(trans('alert-success')); Storage::disk('public')->assertExists('favicon.png'); } public function test_favicon_can_be_deleted() { $this->markTestIncomplete('This fails mimetype validation on the mock'); Storage::fake('public'); $setting = Setting::factory()->create(['favicon' => 'favicon.png']); $original_file = UploadedFile::fake()->image('favicon.png')->storeAs('', 'favicon.png', 'public'); Storage::disk('public')->assertExists($original_file); $this->assertNotNull($setting->favicon); $response = $this->actingAs(User::factory()->superuser()->create()) ->from(route('settings.branding.index')) ->post(route('settings.branding.save', ['clear_favicon' => '1'] )) ->assertValid('favicon') ->assertStatus(302) ->assertRedirect(route('settings.index')); $setting->refresh(); $this->followRedirects($response)->assertSee(trans('alert-success')); $this->assertDatabaseHas('settings', ['favicon' => null]); // This fails for some reason - the file is not being deleted, or at least the test doesn't think it is // Storage::disk('public')->assertMissing('favicon.png'); } }