From 256b197153983a2edcd7a8fe2f416b74516dfda0 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 18 Jul 2014 09:06:54 +0100
Subject: [PATCH] Issue #2276219 by Wim Leers: Asset libraries should declare
 their license.

---
 core/core.libraries.yml                       | 174 ++++++++++++++----
 ...braryDefinitionMissingLicenseException.php |  15 ++
 .../Core/Asset/LibraryDiscoveryParser.php     |  15 ++
 .../Core/Asset/LibraryDiscoveryParserTest.php | 106 +++++++++++
 .../library_test_files/licenses.libraries.yml |  72 ++++++++
 ...licenses_missing_information.libraries.yml |   9 +
 6 files changed, 356 insertions(+), 35 deletions(-)
 create mode 100644 core/lib/Drupal/Core/Asset/Exception/LibraryDefinitionMissingLicenseException.php
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses.libraries.yml
 create mode 100644 core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses_missing_information.libraries.yml

diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index cd03cd38d880..c76d86539444 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -3,6 +3,10 @@
 backbone:
   remote: https://github.com/jashkenas/backbone
   version: 1.1.0
+  license:
+    name: MIT
+    url: https://github.com/jashkenas/backbone/blob/1.1.0/LICENSE
+    gpl-compatible: true
   js:
     assets/vendor/backbone/backbone.js: { weight: -19 }
   dependencies:
@@ -12,18 +16,30 @@ classList:
   remote: https://github.com/eligrey/classList.js
   # @todo Stable release required for Drupal 8.0.
   version: master
+  license:
+    name: Public Domain
+    url: https://github.com/eligrey/classList.js/blob/master/LICENSE.md
+    gpl-compatible: true
   js:
     assets/vendor/classList/classList.min.js: { weight: -21, browsers: { IE: 'lte IE 9', '!IE': false } }
 
 ckeditor:
   remote: https://github.com/ckeditor/ckeditor-dev
   version: 4.4.0
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: https://github.com/ckeditor/ckeditor-dev/blob/887d81ac1824008b690e439a1b29eb4f13b51212/LICENSE.md
+    gpl-compatible: true
   js:
     assets/vendor/ckeditor/ckeditor.js: { preprocess: false }
 
 domready:
   remote: https://github.com/ded/domready
   version: 1.0.4
+  license:
+    name: MIT
+    url: https://github.com/ded/domready/blob/v1.0.4/LICENSE
+    gpl-compatible: true
   js:
     assets/vendor/domready/ready.min.js: { weight: -21 }
 
@@ -278,18 +294,30 @@ drupal.vertical-tabs:
 html5shiv:
   remote: https://github.com/aFarkas/html5shiv
   version: 3.6.2
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: http://www.gnu.org/licenses/gpl-2.0.html
+    gpl-compatible: true
   js:
     assets/vendor/html5shiv/html5.js: { every_page: true, weight: -22, browsers: { IE: 'lte IE 8', '!IE': false } }
 
 jquery:
   remote: https://github.com/jquery/jquery
   version: 2.1.0
+  license:
+    name: MIT
+    url: https://github.com/jquery/jquery/blob/2.1.0/MIT-LICENSE.txt
+    gpl-compatible: true
   js:
     assets/vendor/jquery/jquery.js: { weight: -20 }
 
 jquery.cookie:
   remote: https://github.com/carhartl/jquery-cookie
   version: v1.4.0
+  license:
+    name: MIT
+    url: https://github.com/carhartl/jquery-cookie/blob/v1.4.0/MIT-LICENSE.txt
+    gpl-compatible: true
   js:
     assets/vendor/jquery.cookie/jquery.cookie.js: {}
   dependencies:
@@ -299,6 +327,10 @@ jquery.farbtastic:
   remote: https://github.com/mattfarina/farbtastic
   # @todo Ping @robloach or @mattfarina to retroactively create this release.
   version: 1.2
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: https://github.com/mattfarina/farbtastic/blob/master/LICENSE.txt
+    gpl-compatible: true
   js:
     assets/vendor/farbtastic/farbtastic.js: {}
   css:
@@ -310,6 +342,10 @@ jquery.farbtastic:
 jquery.form:
   remote: https://github.com/malsup/form
   version: 3.50
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: http://malsup.github.com/gpl-license-v2.txt
+    gpl-compatible: true
   js:
     assets/vendor/jquery-form/jquery.form.js: {}
   dependencies:
@@ -325,6 +361,10 @@ jquery.intrinsic:
 jquery.joyride:
   remote: https://github.com/zurb/joyride
   version: v2.0.3
+  license:
+    name: MIT
+    url: https://github.com/zurb/joyride/blob/v2.0.3/README.markdown
+    gpl-compatible: true
   js:
     assets/vendor/jquery-joyride/jquery.joyride-2.0.3.js: {}
   dependencies:
