From d4541ec4293cc1d429f440a1fd1dcbb298d468a8 Mon Sep 17 00:00:00 2001
From: Sergei Zharinov <zharinov@users.noreply.github.com>
Date: Thu, 28 Apr 2022 13:14:47 +0300
Subject: [PATCH] refactor(pr): Extract labels-related code to separate file
 (#15352)

---
 lib/workers/repository/onboarding/pr/index.ts |   7 +-
 .../repository/update/pr/automerge.spec.ts    |   5 +
 .../repository/update/pr/index.spec.ts        | 157 ------------------
 lib/workers/repository/update/pr/index.ts     |  12 +-
 .../repository/update/pr/labels.spec.ts       |  80 +++++++++
 lib/workers/repository/update/pr/labels.ts    |  12 ++
 6 files changed, 100 insertions(+), 173 deletions(-)
 create mode 100644 lib/workers/repository/update/pr/labels.spec.ts
 create mode 100644 lib/workers/repository/update/pr/labels.ts

diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index 8efa0695c2..e0423a12b6 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -12,11 +12,8 @@ import {
 } from '../../../../util/git';
 import * as template from '../../../../util/template';
 import type { BranchConfig } from '../../../types';
-import {
-  addAssigneesReviewers,
-  getPlatformPrOptions,
-  prepareLabels,
-} from '../../update/pr';
+import { addAssigneesReviewers, getPlatformPrOptions } from '../../update/pr';
+import { prepareLabels } from '../../update/pr/labels';
 import { getBaseBranchDesc } from './base-branch';
 import { getConfigDesc } from './config-description';
 import { getDepWarnings, getErrors, getWarnings } from './errors-warnings';
diff --git a/lib/workers/repository/update/pr/automerge.spec.ts b/lib/workers/repository/update/pr/automerge.spec.ts
index adf095f1a2..8152155531 100644
--- a/lib/workers/repository/update/pr/automerge.spec.ts
+++ b/lib/workers/repository/update/pr/automerge.spec.ts
@@ -26,6 +26,11 @@ describe('workers/repository/update/pr/automerge', () => {
       jest.clearAllMocks();
     });
 
+    it('should not automerge if not configured', async () => {
+      await prAutomerge.checkAutoMerge(pr, config);
+      expect(platform.mergePr).toHaveBeenCalledTimes(0);
+    });
+
     it('should automerge if enabled and pr is mergeable', async () => {
       config.automerge = true;
       config.pruneBranchAfterAutomerge = true;
diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts
index ab25a757b1..d6dbf7d49f 100644
--- a/lib/workers/repository/update/pr/index.spec.ts
+++ b/lib/workers/repository/update/pr/index.spec.ts
@@ -10,7 +10,6 @@ import type { Pr } from '../../../../modules/platform';
 import { BranchStatus } from '../../../../types';
 import * as _limits from '../../../global/limits';
 import type { BranchConfig } from '../../../types';
-import * as prAutomerge from './automerge';
 import * as _changelogHelper from './changelog';
 import type { ChangeLogResult } from './changelog';
 import * as codeOwners from './code-owners';
@@ -116,85 +115,6 @@ function isResultWithoutPr(
 }
 
 describe('workers/repository/update/pr/index', () => {
-  describe('checkAutoMerge(pr, config)', () => {
-    let config: BranchConfig;
-    let pr: Pr;
-
-    beforeEach(() => {
-      config = partial<BranchConfig>({
-        ...getConfig(),
-      });
-      pr = partial<Pr>({});
-    });
-
-    afterEach(() => {
-      jest.clearAllMocks();
-    });
-
-    it('should not automerge if not configured', async () => {
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should automerge if enabled and pr is mergeable', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      platform.mergePr.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(1);
-    });
-
-    it('should automerge comment', async () => {
-      config.automerge = true;
-      config.automergeType = 'pr-comment';
-      config.automergeComment = '!merge';
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0);
-      expect(platform.ensureComment).toHaveBeenCalledTimes(1);
-    });
-
-    it('should remove previous automerge comment when rebasing', async () => {
-      config.automerge = true;
-      config.automergeType = 'pr-comment';
-      config.automergeComment = '!merge';
-      config.rebaseRequested = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(1);
-      expect(platform.ensureComment).toHaveBeenCalledTimes(1);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
-      git.isBranchModified.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but branch status is not success', async () => {
-      config.automerge = true;
-      platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is mergeable but unstable', async () => {
-      config.automerge = true;
-      pr.cannotMergeReason = 'some reason';
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-
-    it('should not automerge if enabled and pr is unmergeable', async () => {
-      config.automerge = true;
-      git.isBranchConflicted.mockResolvedValueOnce(true);
-      await prAutomerge.checkAutoMerge(pr, config);
-      expect(platform.mergePr).toHaveBeenCalledTimes(0);
-    });
-  });
-
   describe('ensurePr', () => {
     let config: BranchConfig;
     // TODO fix type
@@ -871,81 +791,4 @@ describe('workers/repository/update/pr/index', () => {
       });
     });
   });
-
-  describe('prepareLabels(config)', () => {
-    it('returns empty array if no labels are configured', () => {
-      const result = prWorker.prepareLabels({});
-      expect(result).toBeArrayOfSize(0);
-    });
-
-    it('only labels', () => {
-      const result = prWorker.prepareLabels({ labels: ['labelA', 'labelB'] });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('only addLabels', () => {
-      const result = prWorker.prepareLabels({
-        addLabels: ['labelA', 'labelB'],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('merge labels and addLabels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', 'labelB'],
-        addLabels: ['labelC'],
-      });
-      expect(result).toBeArrayOfSize(3);
-      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
-    });
-
-    it('deduplicate merged labels and addLabels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', 'labelB'],
-        addLabels: ['labelB', 'labelC'],
-      });
-      expect(result).toBeArrayOfSize(3);
-      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
-    });
-
-    it('empty labels ignored', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', ''],
-        addLabels: [' ', 'labelB'],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('null labels ignored', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['labelA', null],
-        // an empty space between two commas in an array is categorized as a null value
-        // eslint-disable-next-line no-sparse-arrays
-        addLabels: ['labelB', '', undefined, , ,],
-      });
-      expect(result).toBeArrayOfSize(2);
-      expect(result).toEqual(['labelA', 'labelB']);
-    });
-
-    it('template labels', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['datasource-{{{datasource}}}'],
-        datasource: 'npm',
-      });
-      expect(result).toBeArrayOfSize(1);
-      expect(result).toEqual(['datasource-npm']);
-    });
-
-    it('template labels with empty datasource', () => {
-      const result = prWorker.prepareLabels({
-        labels: ['{{{datasource}}}', ' {{{datasource}}} '],
-        datasource: null,
-      });
-      expect(result).toBeArrayOfSize(0);
-      expect(result).toEqual([]);
-    });
-  });
 });
diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts
index ad81190bc2..e44e576a97 100644
--- a/lib/workers/repository/update/pr/index.ts
+++ b/lib/workers/repository/update/pr/index.ts
@@ -1,4 +1,3 @@
-import is from '@sindresorhus/is';
 import { GlobalConfig } from '../../../../config/global';
 import type { RenovateConfig } from '../../../../config/types';
 import {
@@ -15,7 +14,6 @@ import { sampleSize } from '../../../../util';
 import { stripEmojis } from '../../../../util/emoji';
 import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git';
 import { regEx } from '../../../../util/regex';
-import * as template from '../../../../util/template';
 import { Limit, incLimitedValue, isLimitReached } from '../../../global/limits';
 import type {
   BranchConfig,
@@ -26,6 +24,7 @@ import { resolveBranchStatus } from '../branch/status-checks';
 import { getPrBody } from './body';
 import { ChangeLogError } from './changelog/types';
 import { codeOwnersForPr } from './code-owners';
+import { prepareLabels } from './labels';
 
 function noWhitespaceOrHeadings(input: string): string {
   return input.replace(regEx(/\r?\n|\r|\s|#/g), '');
@@ -59,15 +58,6 @@ function prepareAssigneesReviewers(
   return filterUnavailableUsers(config, normalizedUsernames);
 }
 
-export function prepareLabels(config: RenovateConfig): string[] {
-  const labels = config.labels ?? [];
-  const addLabels = config.addLabels ?? [];
-  return [...new Set([...labels, ...addLabels])]
-    .filter(is.nonEmptyStringAndNotWhitespace)
-    .map((label) => template.compile(label, config))
-    .filter(is.nonEmptyStringAndNotWhitespace);
-}
-
 export async function addAssigneesReviewers(
   config: RenovateConfig,
   pr: Pr
diff --git a/lib/workers/repository/update/pr/labels.spec.ts b/lib/workers/repository/update/pr/labels.spec.ts
new file mode 100644
index 0000000000..60f5f8d315
--- /dev/null
+++ b/lib/workers/repository/update/pr/labels.spec.ts
@@ -0,0 +1,80 @@
+import { prepareLabels } from './labels';
+
+describe('workers/repository/update/pr/labels', () => {
+  describe('prepareLabels(config)', () => {
+    it('returns empty array if no labels are configured', () => {
+      const result = prepareLabels({});
+      expect(result).toBeArrayOfSize(0);
+    });
+
+    it('only labels', () => {
+      const result = prepareLabels({ labels: ['labelA', 'labelB'] });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('only addLabels', () => {
+      const result = prepareLabels({
+        addLabels: ['labelA', 'labelB'],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('merge labels and addLabels', () => {
+      const result = prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('deduplicate merged labels and addLabels', () => {
+      const result = prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelB', 'labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('empty labels ignored', () => {
+      const result = prepareLabels({
+        labels: ['labelA', ''],
+        addLabels: [' ', 'labelB'],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('null labels ignored', () => {
+      const result = prepareLabels({
+        labels: ['labelA', null],
+        // an empty space between two commas in an array is categorized as a null value
+        // eslint-disable-next-line no-sparse-arrays
+        addLabels: ['labelB', '', undefined, , ,],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('template labels', () => {
+      const result = prepareLabels({
+        labels: ['datasource-{{{datasource}}}'],
+        datasource: 'npm',
+      });
+      expect(result).toBeArrayOfSize(1);
+      expect(result).toEqual(['datasource-npm']);
+    });
+
+    it('template labels with empty datasource', () => {
+      const result = prepareLabels({
+        labels: ['{{{datasource}}}', ' {{{datasource}}} '],
+        datasource: null,
+      });
+      expect(result).toBeArrayOfSize(0);
+      expect(result).toEqual([]);
+    });
+  });
+});
diff --git a/lib/workers/repository/update/pr/labels.ts b/lib/workers/repository/update/pr/labels.ts
new file mode 100644
index 0000000000..df04f80125
--- /dev/null
+++ b/lib/workers/repository/update/pr/labels.ts
@@ -0,0 +1,12 @@
+import is from '@sindresorhus/is';
+import type { RenovateConfig } from '../../../../config/types';
+import * as template from '../../../../util/template';
+
+export function prepareLabels(config: RenovateConfig): string[] {
+  const labels = config.labels ?? [];
+  const addLabels = config.addLabels ?? [];
+  return [...new Set([...labels, ...addLabels])]
+    .filter(is.nonEmptyStringAndNotWhitespace)
+    .map((label) => template.compile(label, config))
+    .filter(is.nonEmptyStringAndNotWhitespace);
+}
-- 
GitLab