summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-12 09:14:57 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-12 09:14:57 +0000
commit60e7627c998b74d48df10b9a7759d6038a1f139c (patch)
tree9b643b2e776ea868f4e1546cf1f1fd40bbb10e0f /spec
parent913af9b06edd2eff6cba93b1daca6c061b93be91 (diff)
downloadgitlab-ce-60e7627c998b74d48df10b9a7759d6038a1f139c.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/fixtures/security_reports/feature-branch/gl-sast-report.json22
-rw-r--r--spec/fixtures/security_reports/feature-branch/gl-secret-detection-report.json36
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-missing-scanner.json52
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-bandit.json13
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-gosec.json13
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-minimal.json18
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-bandit.json13
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-gosec.json13
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-multiple-findings.json13
-rw-r--r--spec/fixtures/security_reports/master/gl-sast-report.json22
-rw-r--r--spec/fixtures/security_reports/master/gl-secret-detection-report.json35
-rw-r--r--spec/frontend/issues/show/components/description_spec.js19
-rw-r--r--spec/frontend/issues/show/mock_data/mock_data.js13
-rw-r--r--spec/frontend/security_configuration/components/feature_card_spec.js101
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view_spec.js30
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_widget/mock_data.js11
-rw-r--r--spec/graphql/types/permission_types/work_item_spec.rb3
-rw-r--r--spec/initializers/net_http_patch_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/components/instance_path_spec.rb31
-rw-r--r--spec/lib/gitlab/ci/parsers/security/sast_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb2
-rw-r--r--spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb66
-rw-r--r--spec/models/ci/catalog/resource_spec.rb26
-rw-r--r--spec/requests/api/graphql/work_item_spec.rb3
24 files changed, 522 insertions, 43 deletions
diff --git a/spec/fixtures/security_reports/feature-branch/gl-sast-report.json b/spec/fixtures/security_reports/feature-branch/gl-sast-report.json
index 083042e19ff..f153192fed7 100644
--- a/spec/fixtures/security_reports/feature-branch/gl-sast-report.json
+++ b/spec/fixtures/security_reports/feature-branch/gl-sast-report.json
@@ -1,7 +1,8 @@
{
- "version": "14.0.0",
+ "version": "15.0.0",
"vulnerabilities": [
{
+ "id": "1",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -29,6 +30,7 @@
]
},
{
+ "id": "2",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -56,6 +58,7 @@
]
},
{
+ "id": "3",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@@ -90,6 +93,7 @@
]
},
{
+ "id": "4",
"category": "sast",
"name": "Hard coded key",
"message": "Hard coded key",
@@ -124,6 +128,7 @@
]
},
{
+ "id": "5",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@@ -158,8 +163,19 @@
]
}
],
- "remediations": [],
+ "remediations": [
+
+ ],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@@ -174,4 +190,4 @@
"start_time": "2022-08-10T22:37:00",
"end_time": "2022-08-10T22:38:00"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/feature-branch/gl-secret-detection-report.json b/spec/fixtures/security_reports/feature-branch/gl-secret-detection-report.json
index 4862a504cec..c75b9bfb9de 100644
--- a/spec/fixtures/security_reports/feature-branch/gl-secret-detection-report.json
+++ b/spec/fixtures/security_reports/feature-branch/gl-secret-detection-report.json
@@ -1,5 +1,33 @@
{
- "version": "14.1.2",
- "vulnerabilities": [],
- "remediations": []
-} \ No newline at end of file
+ "version": "15.0.0",
+ "vulnerabilities": [
+
+ ],
+ "remediations": [
+
+ ],
+ "scan": {
+ "analyzer": {
+ "id": "secret_detection_analyzer",
+ "name": "Secret Detection Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
+ "scanner": {
+ "id": "secret_detection",
+ "name": "Secret Detection",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "0.1.0"
+ },
+ "type": "sast",
+ "start_time": "2022-03-11T18:48:16",
+ "end_time": "2022-03-11T18:48:22",
+ "status": "success"
+ }
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-missing-scanner.json b/spec/fixtures/security_reports/master/gl-sast-missing-scanner.json
index fcfd9b831f4..16d02490156 100644
--- a/spec/fixtures/security_reports/master/gl-sast-missing-scanner.json
+++ b/spec/fixtures/security_reports/master/gl-sast-missing-scanner.json
@@ -1,7 +1,23 @@
{
- "version": "14.1.2",
+ "version": "15.0.0",
+ "scan": {
+ "analyzer": {
+ "id": "sast_analyzer",
+ "name": "SAST Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
+ "type": "sast",
+ "start_time": "2022-03-11T18:48:16",
+ "end_time": "2022-03-11T18:48:22",
+ "status": "success"
+ },
"vulnerabilities": [
{
+ "id": "1",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108",
@@ -26,6 +42,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
+ "id": "2",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -53,6 +70,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
},
{
+ "id": "3",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -80,6 +98,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
},
{
+ "id": "4",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
@@ -102,6 +121,7 @@
"line": 11
},
{
+ "id": "5",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303",
@@ -124,6 +144,7 @@
"line": 12
},
{
+ "id": "6",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303",
@@ -146,6 +167,7 @@
"line": 13
},
{
+ "id": "6",
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303",
@@ -168,6 +190,7 @@
"line": 14
},
{
+ "id": "7",
"category": "sast",
"message": "Pickle library appears to be in use, possible security issue.",
"cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301",
@@ -190,6 +213,7 @@
"line": 15
},
{
+ "id": "8",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@@ -217,6 +241,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE"
},
{
+ "id": "9",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@@ -244,6 +269,7 @@
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
},
{
+ "id": "10",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108",
@@ -268,6 +294,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
+ "id": "11",
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
@@ -292,6 +319,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
},
{
+ "id": "12",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404",
@@ -314,6 +342,7 @@
"line": 1
},
{
+ "id": "13",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403",
@@ -336,6 +365,7 @@
"line": 2
},
{
+ "id": "14",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404",
@@ -358,6 +388,7 @@
"line": 4
},
{
+ "id": "15",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106",
@@ -382,6 +413,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html"
},
{
+ "id": "16",
"category": "sast",
"message": "Possible hardcoded password: 'root'",
"cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105",
@@ -406,6 +438,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
+ "id": "17",
"category": "sast",
"message": "Possible hardcoded password: ''",
"cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105",
@@ -430,6 +463,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
+ "id": "18",
"category": "sast",
"message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'",
"cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105",
@@ -454,6 +488,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
+ "id": "19",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105",
@@ -478,6 +513,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
+ "id": "20",
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105",
@@ -502,6 +538,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
},
{
+ "id": "21",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404",
@@ -524,6 +561,7 @@
"line": 4
},
{
+ "id": "22",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403",
@@ -546,6 +584,7 @@
"line": 2
},
{
+ "id": "23",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404",
@@ -568,6 +607,7 @@
"line": 7
},
{
+ "id": "24",
"category": "sast",
"message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell",
"cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602",
@@ -592,6 +632,7 @@
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html"
},
{
+ "id": "25",
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404",
@@ -614,6 +655,7 @@
"line": 6
},
{
+ "id": "26",
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404",
@@ -636,6 +678,7 @@
"line": 1
},
{
+ "id": "27",
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403",
@@ -658,6 +701,7 @@
"line": 7
},
{
+ "id": "28",
"category": "sast",
"message": "Consider possible security implications associated with loads module.",
"cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403",
@@ -680,6 +724,7 @@
"line": 6
},
{
+ "id": "29",
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120",
@@ -713,6 +758,7 @@
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
+ "id": "30",
"category": "sast",
"message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)",
"cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362",
@@ -739,6 +785,7 @@
"url": "https://cwe.mitre.org/data/definitions/362.html"
},
{
+ "id": "31",
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120",
@@ -772,6 +819,7 @@
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
+ "id": "32",
"category": "sast",
"message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)",
"cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120",
@@ -799,4 +847,4 @@
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
]
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-bandit.json b/spec/fixtures/security_reports/master/gl-sast-report-bandit.json
index d0346479b85..690c58d049b 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-bandit.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-bandit.json
@@ -1,5 +1,5 @@
{
- "version": "14.0.4",
+ "version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@@ -26,6 +26,15 @@
}
],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "bandit",
"name": "Bandit",
@@ -40,4 +49,4 @@
"end_time": "2022-03-11T00:21:50",
"status": "success"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-gosec.json b/spec/fixtures/security_reports/master/gl-sast-report-gosec.json
index 4c385326c8c..ef1d06d2e4f 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-gosec.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-gosec.json
@@ -1,5 +1,5 @@
{
- "version": "14.0.4",
+ "version": "15.0.4",
"vulnerabilities": [
{
"id": "2e5656ff30e2e7cc93c36b4845c8a689ddc47fdbccf45d834c67442fbaa89be0",
@@ -51,6 +51,15 @@
}
],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "gosec",
"name": "Gosec",
@@ -65,4 +74,4 @@
"end_time": "2022-03-15T20:33:17",
"status": "success"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-minimal.json b/spec/fixtures/security_reports/master/gl-sast-report-minimal.json
index 53d15224b30..d29571638ff 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-minimal.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-minimal.json
@@ -1,7 +1,8 @@
{
- "version": "14.0.0",
+ "version": "15.0.0",
"vulnerabilities": [
{
+ "id": "1",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@@ -49,8 +50,19 @@
}
}
],
- "remediations": [],
+ "remediations": [
+
+ ],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@@ -65,4 +77,4 @@
"start_time": "2022-08-10T21:37:00",
"end_time": "2022-08-10T21:38:00"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-bandit.json b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-bandit.json
index 037b9fb8d3e..c51abf46c13 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-bandit.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-bandit.json
@@ -1,5 +1,5 @@
{
- "version": "14.0.4",
+ "version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@@ -54,6 +54,15 @@
}
],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@@ -68,4 +77,4 @@
"end_time": "2022-03-11T18:48:22",
"status": "success"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-gosec.json b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-gosec.json
index 8fa85c30b56..9a6dd4190c5 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-gosec.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-gosec.json
@@ -1,5 +1,5 @@
{
- "version": "14.0.4",
+ "version": "15.0.4",
"vulnerabilities": [
{
"id": "79f6537b7ec83c7717f5bd1a4f12645916caafefe2e4359148d889855505aa67",
@@ -53,6 +53,15 @@
}
],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@@ -74,4 +83,4 @@
"end_time": "2022-03-15T20:37:05",
"status": "success"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-multiple-findings.json b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-multiple-findings.json
index cbdfdb86f6b..e3659c70710 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-multiple-findings.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report-semgrep-for-multiple-findings.json
@@ -1,5 +1,5 @@
{
- "version": "14.0.4",
+ "version": "15.0.4",
"vulnerabilities": [
{
"id": "985a5666dcae22adef5ac12f8a8a2dacf9b9b481ae5d87cd0ac1712b0fd64864",
@@ -104,6 +104,15 @@
}
],
"scan": {
+ "analyzer": {
+ "id": "semgrep_analyzer",
+ "name": "Semgrep Analyzer",
+ "url": "https://gitlab.com/",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "semgrep",
"name": "Semgrep",
@@ -131,4 +140,4 @@
"end_time": "2022-03-15T20:37:05",
"status": "success"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-sast-report.json b/spec/fixtures/security_reports/master/gl-sast-report.json
index 0ec31252e97..1bd1f241a6d 100644
--- a/spec/fixtures/security_reports/master/gl-sast-report.json
+++ b/spec/fixtures/security_reports/master/gl-sast-report.json
@@ -1,7 +1,8 @@
{
- "version": "14.0.0",
+ "version": "15.0.0",
"vulnerabilities": [
{
+ "id": "1_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -39,6 +40,7 @@
]
},
{
+ "id": "2_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
@@ -66,6 +68,7 @@
]
},
{
+ "id": "3_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
@@ -100,6 +103,7 @@
]
},
{
+ "id": "4_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Hard coded key",
"message": "Hard coded key",
@@ -134,6 +138,7 @@
]
},
{
+ "id": "5_481ae5d87cd0ac1712b0fd64864",
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
@@ -181,8 +186,19 @@
}
}
],
- "remediations": [],
+ "remediations": [
+
+ ],
"scan": {
+ "analyzer": {
+ "id": "find_sec_bugs_analyzer",
+ "name": "Find Security Bugs Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs",
@@ -197,4 +213,4 @@
"start_time": "2022-08-10T21:37:00",
"end_time": "2022-08-10T21:38:00"
}
-} \ No newline at end of file
+}
diff --git a/spec/fixtures/security_reports/master/gl-secret-detection-report.json b/spec/fixtures/security_reports/master/gl-secret-detection-report.json
index cb97b60ced1..43c079e8769 100644
--- a/spec/fixtures/security_reports/master/gl-secret-detection-report.json
+++ b/spec/fixtures/security_reports/master/gl-secret-detection-report.json
@@ -1,5 +1,29 @@
{
- "version": "14.1.2",
+ "version": "15.0.0",
+ "scan": {
+ "analyzer": {
+ "id": "secret_detection_analyzer",
+ "name": "Secret Detection Analyzer",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "1.0.0"
+ },
+ "scanner": {
+ "id": "secret_detection",
+ "name": "Secret Detection",
+ "url": "https://gitlab.com",
+ "vendor": {
+ "name": "GitLab"
+ },
+ "version": "0.1.0"
+ },
+ "type": "sast",
+ "start_time": "2022-03-11T18:48:16",
+ "end_time": "2022-03-11T18:48:22",
+ "status": "success"
+ },
"vulnerabilities": [
{
"id": "27d2322d519c94f803ffed1cf6d14e455df97e5a0668e229eb853fdb0d277d2c",
@@ -17,7 +41,8 @@
"location": {
"file": "aws-key.py",
"dependency": {
- "package": {}
+ "package": {
+ }
},
"commit": {
"sha": "e9c3a56590d5bed4155c0d128f1552d52fdcc7ae"
@@ -32,5 +57,7 @@
]
}
],
- "remediations": []
-} \ No newline at end of file
+ "remediations": [
+
+ ]
+}
diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js
index 4b7b363f5da..56057e9819f 100644
--- a/spec/frontend/issues/show/components/description_spec.js
+++ b/spec/frontend/issues/show/components/description_spec.js
@@ -19,7 +19,11 @@ import {
getIssueDetailsResponse,
projectWorkItemTypesQueryResponse,
} from 'jest/work_items/mock_data';
-import { descriptionProps as initialProps, descriptionHtmlWithList } from '../mock_data/mock_data';
+import {
+ descriptionProps as initialProps,
+ descriptionHtmlWithList,
+ descriptionHtmlWithDetailsTag,
+} from '../mock_data/mock_data';
jest.mock('~/alert');
jest.mock('~/task_list');
@@ -111,6 +115,19 @@ describe('Description component', () => {
expect(findGfmContent().classes()).toContain('issue-realtime-trigger-pulse');
});
+ it('doesnt animate expand/collapse of details elements', async () => {
+ createComponent();
+
+ await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
+ expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
+
+ await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.expanded });
+ expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
+
+ await wrapper.setProps({ descriptionHtml: descriptionHtmlWithDetailsTag.collapsed });
+ expect(findGfmContent().classes()).not.toContain('issue-realtime-pre-pulse');
+ });
+
it('applies syntax highlighting and math when description changed', async () => {
createComponent();
diff --git a/spec/frontend/issues/show/mock_data/mock_data.js b/spec/frontend/issues/show/mock_data/mock_data.js
index e923c0d97f4..ed969a08ac5 100644
--- a/spec/frontend/issues/show/mock_data/mock_data.js
+++ b/spec/frontend/issues/show/mock_data/mock_data.js
@@ -79,3 +79,16 @@ export const descriptionHtmlWithList = `
<li data-sourcepos="3:1-3:8">todo 3</li>
</ul>
`;
+
+export const descriptionHtmlWithDetailsTag = {
+ expanded: `
+ <details open="true">
+ <summary>Section 1</summary>
+ <p>Data</p>
+ </details>'`,
+ collapsed: `
+ <details>
+ <summary>Section 1</summary>
+ <p>Data</p>
+ </details>'`,
+};
diff --git a/spec/frontend/security_configuration/components/feature_card_spec.js b/spec/frontend/security_configuration/components/feature_card_spec.js
index 23edd8a69de..983a66a7fd3 100644
--- a/spec/frontend/security_configuration/components/feature_card_spec.js
+++ b/spec/frontend/security_configuration/components/feature_card_spec.js
@@ -1,10 +1,15 @@
import { GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { securityFeatures } from '~/security_configuration/components/constants';
import FeatureCard from '~/security_configuration/components/feature_card.vue';
import FeatureCardBadge from '~/security_configuration/components/feature_card_badge.vue';
import ManageViaMr from '~/vue_shared/security_configuration/components/manage_via_mr.vue';
-import { REPORT_TYPE_SAST } from '~/vue_shared/security_reports/constants';
+import {
+ REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION,
+ REPORT_TYPE_SAST,
+ REPORT_TYPE_SAST_IAC,
+} from '~/vue_shared/security_reports/constants';
import { manageViaMRErrorMessage } from '../constants';
import { makeFeature } from './utils';
@@ -265,6 +270,56 @@ describe('FeatureCard component', () => {
expect(links.exists()).toBe(false);
});
});
+
+ describe('given an available secondary with a configuration guide', () => {
+ beforeEach(() => {
+ feature = makeFeature({
+ available: true,
+ configurationHelpPath: null,
+ secondary: {
+ name: 'secondary name',
+ description: 'secondary description',
+ configurationHelpPath: '/secondary',
+ configurationText: null,
+ },
+ });
+ createComponent({ feature });
+ });
+
+ it('shows the secondary action', () => {
+ const links = findLinks({
+ text: 'Configuration guide',
+ href: feature.secondary.configurationHelpPath,
+ });
+ expect(links.exists()).toBe(true);
+ expect(links).toHaveLength(1);
+ });
+ });
+
+ describe('given an unavailable secondary with a configuration guide', () => {
+ beforeEach(() => {
+ feature = makeFeature({
+ available: false,
+ configurationHelpPath: null,
+ secondary: {
+ name: 'secondary name',
+ description: 'secondary description',
+ configurationHelpPath: '/secondary',
+ configurationText: null,
+ },
+ });
+ createComponent({ feature });
+ });
+
+ it('does not show the secondary action', () => {
+ const links = findLinks({
+ text: 'Configuration guide',
+ href: feature.secondary.configurationHelpPath,
+ });
+ expect(links.exists()).toBe(false);
+ expect(links).toHaveLength(0);
+ });
+ });
});
describe('information badge', () => {
@@ -290,4 +345,48 @@ describe('FeatureCard component', () => {
});
});
});
+
+ describe('status and badge', () => {
+ describe.each`
+ context | available | configured | expectedStatus
+ ${'configured BAS feature'} | ${true} | ${true} | ${null}
+ ${'unavailable BAS feature'} | ${false} | ${false} | ${'Available with Ultimate'}
+ ${'unconfigured BAS feature'} | ${true} | ${false} | ${null}
+ `('given $context', ({ available, configured, expectedStatus }) => {
+ beforeEach(() => {
+ const securityFeature = securityFeatures.find(
+ ({ type }) => REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION === type,
+ );
+ feature = { ...securityFeature, available, configured };
+ createComponent({ feature });
+ });
+
+ it('should show an incubating feature badge', () => {
+ expect(findBadge().exists()).toBe(true);
+ });
+
+ if (expectedStatus) {
+ it(`should show the status "${expectedStatus}"`, () => {
+ expect(wrapper.findByTestId('feature-status').text()).toBe(expectedStatus);
+ });
+ }
+ });
+
+ describe.each`
+ context | available | configured
+ ${'configured SAST IaC feature'} | ${true} | ${true}
+ ${'unavailable SAST IaC feature'} | ${false} | ${false}
+ ${'unconfigured SAST IaC feature'} | ${true} | ${false}
+ `('given $context', ({ available, configured }) => {
+ beforeEach(() => {
+ const securityFeature = securityFeatures.find(({ type }) => REPORT_TYPE_SAST_IAC === type);
+ feature = { ...securityFeature, available, configured };
+ createComponent({ feature });
+ });
+
+ it(`should not show a status`, () => {
+ expect(wrapper.findByTestId('feature-status').exists()).toBe(false);
+ });
+ });
+ });
});
diff --git a/spec/frontend/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view_spec.js
index 4ca0a813da2..9c8d9656955 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view_spec.js
@@ -8,11 +8,13 @@ import { createAlert } from '~/alert';
import { workspaceLabelsQueries } from '~/sidebar/constants';
import DropdownContentsCreateView from '~/sidebar/components/labels/labels_select_widget/dropdown_contents_create_view.vue';
import createLabelMutation from '~/sidebar/components/labels/labels_select_widget/graphql/create_label.mutation.graphql';
+import { DEFAULT_LABEL_COLOR } from '~/sidebar/components/labels/labels_select_widget/constants';
import {
mockRegularLabel,
mockSuggestedColors,
createLabelSuccessfulResponse,
workspaceLabelsQueryResponse,
+ workspaceLabelsQueryEmptyResponse,
} from './mock_data';
jest.mock('~/alert');
@@ -61,14 +63,16 @@ describe('DropdownContentsCreateView', () => {
mutationHandler = createLabelSuccessHandler,
labelCreateType = 'project',
workspaceType = 'project',
+ labelsResponse = workspaceLabelsQueryResponse,
+ searchTerm = '',
} = {}) => {
const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]);
mockApollo.clients.defaultClient.cache.writeQuery({
query: workspaceLabelsQueries[workspaceType].query,
- data: workspaceLabelsQueryResponse.data,
+ data: labelsResponse.data,
variables: {
fullPath: '',
- searchTerm: '',
+ searchTerm,
},
});
@@ -94,7 +98,7 @@ describe('DropdownContentsCreateView', () => {
it('selects a color after clicking on colored block', async () => {
createComponent();
- expect(findSelectedColor().attributes('style')).toBeUndefined();
+ expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
await nextTick();
@@ -104,7 +108,7 @@ describe('DropdownContentsCreateView', () => {
it('shows correct color hex code after selecting a color', async () => {
createComponent();
- expect(findSelectedColorText().attributes('value')).toBe('');
+ expect(findSelectedColorText().attributes('value')).toBe(DEFAULT_LABEL_COLOR);
findAllColors().at(0).vm.$emit('click', new Event('mouseclick'));
await nextTick();
@@ -123,6 +127,7 @@ describe('DropdownContentsCreateView', () => {
it('disables a Create button if color is not set', async () => {
createComponent();
findLabelTitleInput().vm.$emit('input', 'Test title');
+ findSelectedColorText().vm.$emit('input', '');
await nextTick();
expect(findCreateButton().props('disabled')).toBe(true);
@@ -232,4 +237,21 @@ describe('DropdownContentsCreateView', () => {
titleTakenError.data.labelCreate.errors[0],
);
});
+
+ describe('when empty labels response', () => {
+ it('is able to create label with searched text when empty response', async () => {
+ createComponent({ searchTerm: '', labelsResponse: workspaceLabelsQueryEmptyResponse });
+
+ findLabelTitleInput().vm.$emit('input', 'random');
+
+ findCreateButton().vm.$emit('click');
+ await waitForPromises();
+
+ expect(createLabelSuccessHandler).toHaveBeenCalledWith({
+ color: DEFAULT_LABEL_COLOR,
+ projectPath: '',
+ title: 'random',
+ });
+ });
+ });
});
diff --git a/spec/frontend/sidebar/components/labels/labels_select_widget/mock_data.js b/spec/frontend/sidebar/components/labels/labels_select_widget/mock_data.js
index 5d5a7e9a200..b0b473625bb 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_widget/mock_data.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_widget/mock_data.js
@@ -117,6 +117,17 @@ export const workspaceLabelsQueryResponse = {
},
};
+export const workspaceLabelsQueryEmptyResponse = {
+ data: {
+ workspace: {
+ id: 'gid://gitlab/Project/126',
+ labels: {
+ nodes: [],
+ },
+ },
+ },
+};
+
export const issuableLabelsQueryResponse = {
data: {
workspace: {
diff --git a/spec/graphql/types/permission_types/work_item_spec.rb b/spec/graphql/types/permission_types/work_item_spec.rb
index db6d78b1538..72e9dad3bea 100644
--- a/spec/graphql/types/permission_types/work_item_spec.rb
+++ b/spec/graphql/types/permission_types/work_item_spec.rb
@@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe Types::PermissionTypes::WorkItem do
it do
expected_permissions = [
- :read_work_item, :update_work_item, :delete_work_item, :admin_work_item
+ :read_work_item, :update_work_item, :delete_work_item, :admin_work_item,
+ :admin_parent_link
]
expected_permissions.each do |permission|
diff --git a/spec/initializers/net_http_patch_spec.rb b/spec/initializers/net_http_patch_spec.rb
index d56730917f1..82f896e1fa7 100644
--- a/spec/initializers/net_http_patch_spec.rb
+++ b/spec/initializers/net_http_patch_spec.rb
@@ -8,6 +8,12 @@ require_relative '../../config/initializers/net_http_patch'
RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
let(:net_http) { Net::HTTP.new('hostname.example') }
+ before do
+ # This file can be removed once Ruby 3.0 is no longer supported:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/396223
+ skip if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new(3.1)
+ end
+
describe '#proxy_user' do
subject { net_http.proxy_user }
diff --git a/spec/lib/gitlab/ci/components/instance_path_spec.rb b/spec/lib/gitlab/ci/components/instance_path_spec.rb
index fbe5e0b9d42..e037c37c817 100644
--- a/spec/lib/gitlab/ci/components/instance_path_spec.rb
+++ b/spec/lib/gitlab/ci/components/instance_path_spec.rb
@@ -98,6 +98,37 @@ RSpec.describe Gitlab::Ci::Components::InstancePath, feature_category: :pipeline
end
end
+ context 'when version is `~latest`' do
+ let(:version) { '~latest' }
+
+ context 'when project is a catalog resource' do
+ before do
+ create(:catalog_resource, project: existing_project)
+ end
+
+ context 'when project has releases' do
+ let_it_be(:releases) do
+ [
+ create(:release, project: existing_project, sha: 'sha-1', released_at: Time.zone.now - 1.day),
+ create(:release, project: existing_project, sha: 'sha-2', released_at: Time.zone.now)
+ ]
+ end
+
+ it 'returns the sha of the latest release' do
+ expect(path.sha).to eq(releases.last.sha)
+ end
+ end
+
+ context 'when project does not have releases' do
+ it { expect(path.sha).to be_nil }
+ end
+ end
+
+ context 'when project is not a catalog resource' do
+ it { expect(path.sha).to be_nil }
+ end
+ end
+
context 'when project does not exist' do
let(:project_path) { 'non-existent/project' }
diff --git a/spec/lib/gitlab/ci/parsers/security/sast_spec.rb b/spec/lib/gitlab/ci/parsers/security/sast_spec.rb
index f6113308201..d1ce6808d23 100644
--- a/spec/lib/gitlab/ci/parsers/security/sast_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/sast_spec.rb
@@ -13,8 +13,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Sast do
context "when passing valid report" do
# rubocop: disable Layout/LineLength
where(:report_format, :report_version, :scanner_length, :finding_length, :identifier_length, :file_path, :start_line, :end_line, :primary_identifiers_length) do
- :sast | '14.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
- :sast_semgrep_for_multiple_findings | '14.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
+ :sast | '15.0.0' | 1 | 5 | 6 | 'groovy/src/main/java/com/gitlab/security_products/tests/App.groovy' | 47 | 47 | nil
+ :sast_semgrep_for_multiple_findings | '15.0.4' | 1 | 2 | 6 | 'app/app.py' | 39 | nil | 2
end
# rubocop: enable Layout/LineLength
diff --git a/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb b/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
index e8f1d617cb7..13999b2a9e5 100644
--- a/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/secret_detection_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::SecretDetection do
end
it "generates expected metadata_version" do
- expect(report.findings.first.metadata_version).to eq('14.1.2')
+ expect(report.findings.first.metadata_version).to eq('15.0.0')
end
end
end
diff --git a/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb b/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
new file mode 100644
index 00000000000..467f09ba8bd
--- /dev/null
+++ b/spec/migrations/swap_issue_user_mentions_note_id_to_bigint_for_gitlab_dot_com_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapIssueUserMentionsNoteIdToBigintForGitlabDotCom, feature_category: :database do
+ describe '#up' do
+ before do
+ # A we call `schema_migrate_down!` before each example, and for this migration
+ # `#down` is same as `#up`, we need to ensure we start from the expected state.
+ connection = described_class.new.connection
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute('ALTER TABLE issue_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ end
+
+ # rubocop: disable RSpec/AnyInstanceOf
+ it 'swaps the integer and bigint columns for GitLab.com, dev, or test' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(true)
+
+ user_mentions = table(:issue_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('integer')
+ }
+ end
+ end
+ end
+
+ it 'is a no-op for other instances' do
+ allow_any_instance_of(described_class).to receive(:com_or_dev_or_test_but_not_jh?).and_return(false)
+
+ user_mentions = table(:issue_user_mentions)
+
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+
+ migration.after -> {
+ user_mentions.reset_column_information
+
+ expect(user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to eq('bigint')
+ }
+ end
+ end
+ end
+ # rubocop: enable RSpec/AnyInstanceOf
+ end
+end
diff --git a/spec/models/ci/catalog/resource_spec.rb b/spec/models/ci/catalog/resource_spec.rb
index 1a699fcd842..a239bbad857 100644
--- a/spec/models/ci/catalog/resource_spec.rb
+++ b/spec/models/ci/catalog/resource_spec.rb
@@ -3,6 +3,17 @@
require 'spec_helper'
RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:resource) { create(:catalog_resource, project: project) }
+
+ let_it_be(:releases) do
+ [
+ create(:release, project: project, released_at: Time.zone.now - 2.days),
+ create(:release, project: project, released_at: Time.zone.now - 1.day),
+ create(:release, project: project, released_at: Time.zone.now)
+ ]
+ end
+
it { is_expected.to belong_to(:project) }
it { is_expected.to delegate_method(:avatar_path).to(:project) }
@@ -11,12 +22,21 @@ RSpec.describe Ci::Catalog::Resource, feature_category: :pipeline_composition do
describe '.for_projects' do
it 'returns catalog resources for the given project IDs' do
- project = create(:project)
- resource = create(:catalog_resource, project: project)
-
resources_for_projects = described_class.for_projects(project.id)
expect(resources_for_projects).to contain_exactly(resource)
end
end
+
+ describe '#versions' do
+ it 'returns releases ordered by released date descending' do
+ expect(resource.versions).to eq(releases.reverse)
+ end
+ end
+
+ describe '#latest_version' do
+ it 'returns the latest release' do
+ expect(resource.latest_version).to eq(releases.last)
+ end
+ end
end
diff --git a/spec/requests/api/graphql/work_item_spec.rb b/spec/requests/api/graphql/work_item_spec.rb
index a89c2268208..4ef1ab03574 100644
--- a/spec/requests/api/graphql/work_item_spec.rb
+++ b/spec/requests/api/graphql/work_item_spec.rb
@@ -59,7 +59,8 @@ RSpec.describe 'Query.work_item(id)', feature_category: :team_planning do
'readWorkItem' => true,
'updateWorkItem' => true,
'deleteWorkItem' => false,
- 'adminWorkItem' => true
+ 'adminWorkItem' => true,
+ 'adminParentLink' => true
},
'project' => hash_including('id' => project.to_gid.to_s, 'fullPath' => project.full_path)
)