@@ -334,6 +374,10 @@ jquery.joyride:
 jquery.once:
   remote: https://github.com/RobLoach/jquery-once
   version: 1.2.3
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: https://github.com/RobLoach/jquery-once/blob/1.2.3/LICENSE
+    gpl-compatible: true
   js:
     assets/vendor/jquery-once/jquery.once.js: { weight: -19 }
   dependencies:
@@ -341,7 +385,11 @@ jquery.once:
 
 jquery.ui:
   remote: https://github.com/jquery/jquery-ui
-  version: &jquery_ui 1.10.2
+  version: &jquery_ui_version 1.10.2
+  license: &jquery_ui_license
+    name: MIT
+    url: https://github.com/jquery/jquery-ui/blob/1.10.2/MIT-LICENSE.txt
+    gpl-compatible: true
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.core.js: { weight: -11 }
   css:
@@ -353,7 +401,8 @@ jquery.ui:
     - core/jquery
 
 jquery.ui.accordion:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.accordion.js: {}
   css:
@@ -364,7 +413,8 @@ jquery.ui.accordion:
     - core/jquery.ui.widget
 
 jquery.ui.autocomplete:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.autocomplete.js: {}
   css:
@@ -377,7 +427,8 @@ jquery.ui.autocomplete:
     - core/jquery.ui.menu
 
 jquery.ui.button:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.button.js: {}
   css:
@@ -388,7 +439,8 @@ jquery.ui.button:
     - core/jquery.ui.widget
 
 jquery.ui.datepicker:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.datepicker.js: {}
   css:
@@ -398,7 +450,8 @@ jquery.ui.datepicker:
     - core/jquery.ui
 
 jquery.ui.dialog:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.dialog.js: {}
   css:
@@ -414,7 +467,8 @@ jquery.ui.dialog:
     - core/jquery.ui.resizable
 
 jquery.ui.draggable:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.draggable.js: {}
   dependencies:
@@ -423,7 +477,8 @@ jquery.ui.draggable:
     - core/jquery.ui.widget
 
 jquery.ui.droppable:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.droppable.js: {}
   dependencies:
@@ -433,103 +488,118 @@ jquery.ui.droppable:
     - core/jquery.ui.draggable
 
 jquery.ui.effects.core:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.core.js: { weight: -9 }
 
 jquery.ui.effects.blind:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.blind.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.bounce:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.bounce.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.clip:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.clip.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.drop:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.drop.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.explode:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.explode.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.fade:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.fade.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.fold:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.fold.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.highlight:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.highlight.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.pulsate:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.pulsate.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.scale:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.scale.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.shake:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.shake.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.slide:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.slide.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.effects.transfer:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.effects.transfer.js: {}
   dependencies:
     - core/jquery.ui.effects.core
 
 jquery.ui.menu:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.menu.js: {}
   css:
@@ -540,19 +610,22 @@ jquery.ui.menu:
     - core/jquery.ui.widget
 
 jquery.ui.mouse:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.mouse.js: {}
   dependencies:
     - core/jquery.ui.widget
 
 jquery.ui.position:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.position.js: {}
 
 jquery.ui.progressbar:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.progressbar.js: {}
   css:
@@ -563,7 +636,8 @@ jquery.ui.progressbar:
     - core/jquery.ui.widget
 
 jquery.ui.resizable:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.resizable.js: {}
   css:
@@ -575,7 +649,8 @@ jquery.ui.resizable:
     - core/jquery.ui.mouse
 
 jquery.ui.selectable:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.selectable.js: {}
   css:
@@ -587,7 +662,8 @@ jquery.ui.selectable:
     - core/jquery.ui.widget
 
 jquery.ui.slider:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.slider.js: {}
   css:
@@ -599,7 +675,8 @@ jquery.ui.slider:
     - core/jquery.ui.widget
 
 jquery.ui.sortable:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.sortable.js: {}
   dependencies:
@@ -608,7 +685,8 @@ jquery.ui.sortable:
     - core/jquery.ui.widget
 
 jquery.ui.spinner:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.spinner.js: {}
   dependencies:
@@ -617,7 +695,8 @@ jquery.ui.spinner:
     - core/jquery.ui.button
 
 jquery.ui.tabs:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.tabs.js: {}
   css:
@@ -628,7 +707,8 @@ jquery.ui.tabs:
     - core/jquery.ui.widget
 
 jquery.ui.tooltip:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.tooltip.js: {}
   css:
@@ -642,13 +722,18 @@ jquery.ui.tooltip:
 jquery.ui.touch-punch:
   remote: https://github.com/furf/jquery-ui-touch-punch
   version: 0.2.2
