Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/static_src/elements/chops/chops-announcement/chops-announcement.js b/static_src/elements/chops/chops-announcement/chops-announcement.js
index 477e7d2..5d5a9d6 100644
--- a/static_src/elements/chops/chops-announcement/chops-announcement.js
+++ b/static_src/elements/chops/chops-announcement/chops-announcement.js
@@ -1,8 +1,13 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {LitElement, html, css} from 'lit-element';
+import { LitElement, html, css } from 'lit-element';
+import 'elements/framework/mr-comment-content/mr-comment-content.js';
+
+import { connectStore } from 'reducers/base.js';
+import * as projectV0 from 'reducers/projectV0.js';
+import * as userV0 from 'reducers/userV0.js';
 
 // URL where announcements are fetched from.
 const ANNOUNCEMENT_SERVICE =
@@ -20,9 +25,25 @@
 export const REFRESH_TIME_MS = 5 * 60 * 1000;
 
 /**
+ * @type {Array<Announcement>} A list of hardcodded announcements for Monorail.
+ */
+export const HARDCODED_ANNOUNCEMENTS = [{
+  "messageContent": "The Chromium project will be migrating to Buganizer on " +
+    " February 5  (go/chrome-buganizer). Please test your workflows for this " +
+    "transition with these instructions: go/cob-buv-quick-start",
+  "projects": ["chromium"],
+  "groups": ["everyone@google.com", "googlers@chromium.org"],
+}];
+
+/**
  * @typedef {Object} Announcement
- * @property {string} id
+ * @property {string=} id
  * @property {string} messageContent
+ * @property {Array<string>=} projects Monorail extension for hard-coded
+ *    announcements. Specifies the names of projects the announcement will
+ *    occur in.
+ * @property {Array<string>=} groups Monorail extension for hard-coded
+ *    announcements. Specifies email groups the announces will show up in.
  */
 
 /**
@@ -36,7 +57,7 @@
  *
  * @customElement chops-announcement
  */