+  license:
+    name: GNU-GPL-2.0-or-later
+    url: https://github.com/furf/jquery-ui-touch-punch
+    gpl-compatible: true
   js:
     assets/vendor/jquery-ui-touch-punch/jquery.ui.touch-punch.js: {}
   dependencies:
     - core/jquery.ui
 
 jquery.ui.widget:
-  version: *jquery_ui
+  version: *jquery_ui_version
+  license: *jquery_ui_license
   js:
     assets/vendor/jquery.ui/ui/jquery.ui.widget.js: { weight: -10 }
   dependencies:
@@ -659,6 +744,10 @@ matchmedia:
   # @todo Contribute upstream and replace with upstream version.
   # @see http://drupal.org/node/1815602
   version: VERSION
+  license:
+    name: MIT
+    url: https://github.com/paulirish/matchMedia.js/blob/0.1.0/LICENSE.txt
+    gpl-compatible: true
   js:
     misc/matchmedia.js: {}
   dependencies:
@@ -666,6 +755,10 @@ matchmedia:
 
 modernizr:
   remote: https://github.com/Modernizr/Modernizr
+  license:
+    name: MIT
+    url: http://modernizr.com/license/
+    gpl-compatible: true
   version: v2.6.2
   js:
     assets/vendor/modernizr/modernizr.min.js: { every_page: true, preprocess: 0, scope: header, weight: -21 }
@@ -673,6 +766,10 @@ modernizr:
 normalize:
   remote: https://github.com/necolas/normalize.css
   version: 3.0.1
+  license:
+    name: MIT
+    url: https://github.com/necolas/normalize.css/blob/master/LICENSE.md
+    gpl-compatible: true
   css:
     base:
       assets/vendor/normalize-css/normalize.css: { every_page: true, weight: -20 }
@@ -682,6 +779,10 @@ picturefill:
   # @todo Contribute upstream and/or replace with upstream version.
   # @see https://drupal.org/node/1775530
   version: VERSION
+  license:
+    name: MIT
+    url: https://github.com/scottjehl/picturefill/blob/master/LICENSE
+    gpl-compatible: true
   js:
     assets/vendor/picturefill/picturefill.js: { weight: -10 }
   dependencies:
@@ -690,6 +791,9 @@ picturefill:
 underscore:
   remote: https://github.com/jashkenas/underscore
   version: 1.5.2
+  license:
+    name: MIT
+    url: https://github.com/jashkenas/underscore/blob/1.5.2/LICENSE
+    gpl-compatible: true
   js:
     assets/vendor/underscore/underscore.js: { weight: -20 }
-
diff --git a/core/lib/Drupal/Core/Asset/Exception/LibraryDefinitionMissingLicenseException.php b/core/lib/Drupal/Core/Asset/Exception/LibraryDefinitionMissingLicenseException.php
new file mode 100644
index 000000000000..2ed2c7089fca
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/Exception/LibraryDefinitionMissingLicenseException.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException.
+ */
+
+namespace Drupal\Core\Asset\Exception;
+
+/**
+ * Defines a custom exception if a library has a remote but no license.
+ */
+class LibraryDefinitionMissingLicenseException extends \RuntimeException {
+
+}
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index cbe26209030f..37291612face 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException;
 use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
+use Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
 use Drupal\Component\Serialization\Yaml;
@@ -87,6 +88,20 @@ public function buildByExtension($extension) {
         }
       }
 
+      // If this is a 3rd party library, the license info is required.
+      if (isset($library['remote']) && !isset($library['license'])) {
+        throw new LibraryDefinitionMissingLicenseException(sprintf("Missing license information in library definition for '%s' in %s: it has a remote, but no license.", $id, $library_file));
+      }
+
+      // Assign Drupal's license to libraries that don't have license info.
+      if (!isset($library['license'])) {
+        $library['license'] = array(
+          'name' => 'GNU-GPL-2.0-or-later',
+          'url' => 'https://drupal.org/licensing/faq',
+          'gpl-compatible' => TRUE,
+        );
+      }
+
       foreach (array('js', 'css') as $type) {
         // Prepare (flatten) the SMACSS-categorized definitions.
         // @todo After Asset(ic) changes, retain the definitions as-is and
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index 15b323dd8497..e1126cc7a5cf 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -346,6 +346,112 @@ public function testLibraryWithDataTypes() {
     $this->assertEquals('public://test.css', $library['css'][3]['data']);
   }
 
+  /**
+   * Tests that an exception is thrown when license is missing when 3rd party.
+   *
+   * @expectedException \Drupal\Core\Asset\Exception\LibraryDefinitionMissingLicenseException
+   * @expectedExceptionMessage Missing license information in library definition for 'no-license-info-but-remote' in core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses_missing_information.libraries.yml: it has a remote, but no license.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testLibraryThirdPartyWithMissingLicense() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('licenses_missing_information')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscoveryParser->setPaths('module', 'licenses_missing_information', $path);
+
+    $this->libraryDiscoveryParser->buildByExtension('licenses_missing_information');
+  }
+
+  /**
+   * Tests a library with various licenses, some GPL-compatible, some not.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testLibraryWithLicenses() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('licenses')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscoveryParser->setPaths('module', 'licenses', $path);
+
+    $libraries = $this->libraryDiscoveryParser->buildByExtension('licenses');
+
+
+    // For libraries without license info, the default license is applied.
+    $library = $libraries['no-license-info'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $this->assertTrue(isset($library['license']));
+    $default_license = array(
+      'name' => 'GNU-GPL-2.0-or-later',
+      'url' => 'https://drupal.org/licensing/faq',
+      'gpl-compatible' => TRUE,
+    );
+    $this->assertEquals($library['license'], $default_license);
+
+    // GPL2-licensed libraries.
+    $library = $libraries['gpl2'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $expected_license = array(
+      'name' => 'gpl2',
+      'url' => 'https://url-to-gpl2-license',
+      'gpl-compatible' => TRUE,
+    );
+    $this->assertEquals($library['license'], $expected_license);
+
+    // MIT-licensed libraries.
+    $library = $libraries['mit'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $expected_license = array(
+      'name' => 'MIT',
+      'url' => 'https://url-to-mit-license',
+      'gpl-compatible' => TRUE,
+    );
+    $this->assertEquals($library['license'], $expected_license);
+
+    // Libraries in the Public Domain.
+    $library = $libraries['public-domain'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $expected_license = array(
+      'name' => 'Public Domain',
+      'url' => 'https://url-to-public-domain-license',
+      'gpl-compatible' => TRUE,
+    );
+    $this->assertEquals($library['license'], $expected_license);
+
+    // Apache-licensed libraries.
+    $library = $libraries['apache'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $expected_license = array(
+      'name' => 'apache',
+      'url' => 'https://url-to-apache-license',
+      'gpl-compatible' => FALSE,
+    );
+    $this->assertEquals($library['license'], $expected_license);
+
+    // Copyrighted libraries.
+    $library = $libraries['copyright'];
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(1, $library['js']);
+    $expected_license = array(
+      'name' => '© Some company',
+      'gpl-compatible' => FALSE,
+    );
+    $this->assertEquals($library['license'], $expected_license);
+  }
+
 }
 
 /**
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses.libraries.yml
new file mode 100644
index 000000000000..455b4c59d126
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses.libraries.yml
@@ -0,0 +1,72 @@
+# No license information: should default to GPL 2.0 or later..
+no-license-info:
+  version: 1.0
+  js:
+    no-license-info.js: {}
+  css:
+    base:
+      no-license-info.css: {}
+
+# A library with all assets licensed under the GPL-compatible GPL 2 license.
+gpl2:
+  version: 1.0
+  license:
+    name: gpl2
+    url: https://url-to-gpl2-license
+    gpl-compatible: true
+  js:
+    gpl2.js: {}
+  css:
+    base:
+      gpl2.css: {}
+
+# A library with all assets licensed under the GPL-compatible MIT license.
+mit:
+  version: 1.0
+  license:
+    name: MIT
+    url: https://url-to-mit-license
+    gpl-compatible: true
+  js:
+    mit.js: {}
+  css:
+    base:
+      mit.css: {}
+
+# A library with all assets licensed under the GPL-compatible Public Domain.
+public-domain:
+  version: 1.0
+  license:
+    name: Public Domain
+    url: https://url-to-public-domain-license
+    gpl-compatible: true
+  js:
+    public-domain.js: {}
+  css:
+    base:
+      public-domain.css: {}
+
+# A library with all assets licensed under the GPL-incompatible Apache license.
+apache:
+  version: 1.0
+  license:
+    name: apache
+    url: https://url-to-apache-license
+    gpl-compatible: false
+  js:
+    apache.js: {}
+  css:
+    base:
+      apache.css: {}
+
+# A library with all assets licensed under the GPL-incompatible copyright.
+copyright:
+  version: 1.0
+  license:
+    name: © Some company
+    gpl-compatible: false
+  js:
+    copyright.js: {}
+  css:
+    base:
+      copyright.css: {}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses_missing_information.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses_missing_information.libraries.yml
new file mode 100644
index 000000000000..f36d0611f9ef
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/licenses_missing_information.libraries.yml
@@ -0,0 +1,9 @@
+# No license information for a 3rd party library (it has the 'remote' key).
+no-license-info-but-remote:
+  version: 1.0
+  remote: https://url-to-remote
+  js:
+    no-license-info-but-remote.js: {}
+  css:
+    base:
+      no-license-info-but-remote.css: {}
-- 
GitLab