-export class ChopsAnnouncement extends LitElement {
+class _ChopsAnnouncement extends LitElement {
   /** @override */
   static get styles() {
     return css`
@@ -44,7 +65,7 @@
         display: block;
         width: 100%;
       }
-      p {
+      mr-comment-content {
         display: block;
         color: #222;
         font-size: 13px;
@@ -65,17 +86,29 @@
       return html`<p><strong>Error: </strong>${this._error}</p>`;
     }
     return html`
-      ${this._announcements.map(
-      ({messageContent}) => html`<p>${messageContent}</p>`)}
+      ${this._processedAnnouncements().map(
+      ({ messageContent }) => html`
+          <mr-comment-content
+            .content=${messageContent}>
+          </mr-comment-content>`)}
     `;
   }
 
   /** @override */
   static get properties() {
     return {
-      service: {type: String},
-      _error: {type: String},
-      _announcements: {type: Array},
+      service: { type: String },
+      additionalAnnouncements: { type: Array },
+
+      // Properties from the currently logged in user, usually feched through
+      // Redux.
+      currentUserName: { type: String },
+      userGroups: { type: Array },
+      currentProject: { type: String },
+
+      // Private properties managing state from requests to Chops Dash.
+      _error: { type: String },
+      _announcements: { type: Array },
     };
   }
 
@@ -85,6 +118,13 @@
 
     /** @type {string} */
     this.service = undefined;
+    /** @type {Array<Announcement>} */
+    this.additionalAnnouncements = HARDCODED_ANNOUNCEMENTS;
+
+    this.currentUserName = '';
+    this.userGroups = [];
+    this.currentProject = '';
+
     /** @type {string} */
     this._error = undefined;
     /** @type {Array<Announcement>} */
@@ -135,12 +175,12 @@
    */
   async refresh() {
     try {
-      const {announcements = []} = await this.fetch(this.service);
+      const { announcements = [] } = await this.fetch(this.service);
       this._error = undefined;
       this._announcements = announcements;
     } catch (e) {
       this._error = e.message;
-      this._announcements = [];
+      this._announcements = HARDCODED_ANNOUNCEMENTS;
     }
   }
 
@@ -176,6 +216,64 @@
 
     return JSON.parse(text.substr(XSSI_PREFIX.length));
   }
+
+  _processedAnnouncements() {
+    const announcements = [...this.additionalAnnouncements, ...this._announcements];
+
+    // Only show announcements relevant to the project the user is viewing and
+    // the group the user is part of, if applicable.
+    return announcements.filter(({ groups, projects }) => {
+      if (groups && groups.length && !this._isUserInGroups(groups,
+        this.userGroups, this.currentUserName)) {
+        return false;
+      }
+      if (projects && projects.length && !this._isViewingProject(projects,
+        this.currentProject)) {
+        return false;
+      }
+      return true;
+    });
+  }
+
+  /**
+   * Helper to check if the user is a member of the allowed groups.
+   * @param {Array<string>} allowedGroups
+   * @param {Array<{{userId: string, displayName: string}}>} userGroups
+   * @param {string} userEmail
+   */
+  _isUserInGroups(allowedGroups, userGroups, userEmail) {
+    const userGroupSet = new Set(userGroups.map(
+        ({ displayName }) => displayName.toLowerCase()));
+    return allowedGroups.find((group) => {
+      group = group.toLowerCase();
+
+      // Handle custom groups in Monorail like everyone@google.com
+      if (group.startsWith('everyone@')) {
+        let [_, suffix] = group.split('@');
+        suffix = '@' + suffix;
+        return userEmail.endsWith(suffix);
+      }
+
+      return userGroupSet.has(group);
+    });
+  }
+
+  _isViewingProject(projects, currentProject) {
+    return projects.find((project = "") => project.toLowerCase() === currentProject.toLowerCase());
+  }
 }
 
+/** Redux-connected version of _ChopsAnnouncement. */
+export class ChopsAnnouncement extends connectStore(_ChopsAnnouncement) {
+  /** @override */
+  stateChanged(state) {
+    const { displayName, groups } = userV0.currentUser(state);
+    this.currentUserName = displayName;
+    this.userGroups = groups;
+
+    this.currentProject = projectV0.viewedProjectName(state);
+  }
+}
+
+customElements.define('chops-announcement-base', _ChopsAnnouncement);
 customElements.define('chops-announcement', ChopsAnnouncement);
diff --git a/static_src/elements/chops/chops-announcement/chops-announcement.test.js b/static_src/elements/chops/chops-announcement/chops-announcement.test.js
index fa9643f..bed36f5 100644
--- a/static_src/elements/chops/chops-announcement/chops-announcement.test.js
+++ b/static_src/elements/chops/chops-announcement/chops-announcement.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
@@ -9,11 +9,22 @@
 let element;
 let clock;
 
+function assertRendersMessage(message) {
+  const messageContainer = element.shadowRoot.querySelector('mr-comment-content');
+  assert.include(messageContainer.content, message);
+}
+
+function assertDoesNotRender() {
+  assert.equal(0, element.shadowRoot.children.length);
+}
+
 describe('chops-announcement', () => {
   beforeEach(() => {
-    element = document.createElement('chops-announcement');
+    element = document.createElement('chops-announcement-base');
     document.body.appendChild(element);
 
+    element.additionalAnnouncements = [];
+
     clock = sinon.useFakeTimers({
       now: new Date(0),
       shouldAdvanceTime: false,
@@ -32,10 +43,6 @@
     window.fetch.restore();
   });
 
-  it('initializes', () => {
-    assert.instanceOf(element, ChopsAnnouncement);
-  });
-
   it('does not request announcements when no service specified', async () => {
     sinon.stub(element, 'fetch');
 
@@ -139,7 +146,8 @@
 
     assert.deepEqual(element._announcements,
         [{id: '1234', messageContent: 'test thing'}]);
-    assert.include(element.shadowRoot.textContent, 'test thing');
+
+    assertRendersMessage('test thing');
   });
 
   it('renders empty on empty announcement', async () => {
@@ -154,7 +162,7 @@
     await element.updateComplete;
 
     assert.deepEqual(element._announcements, []);
-    assert.equal(0, element.shadowRoot.children.length);
+    assertDoesNotRender()
   });
 
   it('fetch returns response data', async () => {
@@ -191,4 +199,85 @@
           'Something went wrong while fetching announcements');
     }
   });
+
+  describe('additional announcement handlings', () => {
+    beforeEach(() => {
+      sinon.stub(element, 'fetch');
+      element.fetch.returns({});
+      element.service = 'monorail';
+    });
+
+    it('renders additional announcement', async () => {
+      element.additionalAnnouncements = [{'messageContent': 'test thing'}];
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('renders when user is in group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['hello@group.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@group.com"}];
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not render when user is not in group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['hello@group.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@othergroup.com"}];
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+
+    it('renders when user is in everyone@ group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['everyone@world.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@group.com"}];
+      element.currentUserName = "hello@world.com";
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not renders when user is not in everyone@ group', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'groups': ['everyone@word.com']}
+      ];
+      element.userGroups = [
+        {"userId": "12344", "displayName": "hello@world.com"}];
+      element.currentUserName = "hello@world.com";
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+
+    it('renders when viewing referenced project', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'projects': ['chromium']}];
+      element.currentProject = 'chromium';
+
+      await element.updateComplete;
+
+      assertRendersMessage('test thing');
+    });
+
+    it('does not render when not viewing referenced project', async () => {
+      element.additionalAnnouncements = [
+        {'messageContent': 'test thing', 'projects': ['chromium']}];
+      element.currentProject = 'chrome';
+
+      await element.updateComplete;
+
+      assertDoesNotRender();
+    });
+  });
 });
diff --git a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
index dab8f85..974cadd 100644
--- a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
+++ b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
index e470312..75df329 100644
--- a/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
+++ b/static_src/elements/chops/chops-autocomplete/chops-autocomplete.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-button/chops-button.js b/static_src/elements/chops/chops-button/chops-button.js
index 2139e22..0172d27 100644
--- a/static_src/elements/chops/chops-button/chops-button.js
+++ b/static_src/elements/chops/chops-button/chops-button.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-button/chops-button.test.js b/static_src/elements/chops/chops-button/chops-button.test.js
index 4487564..56ddea7 100644
--- a/static_src/elements/chops/chops-button/chops-button.test.js
+++ b/static_src/elements/chops/chops-button/chops-button.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-checkbox/chops-checkbox.js b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
index d752347..b8be2ee 100644
--- a/static_src/elements/chops/chops-checkbox/chops-checkbox.js
+++ b/static_src/elements/chops/chops-checkbox/chops-checkbox.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js b/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
index 5a11111..12e50be 100644
--- a/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
+++ b/static_src/elements/chops/chops-checkbox/chops-checkbox.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-chip/chops-chip.js b/static_src/elements/chops/chops-chip/chops-chip.js
index ce8319e..b99c8f3 100644
--- a/static_src/elements/chops/chops-chip/chops-chip.js
+++ b/static_src/elements/chops/chops-chip/chops-chip.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-chip/chops-chip.test.js b/static_src/elements/chops/chops-chip/chops-chip.test.js
index 843000b..ce012b4 100644
--- a/static_src/elements/chops/chops-chip/chops-chip.test.js
+++ b/static_src/elements/chops/chops-chip/chops-chip.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
index e300588..4176489 100644
--- a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
+++ b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
index e529735..58407f1 100644
--- a/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
+++ b/static_src/elements/chops/chops-choice-buttons/chops-choice-buttons.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 import {assert} from 'chai';
diff --git a/static_src/elements/chops/chops-collapse/chops-collapse.js b/static_src/elements/chops/chops-collapse/chops-collapse.js
index 0df3e21..de71d7e 100644
--- a/static_src/elements/chops/chops-collapse/chops-collapse.js
+++ b/static_src/elements/chops/chops-collapse/chops-collapse.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-collapse/chops-collapse.test.js b/static_src/elements/chops/chops-collapse/chops-collapse.test.js
index 7058b65..80dcd8e 100644
--- a/static_src/elements/chops/chops-collapse/chops-collapse.test.js
+++ b/static_src/elements/chops/chops-collapse/chops-collapse.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-dialog/chops-dialog.js b/static_src/elements/chops/chops-dialog/chops-dialog.js
index 0d40aa2..0f4e488 100644
--- a/static_src/elements/chops/chops-dialog/chops-dialog.js
+++ b/static_src/elements/chops/chops-dialog/chops-dialog.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-dialog/chops-dialog.test.js b/static_src/elements/chops/chops-dialog/chops-dialog.test.js
index 376496a..c8f75e8 100644
--- a/static_src/elements/chops/chops-dialog/chops-dialog.test.js
+++ b/static_src/elements/chops/chops-dialog/chops-dialog.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
index 3bcc0c6..3f9193a 100644
--- a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
+++ b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
index 3fd2671..4836927 100644
--- a/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
+++ b/static_src/elements/chops/chops-filter-chips/chops-filter-chips.test.js
@@ -1,4 +1,4 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
+// Copyright 2020 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-snackbar/chops-snackbar.js b/static_src/elements/chops/chops-snackbar/chops-snackbar.js
index aea71b8..01857df 100644
--- a/static_src/elements/chops/chops-snackbar/chops-snackbar.js
+++ b/static_src/elements/chops/chops-snackbar/chops-snackbar.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js b/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
index fa45d68..ee9450c 100644
--- a/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
+++ b/static_src/elements/chops/chops-snackbar/chops-snackbar.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
index 2fa1dc2..baa96ac 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
index 5fe344b..5f42a6f 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp-helpers.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp.js b/static_src/elements/chops/chops-timestamp/chops-timestamp.js
index b7f157f..dbd7529 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js b/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
index 21c227d..fcd9e81 100644
--- a/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
+++ b/static_src/elements/chops/chops-timestamp/chops-timestamp.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-toggle/chops-toggle.js b/static_src/elements/chops/chops-toggle/chops-toggle.js
index 52868bd..608373a 100644
--- a/static_src/elements/chops/chops-toggle/chops-toggle.js
+++ b/static_src/elements/chops/chops-toggle/chops-toggle.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
diff --git a/static_src/elements/chops/chops-toggle/chops-toggle.test.js b/static_src/elements/chops/chops-toggle/chops-toggle.test.js
index 423c993..5a1c333 100644
--- a/static_src/elements/chops/chops-toggle/chops-toggle.test.js
+++ b/static_src/elements/chops/chops-toggle/chops-toggle.test.js
@@ -1,4 +1,4 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
+// Copyright 2019 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.