Running with gitlab-runner 14.5.2 (e91107dd)
  on blue-2.private.runners-manager.gitlab.com/gitlab.com/gitlab-org QvBVRoXM
  feature flags: FF_USE_FASTZIP:true
section_start:1639445120:resolve_secrets
Resolving secrets
section_end:1639445120:resolve_secrets
section_start:1639445120:prepare_executor
Preparing the "docker+machine" executor
Using Docker executor with image registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 ...
Starting service postgres:12 ...
Pulling docker image postgres:12 ...
Using docker image sha256:f1a5e4852a8c335ef0f1a3aae30c39c8484660d5aa7dfd5bb8756ee473575da5 for postgres:12 with digest postgres@sha256:0854202db0b3378c46909bab43a85b01dc1b92cc44520480e47dd4fbc22714ee ...
Starting service redis:5.0-alpine ...
Pulling docker image redis:5.0-alpine ...
Using docker image sha256:1746b159f8934fe63cae3984643ee8c5651bcfc80ae107032a60f2871a0e7cdb for redis:5.0-alpine with digest redis@sha256:a04b57e05b784a406bc818f6b450233328c4115a1e1f104d84ce916eb1583925 ...
Waiting for services to be up and running...
Authenticating with credentials from job payload (GitLab Registry)
Pulling docker image registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 ...
Using docker image sha256:5b9920187fd97abe77ba8b8a3c8029b970dbace758fd2dc8756c2976a4bff96d for registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 with digest registry.gitlab.com/gitlab-org/gitlab-build-images@sha256:4ab23b0728c6791b71363fe9413ab1d284f8d163988ebd8823dfb84f31aafe00 ...
section_end:1639445128:prepare_executor
section_start:1639445128:prepare_script
Preparing environment
Running on runner-qvbvroxm-project-278964-concurrent-0 via runner-qvbvroxm-private-1639434189-3b095954...
section_end:1639445129:prepare_script
section_start:1639445129:get_sources
Getting source from Git repository
$ eval "$CI_PRE_CLONE_SCRIPT"
Fetching changes with git depth set to 20...
Initialized empty Git repository in /builds/gitlab-org/gitlab/.git/
Created fresh repository.
remote: Enumerating objects: 91326, done.        
remote: Counting objects:   0% (1/91326)        
remote: Counting objects:   1% (914/91326)        
remote: Counting objects:   2% (1827/91326)        
remote: Counting objects:   3% (2740/91326)        
remote: Counting objects:   4% (3654/91326)        
remote: Counting objects:   5% (4567/91326)        
remote: Counting objects:   6% (5480/91326)        
remote: Counting objects:   7% (6393/91326)        
remote: Counting objects:   8% (7307/91326)        
remote: Counting objects:   9% (8220/91326)        
remote: Counting objects:  10% (9133/91326)        
remote: Counting objects:  11% (10046/91326)        
remote: Counting objects:  12% (10960/91326)        
remote: Counting objects:  13% (11873/91326)        
remote: Counting objects:  14% (12786/91326)        
remote: Counting objects:  15% (13699/91326)        
remote: Counting objects:  16% (14613/91326)        
remote: Counting objects:  17% (15526/91326)        
remote: Counting objects:  18% (16439/91326)        
remote: Counting objects:  19% (17352/91326)        
remote: Counting objects:  20% (18266/91326)        
remote: Counting objects:  21% (19179/91326)        
remote: Counting objects:  22% (20092/91326)        
remote: Counting objects:  23% (21005/91326)        
remote: Counting objects:  24% (21919/91326)        
remote: Counting objects:  25% (22832/91326)        
remote: Counting objects:  26% (23745/91326)        
remote: Counting objects:  27% (24659/91326)        
remote: Counting objects:  28% (25572/91326)        
remote: Counting objects:  29% (26485/91326)        
remote: Counting objects:  30% (27398/91326)        
remote: Counting objects:  31% (28312/91326)        
remote: Counting objects:  32% (29225/91326)        
remote: Counting objects:  33% (30138/91326)        
remote: Counting objects:  34% (31051/91326)        
remote: Counting objects:  35% (31965/91326)        
remote: Counting objects:  36% (32878/91326)        
remote: Counting objects:  37% (33791/91326)        
remote: Counting objects:  38% (34704/91326)        
remote: Counting objects:  39% (35618/91326)        
remote: Counting objects:  40% (36531/91326)        
remote: Counting objects:  41% (37444/91326)        
remote: Counting objects:  42% (38357/91326)        
remote: Counting objects:  43% (39271/91326)        
remote: Counting objects:  44% (40184/91326)        
remote: Counting objects:  45% (41097/91326)        
remote: Counting objects:  46% (42010/91326)        
remote: Counting objects:  47% (42924/91326)        
remote: Counting objects:  48% (43837/91326)        
remote: Counting objects:  49% (44750/91326)        
remote: Counting objects:  50% (45663/91326)        
remote: Counting objects:  51% (46577/91326)        
remote: Counting objects:  52% (47490/91326)        
remote: Counting objects:  53% (48403/91326)        
remote: Counting objects:  54% (49317/91326)        
remote: Counting objects:  55% (50230/91326)        
remote: Counting objects:  56% (51143/91326)        
remote: Counting objects:  57% (52056/91326)        
remote: Counting objects:  58% (52970/91326)        
remote: Counting objects:  59% (53883/91326)        
remote: Counting objects:  60% (54796/91326)        
remote: Counting objects:  61% (55709/91326)        
remote: Counting objects:  62% (56623/91326)        
remote: Counting objects:  63% (57536/91326)        
remote: Counting objects:  64% (58449/91326)        
remote: Counting objects:  65% (59362/91326)        
remote: Counting objects:  66% (60276/91326)        
remote: Counting objects:  67% (61189/91326)        
remote: Counting objects:  68% (62102/91326)        
remote: Counting objects:  69% (63015/91326)        
remote: Counting objects:  70% (63929/91326)        
remote: Counting objects:  71% (64842/91326)        
remote: Counting objects:  72% (65755/91326)        
remote: Counting objects:  73% (66668/91326)        
remote: Counting objects:  74% (67582/91326)        
remote: Counting objects:  75% (68495/91326)        
remote: Counting objects:  76% (69408/91326)        
remote: Counting objects:  77% (70322/91326)        
remote: Counting objects:  78% (71235/91326)        
remote: Counting objects:  79% (72148/91326)        
remote: Counting objects:  80% (73061/91326)        
remote: Counting objects:  81% (73975/91326)        
remote: Counting objects:  82% (74888/91326)        
remote: Counting objects:  83% (75801/91326)        
remote: Counting objects:  84% (76714/91326)        
remote: Counting objects:  85% (77628/91326)
remote: Counting objects:  86% (78541/91326)        
remote: Counting objects:  87% (79454/91326)        
remote: Counting objects:  88% (80367/91326)        
remote: Counting objects:  89% (81281/91326)        
remote: Counting objects:  90% (82194/91326)        
remote: Counting objects:  91% (83107/91326)        
remote: Counting objects:  92% (84020/91326)        
remote: Counting objects:  93% (84934/91326)        
remote: Counting objects:  94% (85847/91326)        
remote: Counting objects:  95% (86760/91326)        
remote: Counting objects:  96% (87673/91326)        
remote: Counting objects:  97% (88587/91326)        
remote: Counting objects:  98% (89500/91326)        
remote: Counting objects:  99% (90413/91326)        
remote: Counting objects: 100% (91326/91326)        
remote: Counting objects: 100% (91326/91326), done.        
remote: Compressing objects:   0% (1/68267)        
remote: Compressing objects:   1% (683/68267)        
remote: Compressing objects:   2% (1366/68267)        
remote: Compressing objects:   3% (2049/68267)        
remote: Compressing objects:   4% (2731/68267)        
remote: Compressing objects:   5% (3414/68267)        
remote: Compressing objects:   6% (4097/68267)        
remote: Compressing objects:   7% (4779/68267)        
remote: Compressing objects:   8% (5462/68267)        
remote: Compressing objects:   9% (6145/68267)        
remote: Compressing objects:   9% (6690/68267)
remote: Compressing objects:  10% (6827/68267)        
remote: Compressing objects:  11% (7510/68267)        
remote: Compressing objects:  12% (8193/68267)        
remote: Compressing objects:  13% (8875/68267)        
remote: Compressing objects:  14% (9558/68267)        
remote: Compressing objects:  15% (10241/68267)        
remote: Compressing objects:  16% (10923/68267)        
remote: Compressing objects:  17% (11606/68267)        
remote: Compressing objects:  18% (12289/68267)        
remote: Compressing objects:  19% (12971/68267)        
remote: Compressing objects:  20% (13654/68267)        
remote: Compressing objects:  21% (14337/68267)        
remote: Compressing objects:  21% (14547/68267)        
remote: Compressing objects:  22% (15019/68267)        
remote: Compressing objects:  23% (15702/68267)        
remote: Compressing objects:  24% (16385/68267)        
remote: Compressing objects:  25% (17067/68267)        
remote: Compressing objects:  26% (17750/68267)        
remote: Compressing objects:  27% (18433/68267)        
remote: Compressing objects:  28% (19115/68267)        
remote: Compressing objects:  29% (19798/68267)        
remote: Compressing objects:  30% (20481/68267)        
remote: Compressing objects:  31% (21163/68267)        
remote: Compressing objects:  32% (21846/68267)        
remote: Compressing objects:  33% (22529/68267)        
remote: Compressing objects:  34% (23211/68267)        
remote: Compressing objects:  35% (23894/68267)        
remote: Compressing objects:  36% (24577/68267)        
remote: Compressing objects:  37% (25259/68267)        
remote: Compressing objects:  38% (25942/68267)        
remote: Compressing objects:  39% (26625/68267)        
remote: Compressing objects:  40% (27307/68267)        
remote: Compressing objects:  41% (27990/68267)        
remote: Compressing objects:  42% (28673/68267)        
remote: Compressing objects:  42% (29206/68267)        
remote: Compressing objects:  43% (29355/68267)        
remote: Compressing objects:  44% (30038/68267)        
remote: Compressing objects:  45% (30721/68267)        
remote: Compressing objects:  46% (31403/68267)        
remote: Compressing objects:  47% (32086/68267)        
remote: Compressing objects:  48% (32769/68267)        
remote: Compressing objects:  49% (33451/68267)        
remote: Compressing objects:  50% (34134/68267)        
remote: Compressing objects:  51% (34817/68267)        
remote: Compressing objects:  52% (35499/68267)        
remote: Compressing objects:  53% (36182/68267)        
remote: Compressing objects:  54% (36865/68267)        
remote: Compressing objects:  55% (37547/68267)        
remote: Compressing objects:  56% (38230/68267)        
remote: Compressing objects:  57% (38913/68267)        
remote: Compressing objects:  58% (39595/68267)        
remote: Compressing objects:  59% (40278/68267)        
remote: Compressing objects:  60% (40961/68267)        
remote: Compressing objects:  61% (41643/68267)        
remote: Compressing objects:  61% (42320/68267)        
remote: Compressing objects:  62% (42326/68267)        
remote: Compressing objects:  63% (43009/68267)        
remote: Compressing objects:  64% (43691/68267)        
remote: Compressing objects:  65% (44374/68267)        
remote: Compressing objects:  66% (45057/68267)        
remote: Compressing objects:  67% (45739/68267)        
remote: Compressing objects:  68% (46422/68267)        
remote: Compressing objects:  69% (47105/68267)        
remote: Compressing objects:  70% (47787/68267)        
remote: Compressing objects:  71% (48470/68267)        
remote: Compressing objects:  72% (49153/68267)        
remote: Compressing objects:  73% (49835/68267)        
remote: Compressing objects:  74% (50518/68267)        
remote: Compressing objects:  75% (51201/68267)        
remote: Compressing objects:  76% (51883/68267)        
remote: Compressing objects:  77% (52566/68267)        
remote: Compressing objects:  78% (53249/68267)        
remote: Compressing objects:  79% (53931/68267)        
remote: Compressing objects:  80% (54614/68267)        
remote: Compressing objects:  81% (55297/68267)        
remote: Compressing objects:  82% (55979/68267)        
remote: Compressing objects:  83% (56662/68267)        
remote: Compressing objects:  84% (57345/68267)        
remote: Compressing objects:  85% (58027/68267)        
remote: Compressing objects:  86% (58710/68267)        
remote: Compressing objects:  87% (59393/68267)        
remote: Compressing objects:  88% (60075/68267)        
remote: Compressing objects:  89% (60758/68267)        
remote: Compressing objects:  90% (61441/68267)        
remote: Compressing objects:  91% (62123/68267)        
remote: Compressing objects:  92% (62806/68267)        
remote: Compressing objects:  93% (63489/68267)        
remote: Compressing objects:  94% (64171/68267)        
remote: Compressing objects:  95% (64854/68267)        
remote: Compressing objects:  96% (65537/68267)        
remote: Compressing objects:  97% (66219/68267)        
remote: Compressing objects:  98% (66902/68267)        
remote: Compressing objects:  99% (67585/68267)        
remote: Compressing objects: 100% (68267/68267)        
remote: Compressing objects: 100% (68267/68267), done.        
Receiving objects:   0% (1/91326)
Receiving objects:   1% (914/91326)
Receiving objects:   2% (1827/91326)
Receiving objects:   3% (2740/91326)
Receiving objects:   4% (3654/91326)
Receiving objects:   5% (4567/91326)
Receiving objects:   6% (5480/91326)
Receiving objects:   7% (6393/91326)
Receiving objects:   8% (7307/91326)
Receiving objects:   9% (8220/91326)
Receiving objects:  10% (9133/91326)
Receiving objects:  11% (10046/91326)
Receiving objects:  12% (10960/91326)
Receiving objects:  13% (11873/91326)
Receiving objects:  14% (12786/91326)
Receiving objects:  15% (13699/91326)
Receiving objects:  16% (14613/91326)
Receiving objects:  17% (15526/91326)
Receiving objects:  18% (16439/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  19% (17352/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  20% (18266/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  21% (19179/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  22% (20092/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  23% (21005/91326), 13.54 MiB | 27.08 MiB/s
Receiving objects:  23% (21856/91326), 30.64 MiB | 30.64 MiB/s
Receiving objects:  24% (21919/91326), 30.64 MiB | 30.64 MiB/s
Receiving objects:  25% (22832/91326), 30.64 MiB | 30.64 MiB/s
Receiving objects:  26% (23745/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  27% (24659/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  28% (25572/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  29% (26485/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  30% (27398/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  31% (28312/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  32% (29225/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  33% (30138/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  34% (31051/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  35% (31965/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  36% (32878/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  37% (33791/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  38% (34704/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  39% (35618/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  40% (36531/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  41% (37444/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  42% (38357/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  43% (39271/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  44% (40184/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  45% (41097/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  46% (42010/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  46% (42192/91326), 50.28 MiB | 33.51 MiB/s
Receiving objects:  47% (42924/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  48% (43837/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  49% (44750/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  50% (45663/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  51% (46577/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  52% (47490/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  53% (48403/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  54% (49317/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  55% (50230/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  56% (51143/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  57% (52056/91326), 59.91 MiB | 29.95 MiB/s
Receiving objects:  58% (52970/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  59% (53883/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  60% (54796/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  61% (55709/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  62% (56623/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  63% (57536/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  64% (58449/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  65% (59362/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  66% (60276/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  67% (61189/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  68% (62102/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  69% (63015/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  70% (63929/91326), 76.22 MiB | 30.49 MiB/s
Receiving objects:  70% (64641/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  71% (64842/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  72% (65755/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  73% (66668/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  74% (67582/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  75% (68495/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  76% (69408/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  77% (70322/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  78% (71235/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  79% (72148/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  80% (73061/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  81% (73975/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  82% (74888/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  83% (75801/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  84% (76714/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  85% (77628/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  86% (78541/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  87% (79454/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  88% (80367/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  89% (81281/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  90% (82194/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  91% (83107/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  92% (84020/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  93% (84934/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  94% (85847/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  95% (86760/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  96% (87673/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  97% (88587/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects:  98% (89500/91326), 86.89 MiB | 28.96 MiB/s
remote: Total 91326 (delta 30507), reused 60832 (delta 19269), pack-reused 0        
Receiving objects:  99% (90413/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects: 100% (91326/91326), 86.89 MiB | 28.96 MiB/s
Receiving objects: 100% (91326/91326), 103.88 MiB | 29.96 MiB/s, done.
Resolving deltas:   0% (0/30507)
Resolving deltas:   1% (311/30507)
Resolving deltas:   2% (691/30507)
Resolving deltas:   3% (926/30507)
Resolving deltas:   4% (1383/30507)
Resolving deltas:   5% (1527/30507)
Resolving deltas:   6% (1831/30507)
Resolving deltas:   7% (2136/30507)
Resolving deltas:   8% (2448/30507)
Resolving deltas:   9% (2747/30507)
Resolving deltas:  10% (3056/30507)
Resolving deltas:  11% (3357/30507)
Resolving deltas:  12% (3661/30507)
Resolving deltas:  13% (3967/30507)
Resolving deltas:  14% (4272/30507)
Resolving deltas:  15% (4577/30507)
Resolving deltas:  16% (4886/30507)
Resolving deltas:  17% (5187/30507)
Resolving deltas:  18% (5492/30507)
Resolving deltas:  19% (5814/30507)
Resolving deltas:  20% (6103/30507)
Resolving deltas:  21% (6409/30507)
Resolving deltas:  22% (6776/30507)
Resolving deltas:  23% (7017/30507)
Resolving deltas:  24% (7323/30507)
Resolving deltas:  25% (7632/30507)
Resolving deltas:  26% (7964/30507)
Resolving deltas:  27% (8262/30507)
Resolving deltas:  28% (8560/30507)
Resolving deltas:  29% (8852/30507)
Resolving deltas:  30% (9164/30507)
Resolving deltas:  31% (9460/30507)
Resolving deltas:  32% (9843/30507)
Resolving deltas:  33% (10070/30507)
Resolving deltas:  34% (10373/30507)
Resolving deltas:  35% (10706/30507)
Resolving deltas:  36% (10989/30507)
Resolving deltas:  37% (11304/30507)
Resolving deltas:  38% (11594/30507)
Resolving deltas:  39% (11906/30507)
Resolving deltas:  40% (12311/30507)
Resolving deltas:  41% (12508/30507)
Resolving deltas:  42% (12815/30507)
Resolving deltas:  43% (13119/30507)
Resolving deltas:  44% (13424/30507)
Resolving deltas:  45% (13730/30507)
Resolving deltas:  46% (14034/30507)
Resolving deltas:  47% (14339/30507)
Resolving deltas:  48% (14644/30507)
Resolving deltas:  49% (14949/30507)
Resolving deltas:  50% (15256/30507)
Resolving deltas:  51% (15562/30507)
Resolving deltas:  52% (15873/30507)
Resolving deltas:  53% (16169/30507)
Resolving deltas:  54% (16474/30507)
Resolving deltas:  55% (16781/30507)
Resolving deltas:  56% (17088/30507)
Resolving deltas:  57% (17390/30507)
Resolving deltas:  58% (17696/30507)
Resolving deltas:  59% (18005/30507)
Resolving deltas:  60% (18305/30507)
Resolving deltas:  61% (18610/30507)
Resolving deltas:  62% (18916/30507)
Resolving deltas:  63% (19221/30507)
Resolving deltas:  64% (19528/30507)
Resolving deltas:  65% (19831/30507)
Resolving deltas:  66% (20135/30507)
Resolving deltas:  67% (20440/30507)
Resolving deltas:  68% (20923/30507)
Resolving deltas:  69% (21052/30507)
Resolving deltas:  70% (21360/30507)
Resolving deltas:  71% (21662/30507)
Resolving deltas:  72% (21971/30507)
Resolving deltas:  73% (22271/30507)
Resolving deltas:  74% (22577/30507)
Resolving deltas:  75% (22987/30507)
Resolving deltas:  76% (23188/30507)
Resolving deltas:  77% (23491/30507)
Resolving deltas:  78% (23798/30507)
Resolving deltas:  79% (24101/30507)
Resolving deltas:  80% (24494/30507)
Resolving deltas:  81% (24732/30507)
Resolving deltas:  82% (25019/30507)
Resolving deltas:  83% (25321/30507)
Resolving deltas:  84% (25634/30507)
Resolving deltas:  85% (25931/30507)
Resolving deltas:  86% (26237/30507)
Resolving deltas:  87% (26542/30507)
Resolving deltas:  88% (26847/30507)
Resolving deltas:  90% (27504/30507)
Resolving deltas:  91% (27943/30507)
Resolving deltas:  92% (28067/30507)
Resolving deltas:  93% (28383/30507)
Resolving deltas:  94% (28704/30507)
Resolving deltas:  95% (29117/30507)
Resolving deltas:  96% (29291/30507)
Resolving deltas:  97% (29592/30507)
Resolving deltas:  98% (29897/30507)
Resolving deltas:  99% (30202/30507)
Resolving deltas: 100% (30507/30507)
Resolving deltas: 100% (30507/30507), done.
From https://gitlab.com/gitlab-org/gitlab
 * [new ref]             74a38a79b62c49b1e9b89b9829f66b53abaed5a9 -> refs/pipelines/428803744
 * [new branch]          master     -> origin/master
Checking out 74a38a79 as master...

Skipping Git submodules setup
section_end:1639445149:get_sources
section_start:1639445149:restore_cache
Restoring cache
Checking cache for ruby-gems-v1-9...
cache.zip is up to date                            
Successfully extracted cache
Checking cache for gitaly-ruby-gems-v1-9...
cache.zip is up to date                            
Successfully extracted cache
section_end:1639445168:restore_cache
section_start:1639445168:download_artifacts
Downloading artifacts
Downloading artifacts for compile-test-assets (1880797874)...
Downloading artifacts from coordinator... ok        id=1880797874 responseStatus=200 OK token=HwSwMQAA
Downloading artifacts for detect-tests (1880797889)...
Downloading artifacts from coordinator... ok        id=1880797889 responseStatus=200 OK token=cosp53gX
Downloading artifacts for retrieve-tests-metadata (1880797899)...
Downloading artifacts from coordinator... ok        id=1880797899 responseStatus=200 OK token=mhRg1nsp
Downloading artifacts for setup-test-env (1880797883)...
Downloading artifacts from coordinator... ok        id=1880797883 responseStatus=200 OK token=eZ79kRQL
section_end:1639445185:download_artifacts
section_start:1639445185:step_script
Executing "step_script" stage of the job script
Using docker image sha256:5b9920187fd97abe77ba8b8a3c8029b970dbace758fd2dc8756c2976a4bff96d for registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-89-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36 with digest registry.gitlab.com/gitlab-org/gitlab-build-images@sha256:4ab23b0728c6791b71363fe9413ab1d284f8d163988ebd8823dfb84f31aafe00 ...
$ echo $FOSS_ONLY

$ [ "$FOSS_ONLY" = "1" ] && rm -rf ee/ qa/spec/ee/ qa/qa/specs/features/ee/ qa/qa/ee/ qa/qa/ee.rb
$ export GOPATH=$CI_PROJECT_DIR/.go
$ mkdir -p $GOPATH
$ source scripts/utils.sh
$ source scripts/prepare_build.sh
Bundler version 2.1.4
production:development
Settings are listed in order of priority. The top value will be used.
path
Set for the current user (/root/.bundle/config): "/builds/gitlab-org/gitlab/vendor"

clean
Set for the current user (/root/.bundle/config): "true"

without
Set via BUNDLE_WITHOUT: [:production, :development]

install_flags
Set via BUNDLE_INSTALL_FLAGS: "--jobs=$(nproc) --retry=3 --quiet"

$ bundle install --jobs=$(nproc) --retry=3 --quiet  && bundle check
The Gemfile's dependencies are satisfied
==> 'bundle install --jobs=$(nproc) --retry=3 --quiet  && bundle check' succeeded in 2 seconds.
$ bundle pristine pg
Installing pg 1.2.3 with native extensions
==> 'bundle pristine pg' succeeded in 10 seconds.
$ setup_db_user_only
CREATE ROLE
GRANT
==> 'setup_db_user_only' succeeded in 0 seconds.
$ bundle exec rake db:drop db:create db:structure:load db:migrate gitlab:db:setup_ee
Dropped database 'gitlabhq_test'
Dropped database 'gitlabhq_geo_test'
Created database 'gitlabhq_test'
Created database 'gitlabhq_geo_test'
DEPRECATION WARNING: Using `bin/rails db:structure:load` is deprecated and will be removed in Rails 6.2. Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead. (called from load at /builds/gitlab-org/gitlab/vendor/ruby/2.7.0/bin/rake:23)
Dropped database 'gitlabhq_geo_test'
Created database 'gitlabhq_geo_test'
==> 'bundle exec rake db:drop db:create db:structure:load db:migrate gitlab:db:setup_ee' succeeded in 30 seconds.
$ run_timed_command "gem install knapsack --no-document"
$ gem install knapsack --no-document
Successfully installed knapsack-4.0.0
1 gem installed
==> 'gem install knapsack --no-document' succeeded in 0 seconds.
$ run_timed_command "scripts/gitaly-test-spawn"
$ scripts/gitaly-test-spawn
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and
installing your bundle as root will break this application for all non-root
users on this machine.
Using abstract_type 0.0.7
Using concurrent-ruby 1.1.9
Using i18n 1.8.10
Using minitest 5.14.4
Using tzinfo 2.0.4
Using zeitwerk 2.4.2
Using activesupport 6.1.4.1
Using builder 3.2.4
Using erubi 1.10.0
Using mini_portile2 2.5.1
Using racc 1.5.2
Using nokogiri 1.11.7 (x86_64-linux)
Using rails-dom-testing 2.0.3
Using crass 1.0.6
Using loofah 2.12.0
Using rails-html-sanitizer 1.4.2
Using actionview 6.1.4.1
Using rack 2.2.3
Using rack-test 1.1.0
Using actionpack 6.1.4.1
Using ice_nine 0.11.2
Using thread_safe 0.3.6
Using memoizable 0.4.2
Using adamantium 0.2.0
Using public_suffix 4.0.6
Using addressable 2.7.0
Using ast 2.4.1
Using binding_ninja 0.2.3
Using bundler 2.1.4
Using charlock_holmes 0.7.7
Using coderay 1.1.2
Using equalizer 0.0.11
Using concord 0.1.5
Using diff-lcs 1.3
Using dotenv 2.7.6
Using escape_utils 1.2.1
Using factory_bot 5.0.2
Using multipart-post 2.1.1
Using faraday 1.0.1
Using ffi 1.15.3
Using json 2.5.1
Using gemojione 3.3.0
Using mini_mime 1.0.2
Using rugged 1.2.0
Using github-linguist 7.12.1
Using github-markup 1.7.0
Using mime-types-data 3.2020.1104
Using mime-types 3.3.1
Using gitlab-gollum-rugged_adapter 0.4.4.4.gitlab.1
Using rouge 3.26.0
Using nokogumbo 1.5.0
Using sanitize 4.6.6
Using stringex 2.8.5
Using gitlab-gollum-lib 4.2.7.10.gitlab.1
Using google-protobuf 3.17.3 (x86_64-linux)
Using googleapis-common-protos-types 1.1.0
Using grpc 1.30.2 (x86_64-linux)
Using opentracing 0.5.0
Using thrift 0.15.0
Using jaeger-client 1.1.0
Using pg_query 2.1.1
Using redis 4.4.0
Using gitlab-labkit 0.21.2
Using rubyzip 2.3.2
Using thor 1.1.0
Using tomlrb 2.0.1
Using with_env 1.1.0
Using rexml 3.2.4
Using xml-simple 1.1.9
Using gitlab-license_finder 6.14.2.1
Using gitlab-markup 1.7.1
Using grpc-tools 1.30.2
Using sawyer 0.8.2
Using octokit 4.20.0
Using reverse_markdown 1.4.0
Using licensee 9.14.1
Using method_source 0.9.2
Using msgpack 1.3.3
Using optimist 3.0.1
Using parallel 1.19.2
Using parser 2.7.2.0
Using procto 0.0.3
Using unparser 0.4.7
Using proc_to_ast 0.1.0
Using pry 0.12.2
Using rainbow 3.0.0
Using rbtrace 0.4.14
Using rdoc 6.3.2
Using regexp_parser 1.8.1
Using rspec-support 3.8.0
Using rspec-core 3.8.0
Using rspec-expectations 3.8.3
Using rspec-mocks 3.8.0
Using rspec 3.8.0
Using rspec-parameterized 0.4.2
Using rubocop-ast 0.2.0
Using ruby-progressbar 1.10.1
Using unicode-display_width 1.7.0
Using rubocop 0.86.0
Using sentry-raven 3.0.4
Using timecop 0.9.1
Bundle complete! 22 Gemfile dependencies, 101 gems now installed.
Gems in the groups production and development were not installed.
Bundled gems are installed into `/builds/gitlab-org/gitlab/vendor/gitaly-ruby`
Checking gitaly-ruby Gemfile...
Checking gitaly-ruby bundle...
The Gemfile's dependencies are satisfied
Trying to connect to gitaly: ................................................ OK
Trying to connect to gitaly2: ................................................................... OK
Trying to connect to praefect: .......... OK
==> 'scripts/gitaly-test-spawn' succeeded in 14 seconds.
$ source ./scripts/rspec_helpers.sh
$ rspec_paralellized_job "--tag ~quarantine --tag ~geo --tag ~level:migration"
KNAPSACK_TEST_FILE_PATTERN: spec/{bin,channels,config,db,dependencies,elastic,elastic_integration,experiments,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,metrics_server,models,policies,presenters,rack_servers,replicators,routing,rubocop,scripts,serializers,services,sidekiq,sidekiq_cluster,spam,support_specs,tasks,uploaders,validators,views,workers,tooling}{,/**/}*_spec.rb
SKIP_FLAKY_TESTS_AUTOMATICALLY: true

Knapsack node specs:
spec/models/merge_request_spec.rb
spec/policies/project_policy_spec.rb
spec/services/git/branch_push_service_spec.rb
spec/finders/group_members_finder_spec.rb
spec/uploaders/design_management/design_v432x230_uploader_spec.rb
spec/lib/gitlab/usage_data_metrics_spec.rb
spec/models/ci/runner_spec.rb
spec/policies/project_statistics_policy_spec.rb
spec/services/merge_requests/merge_service_spec.rb
spec/services/boards/lists/move_service_spec.rb
spec/policies/blob_policy_spec.rb
spec/models/integrations/bamboo_spec.rb
spec/lib/gitlab/ci/config/entry/job_spec.rb
spec/lib/banzai/color_parser_spec.rb
spec/lib/gitlab/gitaly_client/commit_service_spec.rb
spec/lib/gitlab/project_authorizations_spec.rb
spec/models/pages_domain_spec.rb
spec/helpers/namespaces_helper_spec.rb
spec/serializers/environment_serializer_spec.rb
spec/models/notification_recipient_spec.rb
spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb
spec/services/members/update_service_spec.rb
spec/models/merge_request_diff_file_spec.rb
spec/workers/packages/debian/process_changes_worker_spec.rb
spec/lib/error_tracking/sentry_client/issue_spec.rb
spec/lib/gitlab/usage/metric_definition_spec.rb
spec/models/concerns/chronic_duration_attribute_spec.rb
spec/lib/gitlab/hashed_storage/migrator_spec.rb
spec/workers/process_commit_worker_spec.rb
spec/serializers/issue_entity_spec.rb
spec/lib/gitlab/json_spec.rb
spec/models/concerns/routable_spec.rb
spec/lib/gitlab/experimentation/controller_concern_spec.rb
spec/services/jira/requests/projects/list_service_spec.rb
spec/models/ci/daily_build_group_report_result_spec.rb
spec/services/projects/protect_default_branch_service_spec.rb
spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb
spec/services/snippets/destroy_service_spec.rb
spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb
spec/lib/gitlab/database/migration_helpers/v2_spec.rb
spec/lib/gitlab/ci/trace/checksum_spec.rb
spec/policies/ci/pipeline_policy_spec.rb
spec/lib/container_registry/blob_spec.rb
spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
spec/finders/fork_projects_finder_spec.rb
spec/lib/gitlab/pagination/keyset/paginator_spec.rb
spec/services/issues/set_crm_contacts_service_spec.rb
spec/services/ci/archive_trace_service_spec.rb
spec/services/snippets/update_statistics_service_spec.rb
spec/finders/projects/groups_finder_spec.rb
spec/services/ci/job_artifacts/create_service_spec.rb
spec/lib/gitlab/error_tracking_spec.rb
spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
spec/views/notify/pipeline_failed_email.html.haml_spec.rb
spec/services/labels/create_service_spec.rb
spec/lib/gitlab/metrics/methods_spec.rb
spec/models/hooks/project_hook_spec.rb
spec/views/projects/merge_requests/show.html.haml_spec.rb
spec/models/concerns/schedulable_spec.rb
spec/serializers/discussion_diff_file_entity_spec.rb
spec/finders/contributed_projects_finder_spec.rb
spec/lib/gitlab/database/count_spec.rb
spec/models/concerns/project_features_compatibility_spec.rb
spec/services/concerns/rate_limited_service_spec.rb
spec/lib/gitlab/rack_attack_spec.rb
spec/lib/gitlab/ci/reports/test_reports_spec.rb
spec/tasks/gettext_rake_spec.rb
spec/services/ci/run_scheduled_build_service_spec.rb
spec/lib/gitlab/visibility_level_checker_spec.rb
spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
spec/workers/ci/delete_unit_tests_worker_spec.rb
spec/models/packages/dependency_link_spec.rb
spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb
spec/config/inject_enterprise_edition_module_spec.rb
spec/models/lfs_download_object_spec.rb
spec/lib/gitlab/ci/config/entry/service_spec.rb
spec/finders/concerns/finder_with_group_hierarchy_spec.rb
spec/lib/gitlab/ci/reports/security/report_spec.rb
spec/lib/gitlab/shell_spec.rb
spec/services/terraform/remote_state_handler_spec.rb
spec/helpers/routing/pseudonymization_helper_spec.rb
spec/lib/gitlab/database/partitioning/time_partition_spec.rb
spec/views/projects/commit/show.html.haml_spec.rb
spec/lib/banzai/reference_parser/label_parser_spec.rb
spec/lib/banzai/filter/wiki_link_filter_spec.rb
spec/views/shared/_global_alert.html.haml_spec.rb
spec/services/alert_management/alerts/todo/create_service_spec.rb
spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb
spec/services/chat_names/find_user_service_spec.rb
spec/graphql/mutations/terraform/state/delete_spec.rb
spec/services/metrics/dashboard/transient_embed_service_spec.rb
spec/lib/gitlab/null_request_store_spec.rb
spec/models/experiment_subject_spec.rb
spec/models/integrations/bugzilla_spec.rb
spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
spec/lib/gitlab/checks/diff_check_spec.rb
spec/workers/concerns/limited_capacity/worker_spec.rb
spec/finders/protected_branches_finder_spec.rb
spec/models/packages/debian/group_distribution_key_spec.rb
spec/lib/gitlab/ci/config/external/file/project_spec.rb
spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb
spec/models/ci/freeze_period_spec.rb
spec/lib/gitlab/suggestions/suggestion_set_spec.rb
spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb
spec/lib/gitlab/config/entry/undefined_spec.rb
spec/tasks/gitlab/external_diffs_rake_spec.rb
spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb
spec/finders/prometheus_metrics_finder_spec.rb
spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb
spec/workers/personal_access_tokens/expiring_worker_spec.rb
spec/lib/gitlab/bullet/exclusions_spec.rb
spec/lib/gitlab/jwt_authenticatable_spec.rb
spec/graphql/mutations/todos/mark_all_done_spec.rb
spec/services/ci/job_token_scope/remove_project_service_spec.rb
spec/validators/json_schema_validator_spec.rb
spec/views/projects/diffs/_viewer.html.haml_spec.rb
spec/services/error_tracking/base_service_spec.rb
spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
spec/lib/gitlab/git/keep_around_spec.rb
spec/presenters/ci/group_variable_presenter_spec.rb
spec/lib/api/helpers/related_resources_helpers_spec.rb
spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb
spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
spec/graphql/mutations/terraform/state/lock_spec.rb
spec/services/snippets/count_service_spec.rb
spec/lib/banzai/filter/inline_cluster_metrics_filter_spec.rb
spec/services/ci/compare_test_reports_service_spec.rb
spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
spec/helpers/instance_configuration_helper_spec.rb
spec/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb
spec/services/system_notes/base_service_spec.rb
spec/lib/gitlab/ci/templates/5_minute_production_app_ci_yaml_spec.rb
spec/lib/gitlab/kas/client_spec.rb
spec/serializers/member_serializer_spec.rb
spec/lib/banzai/filter/inline_diff_filter_spec.rb
spec/graphql/types/namespace_type_spec.rb
spec/lib/gitlab/exclusive_lease_helpers_spec.rb
spec/services/audit_event_service_spec.rb
spec/models/gpg_key_subkey_spec.rb
spec/lib/gitlab/graphql/batch_key_spec.rb
spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
spec/lib/gitlab/loop_helpers_spec.rb
spec/rubocop/cop/rspec/env_assignment_spec.rb
spec/lib/gitlab/search_context/controller_concern_spec.rb
spec/workers/repository_remove_remote_worker_spec.rb
spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
spec/lib/gitlab/hook_data/group_builder_spec.rb
spec/finders/terraform/states_finder_spec.rb
spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
spec/workers/migrate_external_diffs_worker_spec.rb
spec/graphql/types/base_edge_spec.rb
spec/workers/update_highest_role_worker_spec.rb
spec/workers/authorized_project_update/user_refresh_with_low_urgency_worker_spec.rb
spec/lib/gitlab/git/changes_spec.rb
spec/graphql/mutations/terraform/state/unlock_spec.rb
spec/lib/gitlab/data_builder/wiki_page_spec.rb
spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb
spec/views/projects/environments/terminal.html.haml_spec.rb
spec/lib/gitlab/crypto_helper_spec.rb
spec/lib/gitlab/ci/config/entry/release/assets/link_spec.rb
spec/lib/gitlab/database/postgresql_adapter/empty_query_ping_spec.rb
spec/presenters/service_hook_presenter_spec.rb
spec/graphql/types/ci/pipeline_type_spec.rb
spec/services/issues/after_create_service_spec.rb
spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
spec/lib/gitlab/gitlab_import/client_spec.rb
spec/models/wiki_directory_spec.rb
spec/workers/group_destroy_worker_spec.rb
spec/services/ci/pipeline_bridge_status_service_spec.rb
spec/serializers/user_serializer_spec.rb
spec/workers/pipeline_hooks_worker_spec.rb
spec/presenters/packages/nuget/package_metadata_presenter_spec.rb
spec/workers/user_status_cleanup/batch_worker_spec.rb
spec/lib/gitlab/repository_size_error_message_spec.rb
spec/services/resource_events/merge_into_notes_service_spec.rb
spec/views/projects/clusters/clusters/gcp/_form.html.haml_spec.rb
spec/rubocop/cop/prefer_class_methods_over_module_spec.rb
spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
spec/serializers/jira_connect/app_data_serializer_spec.rb
spec/lib/gitlab/middleware/basic_health_check_spec.rb
spec/presenters/pages_domain_presenter_spec.rb
spec/workers/jira_connect/sync_deployments_worker_spec.rb
spec/tooling/lib/tooling/crystalball/coverage_lines_execution_detector_spec.rb
spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb
spec/models/approval_spec.rb
spec/services/users/dismiss_callout_service_spec.rb
spec/serializers/import/manifest_provider_repo_entity_spec.rb
spec/lib/gitlab/code_navigation_path_spec.rb
spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb
spec/models/diff_viewer/image_spec.rb
spec/serializers/diff_viewer_entity_spec.rb
spec/lib/gitlab/graphql/pagination/connections_spec.rb
spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb
spec/tasks/admin_mode_spec.rb
spec/presenters/alert_management/alert_presenter_spec.rb
spec/workers/experiments/record_conversion_event_worker_spec.rb
spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
spec/lib/gitlab/utils/delegator_override/validator_spec.rb
spec/lib/gitlab/graphql/negatable_arguments_spec.rb
spec/lib/gitlab/import_export/after_export_strategy_builder_spec.rb
spec/lib/gitlab/github_import/bulk_importing_spec.rb
spec/graphql/types/merge_request_state_enum_spec.rb
spec/lib/gitlab/phabricator_import/conduit/users_response_spec.rb
spec/services/base_container_service_spec.rb
spec/lib/gitlab/sidekiq_middleware/extra_done_log_metadata_spec.rb
spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb
spec/models/protected_branch/merge_access_level_spec.rb
spec/serializers/accessibility_reports_comparer_entity_spec.rb
spec/graphql/types/design_management/design_version_event_enum_spec.rb
spec/lib/peek/views/memory_spec.rb
spec/helpers/one_trust_helper_spec.rb
spec/lib/gitlab/hashed_path_spec.rb
spec/lib/api/entities/deploy_keys_project_spec.rb
spec/lib/api/validations/validators/project_portable_spec.rb
spec/lib/sidebars/projects/menus/repository_menu_spec.rb
spec/rubocop/cop/rspec/timecop_freeze_spec.rb
spec/rubocop/cop/qa/selector_usage_spec.rb
spec/lib/gitlab/ci/build/port_spec.rb
spec/rubocop/qa_helpers_spec.rb
spec/views/groups/runners/_sort_dropdown.html.haml_spec.rb
spec/initializers/mailer_retries_spec.rb
spec/lib/gitlab/chat_spec.rb
spec/lib/gitlab/database/background_migration/batch_metrics_spec.rb
spec/lib/constraints/feature_constrainer_spec.rb
spec/lib/gitlab/sidekiq_middleware/size_limiter/server_spec.rb
spec/graphql/types/ci/config/job_type_spec.rb
spec/models/packages/rubygems/metadatum_spec.rb
spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb
spec/lib/gitlab/git/patches/patch_spec.rb
spec/serializers/evidences/release_serializer_spec.rb
spec/graphql/types/packages/package_type_enum_spec.rb
spec/models/concerns/from_union_spec.rb
spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb
spec/views/errors/access_denied.html.haml_spec.rb
spec/lib/gitlab/database/async_indexes_spec.rb
spec/uploaders/uploader_helper_spec.rb
spec/serializers/ci/codequality_mr_diff_entity_spec.rb

Filter specs:

Running specs:
Running all node tests without filter
spec/models/merge_request_spec.rb
spec/policies/project_policy_spec.rb
spec/services/git/branch_push_service_spec.rb
spec/finders/group_members_finder_spec.rb
spec/uploaders/design_management/design_v432x230_uploader_spec.rb
spec/lib/gitlab/usage_data_metrics_spec.rb
spec/models/ci/runner_spec.rb
spec/policies/project_statistics_policy_spec.rb
spec/services/merge_requests/merge_service_spec.rb
spec/services/boards/lists/move_service_spec.rb
spec/policies/blob_policy_spec.rb
spec/models/integrations/bamboo_spec.rb
spec/lib/gitlab/ci/config/entry/job_spec.rb
spec/lib/banzai/color_parser_spec.rb
spec/lib/gitlab/gitaly_client/commit_service_spec.rb
spec/lib/gitlab/project_authorizations_spec.rb
spec/models/pages_domain_spec.rb
spec/helpers/namespaces_helper_spec.rb
spec/serializers/environment_serializer_spec.rb
spec/models/notification_recipient_spec.rb
spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb
spec/services/members/update_service_spec.rb
spec/models/merge_request_diff_file_spec.rb
spec/workers/packages/debian/process_changes_worker_spec.rb
spec/lib/error_tracking/sentry_client/issue_spec.rb
spec/lib/gitlab/usage/metric_definition_spec.rb
spec/models/concerns/chronic_duration_attribute_spec.rb
spec/lib/gitlab/hashed_storage/migrator_spec.rb
spec/workers/process_commit_worker_spec.rb
spec/serializers/issue_entity_spec.rb
spec/lib/gitlab/json_spec.rb
spec/models/concerns/routable_spec.rb
spec/lib/gitlab/experimentation/controller_concern_spec.rb
spec/services/jira/requests/projects/list_service_spec.rb
spec/models/ci/daily_build_group_report_result_spec.rb
spec/services/projects/protect_default_branch_service_spec.rb
spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb
spec/services/snippets/destroy_service_spec.rb
spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb
spec/lib/gitlab/database/migration_helpers/v2_spec.rb
spec/lib/gitlab/ci/trace/checksum_spec.rb
spec/policies/ci/pipeline_policy_spec.rb
spec/lib/container_registry/blob_spec.rb
spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
spec/finders/fork_projects_finder_spec.rb
spec/lib/gitlab/pagination/keyset/paginator_spec.rb
spec/services/issues/set_crm_contacts_service_spec.rb
spec/services/ci/archive_trace_service_spec.rb
spec/services/snippets/update_statistics_service_spec.rb
spec/finders/projects/groups_finder_spec.rb
spec/services/ci/job_artifacts/create_service_spec.rb
spec/lib/gitlab/error_tracking_spec.rb
spec/presenters/projects/settings/deploy_keys_presenter_spec.rb
spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
spec/views/notify/pipeline_failed_email.html.haml_spec.rb
spec/services/labels/create_service_spec.rb
spec/lib/gitlab/metrics/methods_spec.rb
spec/models/hooks/project_hook_spec.rb
spec/views/projects/merge_requests/show.html.haml_spec.rb
spec/models/concerns/schedulable_spec.rb
spec/serializers/discussion_diff_file_entity_spec.rb
spec/finders/contributed_projects_finder_spec.rb
spec/lib/gitlab/database/count_spec.rb
spec/models/concerns/project_features_compatibility_spec.rb
spec/services/concerns/rate_limited_service_spec.rb
spec/lib/gitlab/rack_attack_spec.rb
spec/lib/gitlab/ci/reports/test_reports_spec.rb
spec/tasks/gettext_rake_spec.rb
spec/services/ci/run_scheduled_build_service_spec.rb
spec/lib/gitlab/visibility_level_checker_spec.rb
spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb
spec/workers/ci/delete_unit_tests_worker_spec.rb
spec/models/packages/dependency_link_spec.rb
spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb
spec/config/inject_enterprise_edition_module_spec.rb
spec/models/lfs_download_object_spec.rb
spec/lib/gitlab/ci/config/entry/service_spec.rb
spec/finders/concerns/finder_with_group_hierarchy_spec.rb
spec/lib/gitlab/ci/reports/security/report_spec.rb
spec/lib/gitlab/shell_spec.rb
spec/services/terraform/remote_state_handler_spec.rb
spec/helpers/routing/pseudonymization_helper_spec.rb
spec/lib/gitlab/database/partitioning/time_partition_spec.rb
spec/views/projects/commit/show.html.haml_spec.rb
spec/lib/banzai/reference_parser/label_parser_spec.rb
spec/lib/banzai/filter/wiki_link_filter_spec.rb
spec/views/shared/_global_alert.html.haml_spec.rb
spec/services/alert_management/alerts/todo/create_service_spec.rb
spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb
spec/services/chat_names/find_user_service_spec.rb
spec/graphql/mutations/terraform/state/delete_spec.rb
spec/services/metrics/dashboard/transient_embed_service_spec.rb
spec/lib/gitlab/null_request_store_spec.rb
spec/models/experiment_subject_spec.rb
spec/models/integrations/bugzilla_spec.rb
spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
spec/lib/gitlab/checks/diff_check_spec.rb
spec/workers/concerns/limited_capacity/worker_spec.rb
spec/finders/protected_branches_finder_spec.rb
spec/models/packages/debian/group_distribution_key_spec.rb
spec/lib/gitlab/ci/config/external/file/project_spec.rb
spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb
spec/models/ci/freeze_period_spec.rb
spec/lib/gitlab/suggestions/suggestion_set_spec.rb
spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb
spec/lib/gitlab/config/entry/undefined_spec.rb
spec/tasks/gitlab/external_diffs_rake_spec.rb
spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb
spec/finders/prometheus_metrics_finder_spec.rb
spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb
spec/workers/personal_access_tokens/expiring_worker_spec.rb
spec/lib/gitlab/bullet/exclusions_spec.rb
spec/lib/gitlab/jwt_authenticatable_spec.rb
spec/graphql/mutations/todos/mark_all_done_spec.rb
spec/services/ci/job_token_scope/remove_project_service_spec.rb
spec/validators/json_schema_validator_spec.rb
spec/views/projects/diffs/_viewer.html.haml_spec.rb
spec/services/error_tracking/base_service_spec.rb
spec/lib/gitlab/background_migration/remove_occurrence_pipelines_and_duplicate_vulnerabilities_findings_spec.rb
spec/lib/gitlab/git/keep_around_spec.rb
spec/presenters/ci/group_variable_presenter_spec.rb
spec/lib/api/helpers/related_resources_helpers_spec.rb
spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb
spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb
spec/graphql/mutations/terraform/state/lock_spec.rb
spec/services/snippets/count_service_spec.rb
spec/lib/banzai/filter/inline_cluster_metrics_filter_spec.rb
spec/services/ci/compare_test_reports_service_spec.rb
spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
spec/helpers/instance_configuration_helper_spec.rb
spec/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb
spec/services/system_notes/base_service_spec.rb
spec/lib/gitlab/ci/templates/5_minute_production_app_ci_yaml_spec.rb
spec/lib/gitlab/kas/client_spec.rb
spec/serializers/member_serializer_spec.rb
spec/lib/banzai/filter/inline_diff_filter_spec.rb
spec/graphql/types/namespace_type_spec.rb
spec/lib/gitlab/exclusive_lease_helpers_spec.rb
spec/services/audit_event_service_spec.rb
spec/models/gpg_key_subkey_spec.rb
spec/lib/gitlab/graphql/batch_key_spec.rb
spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
spec/lib/gitlab/loop_helpers_spec.rb
spec/rubocop/cop/rspec/env_assignment_spec.rb
spec/lib/gitlab/search_context/controller_concern_spec.rb
spec/workers/repository_remove_remote_worker_spec.rb
spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb
spec/lib/gitlab/hook_data/group_builder_spec.rb
spec/finders/terraform/states_finder_spec.rb
spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb
spec/workers/migrate_external_diffs_worker_spec.rb
spec/graphql/types/base_edge_spec.rb
spec/workers/update_highest_role_worker_spec.rb
spec/workers/authorized_project_update/user_refresh_with_low_urgency_worker_spec.rb
spec/lib/gitlab/git/changes_spec.rb
spec/graphql/mutations/terraform/state/unlock_spec.rb
spec/lib/gitlab/data_builder/wiki_page_spec.rb
spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb
spec/views/projects/environments/terminal.html.haml_spec.rb
spec/lib/gitlab/crypto_helper_spec.rb
spec/lib/gitlab/ci/config/entry/release/assets/link_spec.rb
spec/lib/gitlab/database/postgresql_adapter/empty_query_ping_spec.rb
spec/presenters/service_hook_presenter_spec.rb
spec/graphql/types/ci/pipeline_type_spec.rb
spec/services/issues/after_create_service_spec.rb
spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
spec/lib/gitlab/gitlab_import/client_spec.rb
spec/models/wiki_directory_spec.rb
spec/workers/group_destroy_worker_spec.rb
spec/services/ci/pipeline_bridge_status_service_spec.rb
spec/serializers/user_serializer_spec.rb
spec/workers/pipeline_hooks_worker_spec.rb
spec/presenters/packages/nuget/package_metadata_presenter_spec.rb
spec/workers/user_status_cleanup/batch_worker_spec.rb
spec/lib/gitlab/repository_size_error_message_spec.rb
spec/services/resource_events/merge_into_notes_service_spec.rb
spec/views/projects/clusters/clusters/gcp/_form.html.haml_spec.rb
spec/rubocop/cop/prefer_class_methods_over_module_spec.rb
spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb
spec/serializers/jira_connect/app_data_serializer_spec.rb
spec/lib/gitlab/middleware/basic_health_check_spec.rb
spec/presenters/pages_domain_presenter_spec.rb
spec/workers/jira_connect/sync_deployments_worker_spec.rb
spec/tooling/lib/tooling/crystalball/coverage_lines_execution_detector_spec.rb
spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb
spec/models/approval_spec.rb
spec/services/users/dismiss_callout_service_spec.rb
spec/serializers/import/manifest_provider_repo_entity_spec.rb
spec/lib/gitlab/code_navigation_path_spec.rb
spec/lib/gitlab/import_export/design_repo_restorer_spec.rb
spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb
spec/models/diff_viewer/image_spec.rb
spec/serializers/diff_viewer_entity_spec.rb
spec/lib/gitlab/graphql/pagination/connections_spec.rb
spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb
spec/tasks/admin_mode_spec.rb
spec/presenters/alert_management/alert_presenter_spec.rb
spec/workers/experiments/record_conversion_event_worker_spec.rb
spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
spec/lib/gitlab/utils/delegator_override/validator_spec.rb
spec/lib/gitlab/graphql/negatable_arguments_spec.rb
spec/lib/gitlab/import_export/after_export_strategy_builder_spec.rb
spec/lib/gitlab/github_import/bulk_importing_spec.rb
spec/graphql/types/merge_request_state_enum_spec.rb
spec/lib/gitlab/phabricator_import/conduit/users_response_spec.rb
spec/services/base_container_service_spec.rb
spec/lib/gitlab/sidekiq_middleware/extra_done_log_metadata_spec.rb
spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb
spec/models/protected_branch/merge_access_level_spec.rb
spec/serializers/accessibility_reports_comparer_entity_spec.rb
spec/graphql/types/design_management/design_version_event_enum_spec.rb
spec/lib/peek/views/memory_spec.rb
spec/helpers/one_trust_helper_spec.rb
spec/lib/gitlab/hashed_path_spec.rb
spec/lib/api/entities/deploy_keys_project_spec.rb
spec/lib/api/validations/validators/project_portable_spec.rb
spec/lib/sidebars/projects/menus/repository_menu_spec.rb
spec/rubocop/cop/rspec/timecop_freeze_spec.rb
spec/rubocop/cop/qa/selector_usage_spec.rb
spec/lib/gitlab/ci/build/port_spec.rb
spec/rubocop/qa_helpers_spec.rb
spec/views/groups/runners/_sort_dropdown.html.haml_spec.rb
spec/initializers/mailer_retries_spec.rb
spec/lib/gitlab/chat_spec.rb
spec/lib/gitlab/database/background_migration/batch_metrics_spec.rb
spec/lib/constraints/feature_constrainer_spec.rb
spec/lib/gitlab/sidekiq_middleware/size_limiter/server_spec.rb
spec/graphql/types/ci/config/job_type_spec.rb
spec/models/packages/rubygems/metadatum_spec.rb
spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb
spec/lib/gitlab/git/patches/patch_spec.rb
spec/serializers/evidences/release_serializer_spec.rb
spec/graphql/types/packages/package_type_enum_spec.rb
spec/models/concerns/from_union_spec.rbKnapsack report generator started!
warning: parser/current is loading parser/ruby27, which recognizes
warning: 2.7.4-compliant syntax, but you are running 2.7.5.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
undefined method `[]' for #<RspecFlaky::FlakyExample:0x00007feccd545490>
Run options: exclude {:quarantine=>true, :geo=>true, :level=>"migration"}
==> /builds/gitlab-org/gitlab/tmp/tests/gitlab-test_bare set up in 0.058773325 seconds...

Test environment set up in 0.69120312 seconds

MergeRequest
  associations
    is expected to belong to target_project class_name => Project required: false
    is expected to belong to source_project class_name => Project required: false
    is expected to belong to merge_user class_name => User required: false
    is expected to have many assignees through merge_request_assignees
    is expected to have many reviewers through merge_request_reviewers
    is expected to have many merge_request_diffs
    is expected to have many user_mentions class_name => MergeRequestUserMention
    is expected to belong to milestone required: false
    is expected to belong to iteration required: false
    is expected to have many resource_milestone_events
    is expected to have many resource_state_events
    is expected to have many draft_notes
    is expected to have many reviews inverse_of => merge_request
    is expected to have one cleanup_schedule inverse_of => merge_request
    for forks
      does not load another project due to inverse relationship
      finds the associated merge request
  .from_and_to_forks
    returns only MRs from and to forks (with no internal MRs)
  .order_merged_at_asc
    returns MRs ordered by merged_at ascending
  .order_merged_at_desc
    returns MRs ordered by merged_at descending
  .order_closed_at_asc
    returns MRs ordered by closed_at ascending
  .order_closed_at_desc
    returns MRs ordered by closed_at descending
  .with_jira_issue_keys
    is expected to contain exactly #<MergeRequest id:15 namespace1/project1!1> and #<MergeRequest id:16 namespace1/project1!2>
    is expected not to include #<MergeRequest id:17 namespace1/project1!3>
  scopes
    .review_requested
      returns MRs that have any review requests
    .no_review_requested
      returns MRs that have no review requests
    .review_requested_to
      returns MRs that the user has been requested to review
    .no_review_requested_to
      returns MRs that the user has not been requested to review
    .drafts
      returns MRs where draft == true
  #squash?
    disabled in database
      is expected to be falsy
    enabled in database
      is expected to be truthy
  #default_squash_commit_message
    returns the merge request title
    uses template from target project
  modules
    is expected to includes the Issuable module
    is expected to includes the Referable module
    is expected to includes the Sortable module
    is expected to includes the Taskable module
    is expected to includes the MilestoneEventable module
    is expected to includes the StateEventable module
    behaves like AtomicInternalId
      .has_internal_id
        Module inclusion
          is expected to includes the AtomicInternalId module
        Validation
          when presence validation is required
            when creating an object
              raises an error if the internal id is blank
            when updating an object
              raises an error if the internal id is blank
          when presence validation is not required
            when creating an object
              does not raise an error if the internal id is blank (PENDING: No reason given)
            when updating an object
              does not raise an error if the internal id is blank (PENDING: No reason given)
        Creating an instance
          saves a new instance properly
        internal id generation
          calls InternalId.generate_next and sets internal id attribute
          does not overwrite an existing internal id
          when the instance has an internal ID set
            calls InternalId.update_last_value and sets the `last_value` to that of the instance
        unsetting the instance internal id on rollback
          when the internal id has been changed
            when the internal id is automatically set
              clears it on the instance
            when the internal id is manually set
              does not clear it on the instance
          when the internal id has not been changed
            preserves the value on the instance
        supply of internal ids
          provides a persistent supply of IID values, sensitive to the current state
        #reset_scope_internal_id_attribute
          rewinds the allocated IID
          allocates the same IID
  validation
    is expected to validate that :target_branch cannot be empty/falsy
    is expected to validate that :source_branch cannot be empty/falsy
    Validation of merge user with Merge When Pipeline Succeeds
      allows user to be nil when the feature is disabled
      is invalid without merge user
      is valid with merge user
    for branch
      branch_name: "foo", valid: true
        validates source_branch
        validates target_branch
      branch_name: "foo:bar", valid: false
        validates source_branch
        validates target_branch
      branch_name: "+foo:bar", valid: false
        validates source_branch
        validates target_branch
      branch_name: "foo bar", valid: false
        validates source_branch
        validates target_branch
      branch_name: "-foo", valid: false
        validates source_branch
        validates target_branch
      branch_name: "HEAD", valid: true
        validates source_branch
        validates target_branch
      branch_name: "refs/heads/master", valid: true
        validates source_branch
        validates target_branch
    for forks
      allows merge requests for sibling-forks
  callbacks
    #ensure_merge_request_metrics
      creates metrics after saving
      does not duplicate metrics for a merge request
      does not create duplicated metrics records when MR is concurrently updated
      syncs the `target_project_id` to the metrics record
    #set_draft_status
      MR is a draft
        sets draft to true
      MR is not a draft
        sets draft to true
  respond to
    is expected to respond to #unchecked?
    is expected to respond to #checking?
    is expected to respond to #can_be_merged?
    is expected to respond to #cannot_be_merged?
    is expected to respond to #merge_params
    is expected to respond to #merge_when_pipeline_succeeds
  .by_commit_sha
    with sha contained in latest merge request diff
      returns merge requests
    with sha contained not in latest merge request diff
      returns empty requests
    with sha not contained in
      returns empty result
  .by_merge_commit_sha
    returns merge requests that match the given merge commit
  .by_squash_commit_sha
    returns merge requests that match the given squash commit
  .by_merge_or_squash_commit_sha
    returns merge requests that match the given squash and merge commits
  .join_metrics
    when a no target_project_id is available
      moves target_project_id condition to the merge request metrics
    when a target_project_id is present in the where conditions
      moves target_project_id condition to the merge request metrics
  .by_related_commit_sha
    when commit is a squash commit
      is expected to eq [#<MergeRequest id:46 namespace1/project1!1>]
    when commit is a part of the merge request
      is expected to eq [#<MergeRequest id:47 namespace1/project1!1>]
    when commit is a merge commit
      is expected to eq [#<MergeRequest id:48 namespace1/project1!1>]
    when commit is not found
      is expected to be empty
    when commit is part of the merge request and a squash commit at the same time
      is expected to eq [#<MergeRequest id:49 namespace1/project1!1>]
  .in_projects
    returns the merge requests for a set of projects
  .set_latest_merge_request_diff_ids!
    sets IDs for merge requests, whether they are already set or not
  .recent_target_branches
    returns target branches sort by updated at desc
  .sort_by_attribute
    merged_at
      sorts asc
      sorts desc
    closed_at
      sorts asc
      sorts desc
      sorts asc when its closed_at
  time to merge calculations
    .total_time_to_merge
      returns the sum of the time to merge for all merged MRs
      when merged_at is earlier than created_at
        returns nil
  #target_branch_sha
    returns memoized value
    when the target branch does not exist
      returns nil
  #card_attributes
    includes the author name
    includes the assignees name
  #assignee_or_author?
    returns true for a user that is assigned to a merge request
    returns true for a user that is the author of a merge request
    returns false for a user that is not the assignee or author
  #visible_closing_issues_for
    shows only allowed issues to guest
    shows only allowed issues to developer
    when external issue tracker is enabled
      calls non #closes_issues to retrieve data
  #cache_merge_request_closes_issues!
    caches closed issues
    does not cache closed issues when merge request is closed
    does not cache closed issues when merge request is merged
    when both internal and external issue trackers are enabled
      does not cache issues from external trackers
      caches an internal issue
    when only external issue tracker enabled
      does not cache issues from external trackers
      does not cache an internal issue
  #source_branch_sha
    returns memoized value
    with diffs
      returns the sha of the source branch last commit
    without diffs
      returns the sha of the source branch last commit
      when there is a tag name matching the branch name
        returns the sha of the source branch last commit
    when the merge request is being created
      returns nil
  #to_reference
    returns a String reference to the object
    supports a cross-project reference
    returns a String reference with the full path
  #raw_diffs
    when there are MR diffs
      delegates to the MR diffs
    when there are no MR diffs
      delegates to the compare object
  #diffs
    when there are MR diffs
      delegates to the MR diffs
    when there are no MR diffs
      delegates to the compare object, setting expanded: true
  #note_positions_for_paths
    returns a Gitlab::Diff::PositionCollection
    within all diff files
      returns correct positions
    within specific diff file
      returns correct positions
    within no diff files
      returns no positions
    when user is given
      returns notes and draft notes positions
    when user is not given
      returns notes positions
  #discussions_diffs
    with commit diff note
      behaves like discussions diffs collection
        initializes Gitlab::DiscussionsDiff::FileCollection with correct data
        eager loads relations
    with merge request diff note
      behaves like discussions diffs collection
        initializes Gitlab::DiscussionsDiff::FileCollection with correct data
        eager loads relations
  #diff_size
    when there are MR diffs
      returns the correct count
      returns the correct overflow count
      does not perform highlighting
    when there are no MR diffs
      returns the correct count
      returns the correct overflow count
      does not perform highlighting
  #modified_paths
    when past_merge_request_diff is specified
      returns affected file paths from specified past_merge_request_diff
    when compare is present
      and diff_stats are not present
        returns affected file paths from compare
      and diff_stats are present
        returns affected file paths from compare
    when no arguments provided
      returns affected file paths for merge_request_diff
  #new_paths
    returns new path of changed files
  #related_notes
    includes notes for commits
    includes notes for commits from target project as well
    excludes system notes for commits
  #for_fork?
    returns true if the merge request is for a fork
    returns false if is not for a fork
  #closes_issues
    accesses the set of issues that will be closed on acceptance
    only lists issues as to be closed if it targets the default branch
    ignores referenced issues when auto-close is disabled
  #issues_mentioned_but_not_closing
    detects issues mentioned in description but not closed
    when the project has an external issue tracker
      detects issues mentioned in description but not closed
  #work_in_progress?
    detects the 'WIP:' prefix
    detects the 'WIP: ' prefix
    detects the '[WIP]' prefix
    detects the '[WIP] ' prefix
    detects the ' [WIP] WIP: [WIP] WIP:' prefix
    detects the 'draft:' prefix
    detects the 'Draft: ' prefix
    detects the '[Draft]' prefix
    detects the '[DRAFT] ' prefix
    doesn't detect 'WIP ' at the start of the title as a draft
    doesn't detect '(WIP)' at the start of the title as a draft
    doesn't detect 'draft' at the start of the title as a draft
    doesn't detect 'Draft' at the start of the title as a draft
    doesn't detect 'Draft -' at the start of the title as a draft
    doesn't detect 'draft - ' at the start of the title as a draft
    doesn't detect 'Draft ' at the start of the title as a draft
    doesn't detect 'draft ' at the start of the title as a draft
    detects merge request title just saying 'wip'
    does not detect merge request title just saying 'draft'
    does not detect WIP in the middle of the title
    does not detect Draft in the middle of the title
    does not detect Draft: in the middle of the title
    does not detect WIP at the end of the title
    does not detect Draft at the end of the title
    doesn't detect WIP for words starting with WIP
    doesn't detect WIP for words containing with WIP
    doesn't detect draft for words containing with draft
    doesn't detect WIP by default
    is aliased to #draft?
  #wipless_title
    removes the 'WIP:' prefix
    is satisfies the #work_in_progress? method
    removes the 'WIP: ' prefix
    is satisfies the #work_in_progress? method
    removes the '[WIP]' prefix
    is satisfies the #work_in_progress? method
    removes the '[WIP] ' prefix
    is satisfies the #work_in_progress? method
    removes the '[WIP] WIP: [WIP] WIP:' prefix
    is satisfies the #work_in_progress? method
    removes the 'draft:' prefix
    is satisfies the #work_in_progress? method
    removes the 'Draft: ' prefix
    is satisfies the #work_in_progress? method
    removes the '[Draft]' prefix
    is satisfies the #work_in_progress? method
    removes the '[DRAFT] ' prefix
    is satisfies the #work_in_progress? method
    removes only WIP prefix from the MR title
    removes only draft prefix from the MR title
    does not remove WIP in the middle of the title
    does not remove Draft in the middle of the title
    does not remove WIP at the end of the title
    does not remove Draft at the end of the title
  #wip_title
    adds the Draft: prefix to the title
    does not add the Draft: prefix multiple times
    is satisfies the #work_in_progress? method
  #can_remove_source_branch?
    can't be removed when its a protected branch
    can't be removed because source project has been deleted
    can't remove a root ref
    is unable to remove the source branch for a project the user cannot push to
    can be removed if the last commit is the head of the source branch
    cannot be removed if the last commit is not also the head of the source branch
  #source_branch_exists?
    when the source project is set
      returns true when the branch exists
    when the source project is not set
      returns false
  #default_merge_commit_message
    includes merge information as the title
    includes its title in the body
    includes its closed issues in the body
    includes its reference in the body
    excludes multiple linebreak runs when description is blank
    includes its description in the body
    does not includes its description in the body
    uses template from target project
    ignores template when include_description is true
  #auto_merge_strategy
    is expected to eq "merge_when_pipeline_succeeds"
    when auto merge is disabled
      is expected to be nil
  #committers
    returns all the committers of every commit in the merge request
    returns an empty array if no committer is associated with a user
  #hook_attrs
    delegates to Gitlab::HookData::MergeRequestBuilder#build
  #diverged_commits_count
    when the target branch does not exist anymore
      does not crash
      returns 0
    diverged on same repository
      counts commits that are on target branch but not on source branch
    diverged on fork
      counts commits that are on target branch but not on source branch
    rebased on fork
      counts commits that are on target branch but not on source branch
    caching
      caches the output
      invalidates the cache when the source sha changes
      invalidates the cache when the target sha changes
  behaves like an editable mentionable
    creates new cross-reference notes when the mentionable text is edited
    behaves like a mentionable
      generates a descriptive back-reference
      extracts references from its reference property
      creates cross-reference notes
      when there are cached markdown fields
        sends in cached markdown fields when appropriate
    when there are cached markdown fields
      refreshes markdown cache if necessary
      when the markdown cache is stale
        persists the refreshed cache so that it does not have to be refreshed every time
  behaves like a Taskable
    with multiple tasks
      returns the correct task status
      #tasks?
        returns true when object has tasks
        returns false when object has no tasks
    with nested tasks
      returns the correct task status
    with an incomplete task
      returns the correct task status
    with tasks that are not formatted correctly
      returns the correct task status
    with a complete task
      returns the correct task status
    with tasks in blockquotes
      returns the correct task status
  #commit_shas
    persisted merge request
      with a limit
        returns a limited number of commit shas
      without a limit
        returns all commit shas of the merge request diff
    new merge request
      returns diff_head_sha as an array
      compare commits
        without a limit
          returns all shas of compare commits
        with a limit
          returns a limited number of shas
  head pipeline
    #head_pipeline
      returns nil for MR without head_pipeline_id
      when the source project does not exist
        returns nil
    #actual_head_pipeline
      returns nil for MR with old pipeline
      returns the pipeline for MR with recent pipeline
      returns the pipeline for MR with recent merge request pipeline
      returns nil when source project does not exist
  #merge_pipeline
    returns nil when not merged
    when the MR is merged
      and there is a merge commit
        returns the pipeline associated with that merge request
      and there is no merge commit, but there is a diff head
        returns the pipeline associated with that merge request
      and there is no merge commit, but there is a squash commit
        returns the pipeline associated with that merge request
  #has_ci?
    has ci
      returns true if MR has head_pipeline_id and commits
      returns true if MR has any pipeline and commits
      returns true if MR has CI integration and commits
    has no ci
      returns false if MR has no CI integration nor pipeline, and no commits
  #update_head_pipeline
    when there is a pipeline with the diff head sha
      updates the head pipeline
      when merge request has already had head pipeline
        when failed to find an actual head pipeline
          does not update the current head pipeline
    when detached merge request pipeline is run on head ref of the merge request
      sets the head ref of the merge request to the pipeline ref
      updates correctly even though the target branch name of the merge request is different from the pipeline ref
      when sha is not HEAD of the source branch
        does not update head pipeline
    when there are no pipelines with the diff head sha
      does not update the head pipeline
  #has_test_reports?
    when head pipeline has test reports
      is expected to be truthy
    when head pipeline does not have test reports
      is expected to be falsey
  #has_accessibility_reports?
    when head pipeline has an accessibility reports
      is expected to be truthy
    when head pipeline does not have accessibility reports
      is expected to be falsey
  #has_coverage_reports?
    when head pipeline has coverage reports
      is expected to be truthy
    when head pipeline does not have coverage reports
      is expected to be falsey
  #has_codequality_mr_diff_report?
    when head pipeline has codequality mr diff report
      is expected to be truthy
    when head pipeline does not have codeqquality mr diff report
      is expected to be falsey
  #has_codequality_reports?
    when head pipeline has a codequality report
      is expected to be truthy
    when head pipeline does not have a codequality report
      is expected to be falsey
  #has_terraform_reports?
    when head pipeline has terraform reports
      returns true
    when head pipeline does not have terraform reports
      returns false
  #has_sast_reports?
    when head pipeline has sast reports
      is expected to be truthy
    when head pipeline does not have sast reports
      is expected to be falsey
  #has_secret_detection_reports?
    when head pipeline has secret detection reports
      is expected to be truthy
    when head pipeline does not have secrets detection reports
      is expected to be falsey
  #calculate_reactive_cache
    when given an unknown service class name
      raises a NameError exception
    when given a known service class name
      does not raises a NameError exception
  #find_exposed_artifacts
    when head pipeline has exposed artifacts
      when reactive cache worker is parsing results asynchronously
        returns status
      when reactive cache worker is inline
        returns status and data
        when an error occurrs
          returns an error message
        when cached results is not latest
          raises and InvalidateReactiveCache error
  #find_coverage_reports
    when head pipeline has coverage reports
      when reactive cache worker is parsing results asynchronously
        returns status
      when reactive cache worker is inline
        returns status and data
        when an error occurrs
          returns an error message
        when cached results is not latest
          raises and InvalidateReactiveCache error
  #find_codequality_mr_diff_reports
    when head pipeline has coverage reports
      when reactive cache worker is parsing results asynchronously
        returns status
      when reactive cache worker is inline
        returns status and data
        when an error occurrs
          returns an error message
        when cached results is not latest
          raises and InvalidateReactiveCache error
  #compare_test_reports
    when head pipeline has test reports
      when reactive cache worker is parsing asynchronously
        returns status
      when reactive cache worker is inline
        returns status and data
        when cached results is not latest
          raises and InvalidateReactiveCache error
    when head pipeline does not have test reports
      returns status and error message
  #compare_accessibility_reports
    when head pipeline has accessibility reports
      when reactive cache worker is parsing results asynchronously
        returns parsing status
      when reactive cache worker is inline
        returns parsed status
        when an error occurrs
          returns an error status
        when cached result is not latest
          raises an InvalidateReactiveCache error
  #compare_codequality_reports
    when head pipeline has codequality report
      when reactive cache worker is parsing results asynchronously
        returns parsing status
      when reactive cache worker is inline
        returns parsed status
        when an error occurrs
          returns an error status
        when cached result is not latest
          raises an InvalidateReactiveCache error
  #all_commit_shas
    when merge request is persisted
      with a completely different branch
        behaves like returning all SHA
          returns all SHAs from all merge_request_diffs
      with a branch having no difference
        behaves like returning all SHA
          returns all SHAs from all merge_request_diffs
    when merge request is not persisted
      when compare commits are set in the service
        returns commits from compare commits temporary data
      when compare commits are not set in the service
        returns array with diff head sha element only
  #short_merge_commit_sha
    returns short id when there is a merge_commit_sha
    returns nil when there is no merge_commit_sha
  #merged_commit_sha
    returns nil when not merged
    when the MR is merged
      returns merge_commit_sha when there is a merge_commit_sha
      returns squash_commit_sha when there is a squash_commit_sha
      returns diff_head_sha when there are no merge_commit_sha and squash_commit_sha
  #short_merged_commit_sha
    when merged_commit_sha is nil
      returns nil
    when merged_commit_sha is present
      returns shortened merged_commit_sha
  #can_be_reverted?
    when there is no merge_commit for the MR
      returns false
    when the MR has been merged
      when there is no revert commit
        returns true
      when there is no merged_at for the MR
        returns true
      when there is a revert commit
        but merged at timestamp cannot be found
          returns false
        when the revert commit is mentioned in a note after the MR was merged
          returns false
        when there is no merged_at for the MR
          returns false
        when the revert commit is mentioned in a note just before the MR was merged
          returns false
        when the revert commit is mentioned in a note long before the MR was merged
          returns true
  #merged_at
    when MR is not merged
      returns nil
    when metrics has merged_at data
      returns metrics merged_at
    when merged event is persisted, but no metrics merged_at is persisted
      returns merged event creation date
    when no metrics or merge event exists
      when resource event for the merge exists
        returns the resource event creation date
      when system note for the merge exists
        returns the merging note creation date
  #participants
    includes the merge request author
    includes the authors of the notes
  cached counts
    updates when assignees change
  #merge_async
    enqueues MergeWorker job and updates merge_jid
  #rebase_async
    atomically enqueues a RebaseWorker job and updates rebase_jid
    refuses to enqueue a job if a rebase is in progress
    refuses to enqueue a job if the MR is not open
    raises ActiveRecord::LockWaitTimeout after 6 tries
  #mergeable?
    returns false if #mergeable_state? is false
    return true if #mergeable_state? is true and the MR #can_be_merged? is true
    return true if #mergeable_state? is true and the MR #can_be_merged? is false
    with skip_ci_check option
      mergeable_ci_state: false, skip_ci_check: false, expected_mergeable: false
        overrides mergeable_ci_state?
      mergeable_ci_state: false, skip_ci_check: true, expected_mergeable: true
        overrides mergeable_ci_state?
      mergeable_ci_state: true, skip_ci_check: false, expected_mergeable: true
        overrides mergeable_ci_state?
      mergeable_ci_state: true, skip_ci_check: true, expected_mergeable: true
        overrides mergeable_ci_state?
    with skip_discussions_check option
      mergeable_discussions_state: false, skip_discussions_check: false, expected_mergeable: false
        overrides mergeable_discussions_state?
      mergeable_discussions_state: false, skip_discussions_check: true, expected_mergeable: true
        overrides mergeable_discussions_state?
      mergeable_discussions_state: true, skip_discussions_check: false, expected_mergeable: true
        overrides mergeable_discussions_state?
      mergeable_discussions_state: true, skip_discussions_check: true, expected_mergeable: true
        overrides mergeable_discussions_state?
  #check_mergeability
    if the merge status is unchecked
      behaves like method that executes MergeabilityCheckService
        executes MergeabilityCheckService
        when async is true
          executes MergeabilityCheckService asynchronously
    if the merge status is checking
      behaves like method that executes MergeabilityCheckService
        executes MergeabilityCheckService
        when async is true
          executes MergeabilityCheckService asynchronously
    if the merge status is checked
      does not call MergeabilityCheckService
  #mergeable_state?
    when merge state caching is on
      behaves like for mergeable_state
        checks if merge request can be merged
        when not open
          returns false
        when working in progress
          returns false
        when broken
          returns false
        when failed
          when improved_mergeability_checks is on
            behaves like failed skip_ci_check
              when #mergeable_ci_state? is false
                returns false
                returns true when skipping ci check
              when #mergeable_discussions_state? is false
                returns false
                returns true when skipping discussions check
          when improved_mergeability_checks is off
            behaves like failed skip_ci_check
              when #mergeable_ci_state? is false
                returns false
                returns true when skipping ci check
              when #mergeable_discussions_state? is false
                returns false
                returns true when skipping discussions check
    when merge state caching is off
      behaves like for mergeable_state
        checks if merge request can be merged
        when not open
          returns false
        when working in progress
          returns false
        when broken
          returns false
        when failed
          when improved_mergeability_checks is on
            behaves like failed skip_ci_check
              when #mergeable_ci_state? is false
                returns false
                returns true when skipping ci check
              when #mergeable_discussions_state? is false
                returns false
                returns true when skipping discussions check
          when improved_mergeability_checks is off
            behaves like failed skip_ci_check
              when #mergeable_ci_state? is false
                returns false
                returns true when skipping ci check
              when #mergeable_discussions_state? is false
                returns false
                returns true when skipping discussions check
  #public_merge_status
    status: "cannot_be_merged_rechecking", public_status: "checking"
      is expected to eq "checking"
    status: "preparing", public_status: "checking"
      is expected to eq "checking"
    status: "checking", public_status: "checking"
      is expected to eq "checking"
    status: "cannot_be_merged", public_status: "cannot_be_merged"
      is expected to eq "cannot_be_merged"
  #head_pipeline_active?
    when project lacks a head_pipeline relation
      returns false
    when project has a head_pipeline relation
      accesses the value from the head_pipeline
  #actual_head_pipeline_success?
    when project lacks an actual_head_pipeline relation
      returns false
    when project has a actual_head_pipeline relation
      accesses the value from the actual_head_pipeline
  #actual_head_pipeline_active?
    when project lacks an actual_head_pipeline relation
      returns false
    when project has a actual_head_pipeline relation
      accesses the value from the actual_head_pipeline
  #mergeable_ci_state?
    when it is only allowed to merge when build is green
      and a failed pipeline is associated
        is expected to be falsey
      and a successful pipeline is associated
        is expected to be truthy
      and a skipped pipeline is associated
        is expected to be falsey
      when no pipeline is associated
        is expected to be falsey
    when it is only allowed to merge when build is green or skipped
      and a failed pipeline is associated
        is expected to be falsey
      and a successful pipeline is associated
        is expected to be truthy
      and a skipped pipeline is associated
        is expected to be truthy
      when no pipeline is associated
        is expected to be falsey
    when merges are not restricted to green builds
      and a failed pipeline is associated
        is expected to be truthy
      when no pipeline is associated
        is expected to be truthy
      and a skipped pipeline is associated
        is expected to be truthy
      when no pipeline is associated
        is expected to be truthy
  #mergeable_discussions_state?
    when project.only_allow_merge_if_all_discussions_are_resolved == true
      with all discussions resolved
        returns true
      with unresolved discussions
        returns false
      with no discussions
        returns true
    when project.only_allow_merge_if_all_discussions_are_resolved == false
      with unresolved discussions
        returns true
  #environments_for
    with multiple environments
      selects deployed environments
      selects latest deployed environment
    with environments on source project
      selects deployed environments
      with environments on target project
        selects deployed environments
    without a diff_head_commit
      returns an empty array
  #environments
    returns environments
    when pipeline is not associated with environments
      returns empty array
    when pipeline is not a pipeline for merge request
      returns empty relation
  #reload_diff
    calls MergeRequests::ReloadDiffsService#execute with correct params
    when using the after_update hook to update
      when the branches are updated
        uses the new heads to generate the diff
  #update_diff_discussion_positions
    updates diff discussion positions
    when resolve_outdated_diff_discussions is set
      calls MergeRequests::ResolvedDiscussionNotificationService
  #branch_merge_base_commit
    source and target branch exist
      is expected to eq "ae73cb07c9eeaf35924a10f713b364d32b2dd34f"
      is expected to be a kind of Commit
    when the target branch does not exist
      returns nil
  #diff_refs
    with diffs
      does not touch the repository
      returns expected diff_refs
      when importing
        returns MR diff_refs
  #source_project_missing?
    when the fork exists
      is expected to be falsey
    when the source project is the same as the target project
      is expected to be falsey
    when the fork does not exist
      returns true
  #merge_ongoing?
    returns true when the merge request is locked
    returns true when merge_id, MR is not merged and it has no running job
    returns false when merge_jid is nil
    returns false if MR is merged
    returns false if there is no merge job running
  #closed_or_merged_without_fork?
    when the merge request is closed
      returns false if the fork exist
      returns true if the fork does not exist
    when the merge request was merged
      returns false if the fork exist
      returns true if the fork does not exist
    when the merge request is open
      returns false
  #reopenable?
    when the merge request is closed
      returns true
      forked project
        returns false if unforked
        returns false if the source project is deleted
        returns false if the merge request is merged
    when the merge request is opened
      returns false
  #pipeline_coverage_delta
    when both source and target branches have coverage information
      returns the appropriate coverage delta
    when target branch does not have coverage information
      returns nil
    when source branch does not have coverage information
      returns nil for coverage_delta
    neither source nor target branch has coverage information
      returns nil for coverage_delta
  #use_merge_base_pipeline_for_comparison?
    when service class is Ci::CompareMetricsReportsService
      is expected to be truthy
    when service class is Ci::CompareCodequalityReportsService
      is expected to be truthy
    when service class is different
      is expected to be falsey
  #comparison_base_pipeline
    when service class is Ci::CompareCodequalityReportsService
      when merge request has a merge request pipeline
        returns the merge_base_pipeline
      when merge does not have a merge request pipeline
        returns the base_pipeline
    when service_class is different
      returns the base_pipeline
  #base_pipeline
    returns latest pipeline for the target branch
  #merge_base_pipeline
    returns a pipeline pointing to a commit on the target ref
  #has_commits?
    returns true when merge request diff has commits
    when commits_count is nil
      returns false
  #has_no_commits?
    returns true when merge request diff has 0 commits
  #merge_request_diff_for
    runs a single query on the initial call, and none afterwards
    with diff refs
      returns the diffs
    with a commit SHA
      returns the diffs
  #version_params_for
    when the diff refs are for an older merge request version
      returns the diff ID for the version to show
    when the diff refs are for a comparison between merge request versions
      returns the diff ID and start sha of the versions to compare
    when the diff refs are not for a merge request version
      returns nil
  #fetch_ref!
    fetches the ref correctly
  removing a merge request
    refreshes the number of open merge requests of the target project
  behaves like throttled touch
    #touch
      updates the updated_at timestamp
      updates the object at most once per minute
  state machine transitions
    #unlock_mr
      updates merge request head pipeline and sets merge_jid to nil
    #mark_as_unchecked
      when the status is unchecked
        is not a valid state transition
      when the status is checking
        is a valid state transition
      when the status is can_be_merged
        is a valid state transition
      when the status is cannot_be_merged_recheck
        is not a valid state transition
      when the status is cannot_be_merged
        is a valid state transition
      when the status is cannot_be_merged
        is a valid state transition
    transition to cannot_be_merged
      opened
        notifies conflict, but does not notify again if rechecking still results in cannot_be_merged
        notifies conflict, but does not notify again if rechecking still results in cannot_be_merged with async mergeability check
        notifies conflict, whenever newly unmergeable
        notifies conflict, whenever newly unmergeable with async mergeability check
        does not notify whenever merge request is newly unmergeable due to other reasons
      locked
        notifies conflict, but does not notify again if rechecking still results in cannot_be_merged
        notifies conflict, but does not notify again if rechecking still results in cannot_be_merged with async mergeability check
        notifies conflict, whenever newly unmergeable
        notifies conflict, whenever newly unmergeable with async mergeability check
        does not notify whenever merge request is newly unmergeable due to other reasons
      closed
        does not notify
      merged
        does not notify
      source branch is missing
        does not raise error
    check_state?
      indicates whether MR is still checking for mergeability
  #should_be_rebased?
    returns false for the same source and target branches
  #rebase_in_progress?
    rebase_jid: "foo", jid_valid: true, result: true
      is expected to eq true
    rebase_jid: "foo", jid_valid: false, result: false
      is expected to eq false
    rebase_jid: "", jid_valid: true, result: false
      is expected to eq false
    rebase_jid: nil, jid_valid: true, result: false
      is expected to eq false
  #allow_collaboration
    is false when pushing by a maintainer is not possible
    is true when pushing by a maintainer is possible
  #collaborative_push_possible?
    does not allow maintainer to push if the source project is the same as the target
    allows maintainer to push when both source and target are public
    is not available for protected branches
  #can_allow_collaboration?
    is false if the user does not have push access to the source project
    is true when the user has push access to the source project
  #merge_participants
    contains author
    when merge_when_pipeline_succeeds? is true
      when merge user is author
        author is not a project member
          is empty
        author is a project member
          contains author only
      when merge user and author are different users
        merge user is not a member
          contains author only
        both author and merge users are project members
          contains author and merge user
  .merge_request_ref?
    when ref is ref name of a branch
      is expected to be falsey
    when ref is HEAD ref path of a branch
      is expected to be falsey
    when ref is HEAD ref path of a merge request
      is expected to be truthy
    when ref is merge ref path of a merge request
      is expected to be truthy
  .merge_train_ref?
    when ref is ref name of a branch
      is expected to be falsey
    when ref is HEAD ref path of a branch
      is expected to be falsey
    when ref is HEAD ref path of a merge request
      is expected to be falsey
    when ref is merge ref path of a merge request
      is expected to be falsey
    when ref is train ref path of a merge request
      is expected to be truthy
  #cleanup_refs
    when removing all refs
      deletes all refs from the target project
    when removing only train ref
      deletes train ref from the target project
  .with_auto_merge_enabled
    is expected to contain exactly #<MergeRequest id:373 namespace1/project171!1>
  behaves like versioned description
    associations
      is expected to have many description_versions
    save_description_version
      when description was changed
        saves the old and new description for the first update
        only saves the new description for subsequent updates
        sets the new description version to `saved_description_version`
        clears `saved_description_version` after another save that does not change description
      when description was not changed
        does not save any description version
  #commits
    persisted merge request
      with a limit
        returns a limited number of commits
      without a limit
        returns all commits of the merge request diff
    new merge request
      compare commits
        without a limit
          returns all the compare commits
        with a limit
          returns a limited number of commits
  #recent_commits
    returns the safe number of commits
  #recent_visible_deployments
    returns visible deployments
    only returns a limited number of deployments
  #diffable_merge_ref?
    merge request can be merged
      merge_head diff is not created
        returns true
      merge_head diff is created
        returns true
        merge request is merged
          returns false
        merge request cannot be merged
          returns false
          display_merge_conflicts_in_diff is disabled
            returns false
  #predefined_variables
    caches all SQL-sourced data on the first call
  banzai_render_context
    sets the label_url_method in the context
  #head_pipeline_builds_with_coverage
    delegates to head_pipeline
  #merge_ref_head
    when merge_ref_sha is not present
      returns the commit based on merge ref path
    when merge_ref_sha is present
      returns the commit based on cached merge_ref_sha
  #allows_reviewers?
    returns true
  #update_and_mark_in_progress_merge_commit_sha
    updates commit ID
  #enabled_reports
    report_type: :sast, with_reports: :with_sast_reports, feature: :sast
      when head pipeline has reports
        is expected to be truthy
      when head pipeline does not have reports
        is expected to be falsy
    report_type: :secret_detection, with_reports: :with_secret_detection_reports, feature: :secret_detection
      when head pipeline has reports
        is expected to be truthy
      when head pipeline does not have reports
        is expected to be falsy
  #includes_ci_config?
    when diff_stats is nil
      is expected to eq false
    when diff_stats does not include the ci config path of the project
      is expected to eq false
    when diff_stats includes the ci config path of the project
      is expected to eq true
  .from_fork
    returns merge requests from forks only

ProjectPolicy
  does not include the read_issue permission when the issue author is not a member of the private project
  with no project feature
    returns false
  behaves like model with wiki policies
    container_level: :public, access_level: :enabled, membership: :admin, access: :all
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :maintainer, access: :maintainer
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :developer, access: :developer
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :reporter, access: :reporter
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :guest, access: :guest
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :non_member, access: :guest
      allows actions based on membership
    container_level: :public, access_level: :enabled, membership: :anonymous, access: :guest
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :admin, access: :all
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :maintainer, access: :maintainer
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :developer, access: :developer
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :reporter, access: :reporter
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :guest, access: :guest
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :public, access_level: :private, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :admin, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :maintainer, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :developer, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :reporter, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :guest, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :public, access_level: :disabled, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :admin, access: :all
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :maintainer, access: :maintainer
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :developer, access: :developer
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :reporter, access: :reporter
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :guest, access: :guest
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :non_member, access: :guest
      allows actions based on membership
    container_level: :internal, access_level: :enabled, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :admin, access: :all
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :maintainer, access: :maintainer
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :developer, access: :developer
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :reporter, access: :reporter
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :guest, access: :guest
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :private, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :admin, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :maintainer, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :developer, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :reporter, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :guest, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :internal, access_level: :disabled, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :admin, access: :all
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :maintainer, access: :maintainer
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :developer, access: :developer
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :reporter, access: :reporter
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :guest, access: :guest
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :private, access_level: :private, membership: :anonymous, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :admin, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :maintainer, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :developer, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :reporter, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :guest, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :non_member, access: nil
      allows actions based on membership
    container_level: :private, access_level: :disabled, membership: :anonymous, access: nil
      allows actions based on membership
  issues feature
    when the feature is disabled
      does not include the issues permissions
      disables boards and lists permissions
      when external tracker configured
        does not include the issues permissions
  merge requests feature
    disallows all permissions when the feature is disabled
  for a guest in a private project
    disallows the guest from reading the merge request and merge request iid
  pipeline feature
    for confirmed user
      allows modify pipelines
    for unconfirmed user
      disallows to modify pipelines
    destroy permission
      for developers
        prevents :destroy_pipeline
      for maintainers
        prevents :destroy_pipeline
      for project owner
        allows :destroy_pipeline
        on archived projects
          prevents :destroy_pipeline
        on archived pending_delete projects
          allows :destroy_pipeline
  builds feature
    when builds are disabled
      disallows all permissions except pipeline when the feature is disabled
    when builds are disabled only for some users
      disallows pipeline and commit_status permissions
  repository feature
    when user is a project member
      when it is disabled
        disallows all permissions
    when user is non-member
      when access level is private
        disallows all permissions
  behaves like project policies as anonymous
    abilities for public projects
      when a project has pending invites
        does not grant owner access
        behaves like archived project policies
          when the project is archived
            disables write actions on all relevant project features
            disables some other important write actions
            does not disable other abilities
    abilities for non-public projects
      is expected to be banned
  behaves like project policies as guest
    abilities for non-public projects
      is expected not to be allowed :set_note_created_at
      behaves like deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
      public builds enabled
        is expected to be allowed :read_pipeline
      when public builds disabled
        is expected not to be allowed :read_pipeline
      when builds are disabled
        is expected to be allowed :read_pipeline
  behaves like project policies as reporter
    abilities for non-public projects
      is expected not to be allowed :set_note_created_at
      behaves like deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
  behaves like project policies as developer
    abilities for non-public projects
      is expected not to be allowed :set_note_created_at
      behaves like deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
  behaves like project policies as maintainer
    abilities for non-public projects
      is expected not to be allowed :set_note_created_at
      behaves like deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
  behaves like project policies as owner
    abilities for non-public projects
      is expected to be allowed :set_note_created_at
      behaves like deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
  behaves like project policies as admin with admin mode
    abilities for non-public projects
      is expected to be allowed :set_note_created_at
      deploy token does not get confused with user
        is expected not to be allowed :set_note_created_at
      behaves like archived project policies
        when the project is archived
          disables write actions on all relevant project features
          disables some other important write actions
          does not disable other abilities
    abilities for all project visibility
      behaves like project private features with read_all_resources ability
        for public projects
          allows the download_code ability
        for internal projects
          allows the download_code ability
        for private projects
          allows the download_code ability
  behaves like project policies as admin without admin mode
    abilities for non-public projects
      is expected to be banned
      deploy token does not get confused with user
        is expected to be banned
  when a public project has merge requests allowing access
    does not allow pushing code
    allows pushing if the user is a member with push access to the target project
    disallows abilities to a maintainer if the merge request was closed
  behaves like clusterable policies
    #add_cluster?
      with a developer
        is expected not to be allowed :read_cluster
        is expected not to be allowed :add_cluster
        is expected not to be allowed :create_cluster
        is expected not to be allowed :update_cluster
        is expected not to be allowed :admin_cluster
      with a maintainer
        with no clusters
          is expected to be allowed :read_cluster
          is expected to be allowed :add_cluster
          is expected to be allowed :create_cluster
          is expected to be allowed :update_cluster
          is expected to be allowed :admin_cluster
  reading a project
    allows access when a user has read access to the repo
    never checks the external service
    with an external authorization service
      allows access when the external service allows it
      prevents all but seeing a public project in a list when access is denied
      passes the full path to external authorization for logging purposes
      with an admin
        when admin mode is enabled
          does not check the external service and allows access
        when admin mode is disabled
          checks the external service and allows access
  forking a project
    anonymous user
      is expected to be disallowed :fork_project
    project member
      guest
        is expected to be disallowed :fork_project
      reporter
        is expected to be allowed :fork_project
      developer
        is expected to be allowed :fork_project
      maintainer
        is expected to be allowed :fork_project
  update_max_artifacts_size
    when no user
      is expected not to be allowed :update_max_artifacts_size
    admin
      when admin mode is enabled
        is expected to be allowed :update_max_artifacts_size
      when admin mode is disabled
        is expected not to be allowed :update_max_artifacts_size
    guest
      is expected not to be allowed :update_max_artifacts_size
    reporter
      is expected not to be allowed :update_max_artifacts_size
    developer
      is expected not to be allowed :update_max_artifacts_size
    maintainer
      is expected not to be allowed :update_max_artifacts_size
    owner
      is expected not to be allowed :update_max_artifacts_size
  read_storage_disk_path
    when no user
      is expected not to be allowed :read_storage_disk_path
    admin
      when admin mode is enabled
        is expected to be allowed :read_storage_disk_path
      when admin mode is disabled
        is expected not to be allowed :read_storage_disk_path
    guest
      is expected not to be allowed :read_storage_disk_path
    reporter
      is expected not to be allowed :read_storage_disk_path
    developer
      is expected not to be allowed :read_storage_disk_path
    maintainer
      is expected not to be allowed :read_storage_disk_path
    owner
      is expected not to be allowed :read_storage_disk_path
  alert bot
    is expected to be allowed :reporter_access
    within a private project
      is expected to be allowed :admin_issue
  set_pipeline_variables
    when user is developer
      when project allows user defined variables
        is expected to be allowed :set_pipeline_variables
      when project restricts use of user defined variables
        is expected not to be allowed :set_pipeline_variables
    when user is maintainer
      when project allows user defined variables
        is expected to be allowed :set_pipeline_variables
      when project restricts use of user defined variables
        is expected to be allowed :set_pipeline_variables
  support bot
    with service desk disabled
      is expected to be allowed :public_access
      is expected not to be allowed :read_project
    with service desk enabled
      is expected to be allowed :read_issue
      when issues are protected members only
        is expected to be allowed :read_issue
  project bots
    project_bot_access
      when regular user and part of the project
        is expected not to be allowed :project_bot_access
      when project bot and not part of the project
        is expected not to be allowed :project_bot_access
      when project bot and part of the project
        is expected to be allowed :project_bot_access
    with resource access tokens
      is expected not to be allowed :create_resource_access_tokens
  read_prometheus_alerts
    with admin
      when admin mode is enabled
        is expected to be allowed :read_prometheus_alerts
      when admin mode is disabled
        is expected to be disallowed :read_prometheus_alerts
    with owner
      is expected to be allowed :read_prometheus_alerts
    with maintainer
      is expected to be allowed :read_prometheus_alerts
    with developer
      is expected to be disallowed :read_prometheus_alerts
    with reporter
      is expected to be disallowed :read_prometheus_alerts
    with guest
      is expected to be disallowed :read_prometheus_alerts
    with anonymous
      is expected to be disallowed :read_prometheus_alerts
  metrics_dashboard feature
    public project
      feature private
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be disallowed :metrics_dashboard
        with anonymous
          is expected to be disallowed :metrics_dashboard
      feature enabled
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with anonymous
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be disallowed :read_metrics_user_starred_dashboard
          is expected to be disallowed :create_metrics_user_starred_dashboard
    internal project
      feature private
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be disallowed :metrics_dashboard
        with anonymous
          is expected to be disallowed :metrics_dashboard
      feature enabled
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with anonymous
          is expected to be disallowed :metrics_dashboard
    private project
      feature private
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be disallowed :metrics_dashboard
        with anonymous
          is expected to be disallowed :metrics_dashboard
      feature enabled
        with reporter
          is expected to be allowed :metrics_dashboard
          is expected to be allowed :read_prometheus
          is expected to be allowed :read_deployment
          is expected to be allowed :read_metrics_user_starred_dashboard
          is expected to be allowed :create_metrics_user_starred_dashboard
        with guest
          is expected to be disallowed :metrics_dashboard
        with anonymous
          is expected to be disallowed :metrics_dashboard
    feature disabled
      with reporter
        is expected to be disallowed :metrics_dashboard
      with guest
        is expected to be disallowed :metrics_dashboard
      with anonymous
        is expected to be disallowed :metrics_dashboard
  deploy key access
    private project
      when a read deploy key is enabled in the project
        is expected to be allowed :download_code
        is expected to be disallowed :push_code
        is expected to be disallowed :read_project
      when a write deploy key is enabled in the project
        is expected to be allowed :download_code
        is expected to be allowed :push_code
        is expected to be disallowed :read_project
      when the deploy key is not enabled in the project
        is expected to be disallowed :download_code
        is expected to be disallowed :push_code
        is expected to be disallowed :read_project
  deploy token access
    a deploy token with read_package_registry scope
      is expected to be allowed :read_package
      is expected to be allowed :read_project
      is expected to be disallowed :create_package
      behaves like package access with repository disabled
        when repository is disabled
          is expected to be allowed :read_package
    a deploy token with write_package_registry scope
      is expected to be allowed :create_package
      is expected to be allowed :read_package
      is expected to be allowed :read_project
      is expected to be disallowed :destroy_package
      behaves like package access with repository disabled
        when repository is disabled
          is expected to be allowed :read_package
  create_web_ide_terminal
    with admin
      when admin mode enabled
        is expected to be allowed :create_web_ide_terminal
      when admin mode disabled
        is expected to be disallowed :create_web_ide_terminal
    with owner
      is expected to be allowed :create_web_ide_terminal
    with maintainer
      is expected to be allowed :create_web_ide_terminal
    with developer
      is expected to be disallowed :create_web_ide_terminal
    with reporter
      is expected to be disallowed :create_web_ide_terminal
    with guest
      is expected to be disallowed :create_web_ide_terminal
    with non member
      is expected to be disallowed :create_web_ide_terminal
    with anonymous
      is expected to be disallowed :create_web_ide_terminal
  read_repository_graphs
    when user can download_code
      is expected to be allowed :read_repository_graphs
    when user cannot download_code
      is expected to be disallowed :read_repository_graphs
  security configuration feature
    guest
      prevents reading security configuration
    reporter
      prevents reading security configuration
    developer
      allows reading security configuration
    maintainer
      allows reading security configuration
    owner
      allows reading security configuration
  infrastructure google cloud feature
    guest
      disallows managing google cloud
    reporter
      disallows managing google cloud
    developer
      disallows managing google cloud
    maintainer
      allows managing google cloud
    owner
      allows managing google cloud
  design permissions
    when design management is not available
      is expected not to be allowed :read_design_activity and :read_design
    when design management is available
      is expected to be allowed :read_design_activity and :read_design
  read_build_report_results
    when user can read_build and read_pipeline
      is expected to be allowed :read_build_report_results
    when user can read_build but cannot read_pipeline
      is expected to be disallowed :read_build_report_results
    when user cannot read_build but can read_pipeline
      is expected to be disallowed :read_build_report_results
    when user cannot read_build and cannot read_pipeline
      is expected to be disallowed :read_build_report_results
  read_package
    with admin
      is expected to be allowed :read_package
      behaves like package access with repository disabled
        when repository is disabled
          is expected to be allowed :read_package
    with owner
      is expected to be allowed :read_package
    with maintainer
      is expected to be allowed :read_package
    with developer
      is expected to be allowed :read_package
    with reporter
      is expected to be allowed :read_package
    with guest
      is expected to be allowed :read_package
    with non member
      is expected to be allowed :read_package
    with anonymous
      is expected to be allowed :read_package
  read_feature_flag
    with maintainer
      when repository is available
        is expected to be allowed :read_feature_flag
      when repository is disabled
        is expected to be disallowed :read_feature_flag
    with developer
      when repository is available
        is expected to be allowed :read_feature_flag
    with reporter
      when repository is available
        is expected to be disallowed :read_feature_flag
  read_analytics
    anonymous user
      is expected to be allowed :read_analytics
    with various analytics features
      when analytics is disabled for the project
        for guest user
          is expected to be disallowed :read_cycle_analytics
          is expected to be disallowed :read_insights
          is expected to be disallowed :read_repository_graphs
          is expected to be disallowed :read_ci_cd_analytics
        for reporter user
          is expected to be disallowed :read_cycle_analytics
          is expected to be disallowed :read_insights
          is expected to be disallowed :read_repository_graphs
          is expected to be disallowed :read_ci_cd_analytics
        for developer
          is expected to be disallowed :read_cycle_analytics
          is expected to be disallowed :read_insights
          is expected to be disallowed :read_repository_graphs
          is expected to be disallowed :read_ci_cd_analytics
      when analytics is private for the project
        for guest user
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be disallowed :read_repository_graphs
          is expected to be disallowed :read_ci_cd_analytics
        for reporter user
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be allowed :read_repository_graphs
          is expected to be allowed :read_ci_cd_analytics
        for developer
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be allowed :read_repository_graphs
          is expected to be allowed :read_ci_cd_analytics
      when analytics is enabled for the project
        for guest user
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be disallowed :read_repository_graphs
          is expected to be disallowed :read_ci_cd_analytics
        for reporter user
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be allowed :read_repository_graphs
          is expected to be allowed :read_ci_cd_analytics
        for developer
          is expected to be allowed :read_cycle_analytics
          is expected to be allowed :read_insights
          is expected to be allowed :read_repository_graphs
          is expected to be allowed :read_ci_cd_analytics
    project member
      guest
        is expected to be allowed :read_analytics
        without access to Analytics
          is expected to be disallowed :read_analytics
      reporter
        is expected to be allowed :read_analytics
        without access to Analytics
          is expected to be disallowed :read_analytics
      developer
        is expected to be allowed :read_analytics
        without access to Analytics
          is expected to be disallowed :read_analytics
      maintainer
        is expected to be allowed :read_analytics
        without access to Analytics
          is expected to be disallowed :read_analytics
  behaves like Self-managed Core resource access tokens
    with owner access
      create resource access tokens
        is expected to be allowed :create_resource_access_tokens
        when resource access token creation is not allowed
          is expected not to be allowed :create_resource_access_tokens
        when parent group has project access token creation disabled
          is expected not to be allowed :create_resource_access_tokens
        with a personal namespace project
          is expected to be allowed :create_resource_access_tokens
      read resource access tokens
        is expected to be allowed :read_resource_access_tokens
      destroy resource access tokens
        is expected to be allowed :destroy_resource_access_tokens
    with developer access
      create resource access tokens
        is expected not to be allowed :create_resource_access_tokens
      read resource access tokens
        is expected not to be allowed :read_resource_access_tokens
      destroy resource access tokens
        is expected not to be allowed :destroy_resource_access_tokens
  operations feature
    project_visibility: :public, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 20, role: :guest, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 20, role: :anonymous, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 10, role: :guest, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :public, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 20, role: :guest, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 20, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 10, role: :guest, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :internal, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 20, role: :guest, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 20, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 10, role: :guest, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the operation feature access level
    project_visibility: :private, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the operation feature access level
  access_security_and_compliance
    when the "Security & Compliance" is enabled
      when the role is owner
        is expected to be allowed :access_security_and_compliance
      when the role is maintainer
        is expected to be allowed :access_security_and_compliance
      when the role is developer
        is expected to be allowed :access_security_and_compliance
      with admin
        when admin mode enabled
          is expected to be allowed :access_security_and_compliance
        when admin mode disabled
          is expected to be disallowed :access_security_and_compliance
      when the role is reporter
        is expected to be disallowed :access_security_and_compliance
      when the role is guest
        is expected to be disallowed :access_security_and_compliance
      with non member
        is expected to be disallowed :access_security_and_compliance
      with anonymous
        is expected to be disallowed :access_security_and_compliance
    when the "Security & Compliance" is not enabled
      when the role is owner
        is expected to be disallowed :access_security_and_compliance
      when the role is maintainer
        is expected to be disallowed :access_security_and_compliance
      when the role is developer
        is expected to be disallowed :access_security_and_compliance
      when the role is reporter
        is expected to be disallowed :access_security_and_compliance
      when the role is guest
        is expected to be disallowed :access_security_and_compliance
      with admin
        when admin mode enabled
          is expected to be disallowed :access_security_and_compliance
        when admin mode disabled
          is expected to be disallowed :access_security_and_compliance
      with non member
        is expected to be disallowed :access_security_and_compliance
      with anonymous
        is expected to be disallowed :access_security_and_compliance
  when user is authenticated via CI_JOB_TOKEN
    project_visibility: :private, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :private, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :private, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: false
      enforces the expected permissions
    project_visibility: :private, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :private, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :private, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :private, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: false
      enforces the expected permissions
    project_visibility: :private, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: true, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: true, scope_project_type: :different, token_scope_enabled: true, result: false
      enforces the expected permissions
    project_visibility: :internal, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: true, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: true, scope_project_type: :different, token_scope_enabled: true, result: false
      enforces the expected permissions
    project_visibility: :internal, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :reporter, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :reporter, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :guest, external_user: false, scope_project_type: :same, token_scope_enabled: false, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: true, result: true
      enforces the expected permissions
    project_visibility: :public, user_role: :guest, external_user: false, scope_project_type: :different, token_scope_enabled: false, result: true
      enforces the expected permissions
  container_image policies
    project_visibility: :public, access_level: 20, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :guest, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 20, role: :anonymous, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :admin, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :owner, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :reporter, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :public, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :guest, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 20, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :admin, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :owner, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :reporter, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :internal, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 20, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :admin, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :owner, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :maintainer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :developer, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :reporter, allowed: true
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 10, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :admin, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :owner, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :maintainer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :developer, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :reporter, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :guest, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
    project_visibility: :private, access_level: 0, role: :anonymous, allowed: false
      allows/disallows the abilities based on the container_registry feature access level
      allows build_read_container_image to admins who are also team members
  update_runners_registration_token
    when anonymous
      is expected not to be allowed :update_runners_registration_token
    admin
      when admin mode is enabled
        is expected to be allowed :update_runners_registration_token
      when admin mode is disabled
        is expected to be disallowed :update_runners_registration_token
    guest
      is expected to be disallowed :update_runners_registration_token
    reporter
      is expected to be disallowed :update_runners_registration_token
    developer
      is expected to be disallowed :update_runners_registration_token
    maintainer
      is expected to be allowed :update_runners_registration_token
    owner
      is expected to be allowed :update_runners_registration_token

Git::BranchPushService
  Push branches
    new branch
      is expected to be truthy
      calls the after_push_commit hook
      calls the after_create_branch hook
    existing branch
      is expected to be truthy
      calls the after_push_commit hook
    rm branch
      is expected to be truthy
      calls the after_push_commit hook
      calls the after_remove_branch hook
  Pipelines
    creates a pipeline with the right parameters
    creates a new pipeline
    when pipeline has errors
      reports an error
      with push options
        sanitizes push options
    when .gitlab-ci.yml file is invalid
      persists an error pipeline
  Updates merge requests
    when pushing a new branch for the first time
  Updates git attributes
    for default branch
      calls the copy attributes method for the first push to the default branch
      calls the copy attributes method for changes to the default branch
    for non-default branch
      does not call copy attributes method
  Webhooks
    execute webhooks
      when pushing a branch for the first time
      when pushing a branch for the first time with default branch protection disabled
      when pushing a branch for the first time with default branch protection set to 'developers can push'
      when pushing a branch for the first time with an existing branch permission configured
      when pushing a branch for the first time with default branch protection set to 'developers can merge'
      when pushing new commits to existing branch
  cross-reference notes
    creates a note if a pushed commit mentions an issue
    only creates a cross-reference note if one doesn't already exist
    defaults to the pushing user if the commit's author is not known
    finds references in the first push to a non-default branch
  issue metrics
    while saving the 'first_mentioned_in_commit_at' metric for an issue
      sets the metric for referenced issues
      does not set the metric for non-referenced issues
  closing issues from pushed commits containing a closing reference
    to default branches
      closes issues
      adds a note indicating that the issue is now closed
      doesn't create additional cross-reference notes
    to non-default branches
      creates cross-reference notes
      doesn't close issues
    for jira issue tracker
      mentioning an issue
        initiates one api call to jira server to mention the issue
      closing an issue
        using right markdown
          initiates one api call to jira server to close the issue
          initiates one api call to jira server to comment on the issue
        using internal issue reference
          when internal issues are disabled
            does not initiates one api call to jira server to close the issue
            does not initiates one api call to jira server to comment on the issue
          when internal issues are enabled
            initiates one api call to jira server to close the jira issue
            initiates one api call to jira server to comment on the jira issue
            closes the internal issue
            adds a note indicating that the issue is now closed
  empty project
    push to first branch updates HEAD
  CI environments
    create branch
      does nothing
    update branch
      does nothing
    delete branch
      stops environments
  artifacts
    create branch
      does nothing
    update branch
      does nothing
    delete branch
      unlocks artifacts
  Hooks
    run on a branch
      delegates to Git::BranchHooksService
    run on a tag
      does nothing
  Jira Connect hooks
    with a Jira subscription
      branch name contains Jira issue key
        behaves like enqueues Jira sync worker
          aggregate_failures
      commit message contains Jira issue key
        behaves like enqueues Jira sync worker
          aggregate_failures
      branch name and commit message does not contain Jira issue key
        behaves like does not enqueue Jira sync worker
          is expected not to change `Array#size`
    without a Jira subscription
      behaves like does not enqueue Jira sync worker
        is expected not to change `Array#size`

GroupMembersFinder#execute
  relations
    raises an error if a non-supported relation type is used
    subject_relations: nil, subject_group: :group, expected_members: [:user1_group, :user2_group, :user3_group, :user4_group]
      returns correct members
    subject_relations: [:direct], subject_group: :group, expected_members: [:user1_group, :user2_group, :user3_group, :user4_group]
      returns correct members
    subject_relations: [:inherited], subject_group: :group, expected_members: []
      returns correct members
    subject_relations: [:descendants], subject_group: :group, expected_members: [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
      returns correct members
    subject_relations: [:direct, :inherited], subject_group: :group, expected_members: [:user1_group, :user2_group, :user3_group, :user4_group]
      returns correct members
    subject_relations: [:direct, :descendants], subject_group: :group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:descendants, :inherited], subject_group: :group, expected_members: [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
      returns correct members
    subject_relations: [:direct, :descendants, :inherited], subject_group: :group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: nil, subject_group: :sub_group, expected_members: [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct], subject_group: :sub_group, expected_members: [:user1_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
      returns correct members
    subject_relations: [:inherited], subject_group: :sub_group, expected_members: [:user1_group, :user2_group, :user3_group, :user4_group]
      returns correct members
    subject_relations: [:descendants], subject_group: :sub_group, expected_members: [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
      returns correct members
    subject_relations: [:direct, :inherited], subject_group: :sub_group, expected_members: [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct, :descendants], subject_group: :sub_group, expected_members: [:user1_sub_sub_group, :user2_sub_group, :user3_sub_group, :user4_sub_group]
      returns correct members
    subject_relations: [:descendants, :inherited], subject_group: :sub_group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct, :descendants, :inherited], subject_group: :sub_group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: nil, subject_group: :sub_sub_group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct], subject_group: :sub_sub_group, expected_members: [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
      returns correct members
    subject_relations: [:inherited], subject_group: :sub_sub_group, expected_members: [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:descendants], subject_group: :sub_sub_group, expected_members: []
      returns correct members
    subject_relations: [:direct, :inherited], subject_group: :sub_sub_group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct, :descendants], subject_group: :sub_sub_group, expected_members: [:user1_sub_sub_group, :user2_sub_sub_group, :user3_sub_sub_group, :user4_sub_sub_group]
      returns correct members
    subject_relations: [:descendants, :inherited], subject_group: :sub_sub_group, expected_members: [:user1_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
    subject_relations: [:direct, :descendants, :inherited], subject_group: :sub_sub_group, expected_members: [:user1_sub_sub_group, :user2_group, :user3_sub_group, :user4_group]
      returns correct members
  search
    returns searched members if requested
    returns nothing if search only in inherited relation
    returns searched member only from sub_group if search only in inherited relation
  filter by two-factor
    returns members with two-factor auth if requested by owner
    returns members without two-factor auth if requested by owner
    returns direct members with two-factor auth if requested by owner
    returns inherited members with two-factor auth if requested by owner
    returns direct members without two-factor auth if requested by owner
    returns inherited members without two-factor auth if requested by owner

DesignManagement::DesignV432x230Uploader
  resizes images
  behaves like builds correct paths
    #store_dir
      behaves like matches the method pattern
        is expected to match /uploads\/-\/system\/design_management\/action\/image_v432x230\//
    #cache_dir
      behaves like matches the method pattern
        example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
    #work_dir
      behaves like matches the method pattern
        example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
    #upload_path
      behaves like matches the method pattern
        is expected to match /uploads\/-\/system\/design_management\/action\/image_v432x230\//
    #relative_path
      is relative (PENDING: Path not set, skipping.)
    .absolute_path
      behaves like matches the method pattern
        is expected to match /\/builds\/gitlab-org\/gitlab\/tmp\/tests\/public\/uploads\/-\/system\/design_management\/action\/image_v432x230\//
    .base_dir
      behaves like matches the method pattern
        example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
    path traversal exploits
      throws an exception
  object_store is REMOTE
    behaves like builds correct paths
      #store_dir
        behaves like matches the method pattern
          is expected to match /design_management\/action\/image_v432x230\//
      #cache_dir
        behaves like matches the method pattern
          example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
      #work_dir
        behaves like matches the method pattern
          example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
      #upload_path
        behaves like matches the method pattern
          is expected to match /design_management\/action\/image_v432x230\//
      #relative_path
        is relative (PENDING: Path not set, skipping.)
      .absolute_path
        behaves like matches the method pattern
          example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
      .base_dir
        behaves like matches the method pattern
          example at ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8 (PENDING: No pattern provided, skipping.)
      path traversal exploits
        throws an exception
  #migrate!
    behaves like migrates
      returns corresponding file type
      does nothing when migrating to the current store
      migrate to the specified store
      removes the original file after the migration
      can access to the original file during migration
      when migrate! is not occupied by another process
        executes migrate!
        executes use_file
      when migrate! is occupied by another process
        does not execute migrate!
        does not execute use_file
      migration is unsuccessful
        when the store is not supported
          does not update the object_store
          does not delete the original file
        upon a fog failure
          does not update the object_store
          does not delete the original file
        upon a database failure
          does not update the object_store
          does not delete the original file
    behaves like migrates
      returns corresponding file type
      does nothing when migrating to the current store
      migrate to the specified store
      removes the original file after the migration
      can access to the original file during migration
      when migrate! is not occupied by another process
        executes migrate!
        executes use_file
      when migrate! is occupied by another process
        does not execute migrate!
        does not execute use_file
      migration is unsuccessful
        when the store is not supported
          does not update the object_store
          does not delete the original file
        upon a fog failure
          does not update the object_store
          does not delete the original file
        upon a database failure
          does not update the object_store
          does not delete the original file
  accept whitelist file content type
    mime_type: "image/png"
      behaves like accepted carrierwave upload
        will accept upload
        will cache uploaded file
    mime_type: "image/jpeg"
      behaves like accepted carrierwave upload
        will accept upload
        will cache uploaded file
    mime_type: "image/bmp"
      behaves like accepted carrierwave upload
        will accept upload
        will cache uploaded file
    mime_type: "image/gif"
      behaves like accepted carrierwave upload
        will accept upload
        will cache uploaded file
  upload non-whitelisted file content type
    behaves like denied carrierwave upload
      will deny upload
  upload misnamed non-whitelisted file content type
    behaves like denied carrierwave upload
      will deny upload

Gitlab::UsageDataMetrics
  .uncached_data
    with instrumentation_class
      includes top level keys
      includes counts keys
      includes counts keys
      includes usage_activity_by_stage keys
      includes usage_activity_by_stage_monthly keys
      includes settings keys
      Redis_HLL_counters
        is included in the Service Ping hash structure
  .suggested_names
    includes Service Ping suggested names

Ci::Runner
  behaves like having unique enum values
    has unique values in "access_level"
    has unique values in "runner_type"
    has unique values in "executor_type"
  behaves like it has loose foreign keys
    has at least one loose foreign key definition
    has the deletion trigger present
    records record deletions
    cleans up record deletions
  groups association
    does not create a cross-database query
  validation
    is expected to validate that :access_level cannot be empty/falsy
    is expected to validate that :runner_type cannot be empty/falsy
    when runner is not allowed to pick untagged jobs
      when runner does not have tags
        is not valid
      when runner has tags
        is valid
    #exactly_one_group
      disallows assigning group if already assigned to a group
    runner_type validations
      disallows assigning group to project_type runner
      disallows assigning group to instance_type runner
      disallows assigning project to group_type runner
      disallows assigning project to instance_type runner
      fails to save a group assigned to a project runner even if the runner is already saved
      when runner has config
        is valid
      when runner has an invalid config
        is invalid
    cost factors validations
      dissalows :private_projects_minutes_cost_factor being nil
      dissalows :public_projects_minutes_cost_factor being nil
      dissalows :private_projects_minutes_cost_factor being negative
      dissalows :public_projects_minutes_cost_factor being negative
  constraints
    .UPDATE_CONTACT_COLUMN_EVERY
  #access_level
    when creating new runner and access_level is nil
      object is invalid
    when creating new runner and access_level is defined in enum
      object is valid
    when creating new runner and access_level is not defined in enum
      raises an error
  .instance_type
    returns only shared runners
  .belonging_to_project
    returns the specific project runner
  .belonging_to_parent_group_of_project
    returns the specific group runner
    with a parent group with a runner
      returns the group runner from the parent group
  .owned_or_instance_wide
    returns a globally shared, a project specific and a group specific runner
  #display_name
    returns the description if it has a value
    returns the token if it does not have a description
    returns the token if the description is an empty string
  #assign_to
    with shared_runner
      transitions shared runner to project runner and assigns project
    with group runner
      raises an error
  .recent
    is expected to eq [#<Ci::Runner id: 21, token: nil, created_at: "2021-10-14 01:40:14.474282524 +0000", updated_at: "202...tor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>]
  .active
    with active_value set to false
      returns inactive runners
    with active_value set to true
      returns active runners
  .paused
    returns inactive runners
  .stale
    returns stale runners
  #stale?
    table tests
      created_at: nil, contacted_at: nil, expected_stale?: false
        no cache value
          is expected to eq false
        with cache value
          is expected to eq false
      created_at: Tue, 14 Sep 2021 01:28:10.156405855 UTC +00:00, contacted_at: Tue, 14 Sep 2021 01:28:11.155628164 UTC +00:00, expected_stale?: true
        no cache value
          is expected to eq true
        with cache value
          is expected to eq true
      created_at: Tue, 14 Sep 2021 01:28:10.156728055 UTC +00:00, contacted_at: Tue, 14 Sep 2021 02:28:11.156801325 UTC +00:00, expected_stale?: false
        no cache value
          is expected to eq false
        with cache value
          is expected to eq false
      created_at: Tue, 14 Sep 2021 01:28:10.156868225 UTC +00:00, contacted_at: nil, expected_stale?: true
        no cache value
          is expected to eq true
        with cache value
          is expected to eq true
      created_at: Tue, 14 Sep 2021 02:28:11.156936165 UTC +00:00, contacted_at: nil, expected_stale?: false
        no cache value
          is expected to eq false
        with cache value
          is expected to eq false
  .online
    is expected to contain exactly #<Ci::Runner id: 46, token: nil, created_at: "2021-12-14 01:40:15.283654030 +0000", updated_at: "2021...ctor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>
  #online?
    no cache value
      never contacted
        is expected to be falsey
      contacted long time ago
        is expected to be falsey
      contacted 1s ago
        is expected to be truthy
    with cache value
      contacted long time ago
        is expected to be falsey
      contacted 1s ago
        is expected to be truthy
  .offline
    is expected to eq [#<Ci::Runner id: 52, token: nil, created_at: "2021-12-14 01:40:15.511772684 +0000", updated_at: "202...tor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>]
  #tick_runner_queue
    sticks the runner to the primary and calls the original method
  #can_pick?
    a different runner
      cannot handle builds
    when runner does not have tags
      can handle builds without tags
      cannot handle build with tags
    when runner has tags
      when runner can pick untagged jobs
        can handle builds without tags
        behaves like tagged build picker
          can handle build with matching tags
          cannot handle build without matching tags
      when runner cannot pick untagged jobs
        cannot handle builds without tags
        behaves like tagged build picker
          can handle build with matching tags
          cannot handle build without matching tags
    when runner is shared
      can handle builds
      does not query for owned or instance runners
      when runner is locked
        can handle builds
      when feature flag ci_runners_short_circuit_assignable_for is disabled
        does not query for owned or instance runners
    when runner is not shared
      when runner is assigned to a project
        can handle builds
      when runner is assigned to another project
        cannot handle builds
      when runner is assigned to a group
        can handle builds
        knows namespace id it is assigned to
    when access_level of runner is not_protected
      when build is protected
        is expected to be truthy
      when build is unprotected
        is expected to be truthy
    when access_level of runner is ref_protected
      when build is protected
        is expected to be truthy
      when build is unprotected
        is expected to be falsey
    matches tags
      run_untagged: true, runner_tags: [], build_tags: [], result: true
        is expected to eq true
      run_untagged: true, runner_tags: [], build_tags: ["a"], result: false
        is expected to eq false
      run_untagged: true, runner_tags: ["a", "b"], build_tags: ["a"], result: true
        is expected to eq true
      run_untagged: true, runner_tags: ["a"], build_tags: ["a", "b"], result: false
        is expected to eq false
      run_untagged: true, runner_tags: ["a"], build_tags: ["a"], result: true
        is expected to eq true
      run_untagged: false, runner_tags: ["a"], build_tags: ["a"], result: true
        is expected to eq true
      run_untagged: false, runner_tags: ["b"], build_tags: ["a"], result: false
        is expected to eq false
      run_untagged: false, runner_tags: ["a", "b"], build_tags: ["a"], result: true
        is expected to eq true
  #status
    never connected
      with legacy_mode enabled
        is expected to eq :not_connected
      with legacy_mode disabled
        is expected to eq :stale
      created recently
        is expected to eq :never_contacted
    inactive but online
      with legacy_mode enabled
        is expected to eq :paused
      with legacy_mode disabled
        is expected to eq :online
    contacted 1s ago
      is expected to eq :online
    contacted recently
      is expected to eq :offline
    contacted long time ago
      with legacy_mode enabled
        is expected to eq :offline
      with legacy_mode disabled
        is expected to eq :stale
  #deprecated_rest_status
    never connected
      is expected to eq :not_connected
    contacted 1s ago
      is expected to eq :online
    contacted long time ago
      is expected to eq :offline
    inactive
      is expected to eq :paused
  #tick_runner_queue
    returns a new last_update value
  #ensure_runner_queue_value
    sets a new last_update value when it is called the first time
    does not change if it is not expired and called again
    updates runner queue after changing editable value
      sets a new last_update value
    does not update runner value after save
      has an old last_update value
  #heartbeat
    when database was updated recently
      updates cache
    when database was not updated recently
      updates redis cache and database
      with invalid runner
        still updates redis cache and database
      with custom executor
        updates with expected executor type
      with shell executor
        updates with expected executor type
      with docker executor
        updates with expected executor type
      with docker-windows executor
        updates with expected executor type
      with docker-ssh executor
        updates with expected executor type
      with ssh executor
        updates with expected executor type
      with parallels executor
        updates with expected executor type
      with virtualbox executor
        updates with expected executor type
      with docker+machine executor
        updates with expected executor type
      with docker-ssh+machine executor
        updates with expected executor type
      with kubernetes executor
        updates with expected executor type
      with some-unknown-type executor
        updates with expected executor type
  #destroy
    when there is a tick in the queue
      cleans up the queue
  .assignable_for
    with already assigned project
      is expected to be empty
    with a different project
      is expected to include #<Ci::Runner id: 109, token: nil, created_at: "2021-12-14 01:40:26.124911400 +0000", updated_at: "202...ctor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>
      is expected not to include #<Ci::Runner id: 115, token: nil, created_at: "2021-12-14 01:40:27.077950427 +0000", updated_at: "202...ctor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>
      is expected not to include #<Ci::Runner id: 118, token: nil, created_at: "2021-12-14 01:40:27.859738904 +0000", updated_at: "202...ctor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>
      is expected not to include #<Ci::Runner id: 124, token: nil, created_at: "2021-12-14 01:40:28.824683900 +0000", updated_at: "202...ctor: 0.0, private_projects_minutes_cost_factor: 1.0, config: {}, executor_type: nil, tag_list: nil>
  belongs_to_one_project?
    returns false if there are two projects runner assigned to
    returns true
  #belongs_to_more_than_one_project?
    project runner
      two projects assigned to runner
        returns true
      one project assigned to runner
        returns false
    group runner
      returns false
    shared runner
      returns false
  #has_tags?
    when runner has tags
      is expected to have tags
    when runner does not have tags
      is expected not to have tags
  .search
    returns runners with a matching token
    does not return runners with a partially matching token
    does not return runners with a matching token with different casing
    returns runners with a matching description
    returns runners with a partially matching description
    returns runners with a matching description regardless of the casing
  #assigned_to_group?
    when project runner
      is expected to be falsey
    when shared runner
      is expected to be falsey
    when group runner
      is expected to be truthy
  #assigned_to_project?
    when group runner
      is expected to be falsey
    when shared runner
      is expected to be falsey
    when project runner
      is expected to be truthy
  #pick_build!
    runner can pick the build
      calls #tick_runner_queue
    runner cannot pick the build
      does not call #tick_runner_queue
    build picking improvement
      does not check if the build is assignable to a runner
  project runner without projects is destroyable
    does not have projects
    can be destroyed
  .order_by
    supports ordering by the contact date
    supports ordering by the creation date
  .runner_matchers
    deduplicates on runner_type
      creates two matchers
    deduplicates on public_projects_minutes_cost_factor
      creates two matchers
    deduplicates on private_projects_minutes_cost_factor
      creates two matchers
    deduplicates on run_untagged
      creates two matchers
    deduplicates on access_level
      creates two matchers
    deduplicates on tag_list
      creates two matchers
    with runner_ids
      includes runner_ids
  #runner_matcher
    is expected to eq [1247]
    is expected to eq "instance_type"
    is expected to eq 0.0
    is expected to eq 1.0
    is expected to eq true
    is expected to eq "not_protected"
    is expected to contain exactly "tag1" and "tag2"
  #uncached_contacted_at
    is expected to eq 2021-12-14 00:40:36.000000000 +0000
  .belonging_to_group
    behaves like returns group runners
      returns the specific group runner
      runner belonging to parent group
        when include_parent option is passed
          returns the group runner from the parent group
        when include_parent option is not passed
          does not return the group runner from the parent group
    when feature flag :linear_runner_ancestor_scopes is disabled
      behaves like returns group runners
        returns the specific group runner
        runner belonging to parent group
          when include_parent option is passed
            returns the group runner from the parent group
          when include_parent option is not passed
            does not return the group runner from the parent group

ProjectStatisticsPolicy
  #rules
    project_type: :public, user_type: :unauthenticated, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :public, user_type: :non_member, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :public, user_type: :guest, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :public, user_type: :reporter, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :public, user_type: :developer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :public, user_type: :maintainer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :private, user_type: :unauthenticated, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :private, user_type: :non_member, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :private, user_type: :guest, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :private, user_type: :reporter, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :private, user_type: :developer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :private, user_type: :maintainer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :internal, user_type: :unauthenticated, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :internal, user_type: :non_member, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :internal, user_type: :guest, outcome: false
      is expected to eq false
      when the user is external
        is expected to eq false
    project_type: :internal, user_type: :reporter, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :internal, user_type: :developer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true
    project_type: :internal, user_type: :maintainer, outcome: true
      is expected to eq true
      when the user is external
        is expected to eq true

MergeRequests::MergeService
  #execute
    valid params
      is expected to be valid
      is expected to be merged
      persists merge_commit_sha and nullifies in_progress_merge_commit_sha
      does not update squash_commit_sha if it is not a squash
      sends email to user2 about merge of new merge_request
      note creation
        creates resource state event about merge_request merge
      when squashing
        merges the merge request with squashed commits
        persists squash_commit_sha
    running the service multiple time
      is idempotent
    when an invalid sha is passed
      does not merge the MR
    when the `sha` param is missing
      returns the error
    closes related issues
      closes GitLab issue tracker issues
      with Jira integration
        closes issues on Jira issue tracker
        wrong issue markdown
          does not close issues on Jira issue tracker
    closes related todos
      is expected to be done
    source branch removal
      when the source branch is protected
        does not delete the source branch
      when the source branch is the default branch
        does not delete the source branch
      when the source branch can be removed
        when MR author set the source branch to be removed
          removes the source branch using the author user
          when the merger set the source branch not to be removed
            does not delete the source branch
        when MR merger set the source branch to be removed
          removes the source branch using the current user
    error handling
      logs and saves error if there is an exception
      logs and saves error if user is not authorized
      logs and saves error if there is an PreReceiveError exception
      logs and saves error if commit is not created
      when source is missing
        logs and saves error
      when squashing is required
        raises an error if squashing is not done
      when squashing
        logs and saves error if there is an error when squashing
        logs and saves error if there is an PreReceiveError exception
        when fast-forward merge is not allowed
          logs and saves error if merge is semi-linear only
          logs and saves error if merge is ff only
      when not mergeable
        with failing CI
          logs and saves error
        with unresolved discussions
          logs and saves error
          when passing `skip_discussions_check: true` as `options` parameter
            merges the merge request
    when the other sidekiq worker has already been running
      does not execute service

Boards::Lists::MoveService
  #execute
    when board parent is a project
      behaves like lists move service
        keeps position of lists when list type is closed
        when list type is set to label
          keeps position of lists when new position is nil
          keeps position of lists when new position is equal to old position
          keeps position of lists when new position is negative
          keeps position of lists when new position is equal to number of labels lists
          keeps position of lists when new position is greater than number of labels lists
          increments position of intermediate lists when new position is equal to first position
          decrements position of intermediate lists when new position is equal to last position
          decrements position of intermediate lists when new position is greater than old position
          increments position of intermediate lists when new position is lower than old position
    when board parent is a group
      behaves like lists move service
        keeps position of lists when list type is closed
        when list type is set to label
          keeps position of lists when new position is nil
          keeps position of lists when new position is equal to old position
          keeps position of lists when new position is negative
          keeps position of lists when new position is equal to number of labels lists
          keeps position of lists when new position is greater than number of labels lists
          increments position of intermediate lists when new position is equal to first position
          decrements position of intermediate lists when new position is equal to last position
          decrements position of intermediate lists when new position is greater than old position
          increments position of intermediate lists when new position is lower than old position

BlobPolicy
  project_level: :public, feature_access_level: :enabled, membership: :admin, admin_mode: true, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :enabled, membership: :reporter, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :enabled, membership: :guest, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :enabled, membership: :anonymous, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :private, membership: :admin, admin_mode: true, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :private, membership: :admin, admin_mode: false, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :private, membership: :reporter, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :private, membership: :guest, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :public, feature_access_level: :private, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :private, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :disabled, membership: :reporter, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :disabled, membership: :guest, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :disabled, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :public, feature_access_level: :disabled, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :admin, admin_mode: true, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :admin, admin_mode: false, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :reporter, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :guest, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :non_member, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :enabled, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :admin, admin_mode: true, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :admin, admin_mode: false, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :reporter, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :guest, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :private, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :disabled, membership: :reporter, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :disabled, membership: :guest, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :disabled, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :internal, feature_access_level: :disabled, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :private, membership: :admin, admin_mode: true, expected_count: 1
    grants permission
  project_level: :private, feature_access_level: :private, membership: :admin, admin_mode: false, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :private, membership: :reporter, admin_mode: nil, expected_count: 1
    grants permission
  project_level: :private, feature_access_level: :private, membership: :guest, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :private, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :private, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :disabled, membership: :reporter, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :disabled, membership: :guest, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :disabled, membership: :non_member, admin_mode: nil, expected_count: 0
    grants permission
  project_level: :private, feature_access_level: :disabled, membership: :anonymous, admin_mode: nil, expected_count: 0
    grants permission

Integrations::Bamboo
  Validations
    when active
      is expected to validate that :build_key cannot be empty/falsy
      is expected to validate that :bamboo_url cannot be empty/falsy
      behaves like issue tracker integration URL attribute
        is expected to allow :bamboo_url to be ‹"https://example.com"›
        is expected not to allow :bamboo_url to be ‹"example.com"›
        is expected not to allow :bamboo_url to be ‹"ftp://example.com"›
        is expected not to allow :bamboo_url to be ‹"herp-and-derp"›
      #username
        does not validate the presence of username if password is nil
        validates the presence of username if password is present
      #password
        does not validate the presence of password if username is nil
        validates the presence of password if username is present
    when inactive
      is expected not to validate that :build_key cannot be empty/falsy
      is expected not to validate that :bamboo_url cannot be empty/falsy
      is expected not to validate that :username cannot be empty/falsy
      is expected not to validate that :password cannot be empty/falsy
  Callbacks
    before_validation :reset_password
      saves password if new url is set together with password when no password was previously set
      when a password was previously set
        resets password if url changed
        does not reset password if username changed
        does not reset password if new url is set together with password, even if it's the same password
  #execute
    runs update and build action
  #build_page
    returns the contents of the reactive cache
  #commit_status
    returns the contents of the reactive cache
  #calculate_reactive_cache
    when Bamboo API returns single result
      behaves like reactive cache calculation
        #build_page
          returns a specific URL when status is 500
          returns a specific URL when response has no results
          returns a build URL when bamboo_url has no trailing slash
          bamboo_url has trailing slash
            returns a build URL
        #commit_status
          sets commit status to :error when status is 500
          sets commit status to "pending" when status is 404
          sets commit status to "pending" when response has no results
          sets commit status to "success" when build state contains Success
          sets commit status to "failed" when build state contains Failed
          sets commit status to "pending" when build state contains Pending
          sets commit status to :error when build state is unknown
          sets commit status to :error with a Net::OpenTimeout error
          sets commit status to :error with a Net::ReadTimeout error
          sets commit status to :error with a Net::WriteTimeout error
          sets commit status to :error with a Gitlab::HTTP::ReadTotalTimeout error
          sets commit status to :error with a EOFError error
          sets commit status to :error with a SocketError error
          sets commit status to :error with a OpenSSL::SSL::SSLError error
          sets commit status to :error with a OpenSSL::OpenSSLError error
          sets commit status to :error with a Errno::ECONNRESET error
          sets commit status to :error with a Errno::ECONNREFUSED error
          sets commit status to :error with a Errno::EHOSTUNREACH error
          sets commit status to :error with a Errno::ENETUNREACH error
          sets commit status to :error with a Gitlab::HTTP::BlockedUrlError error
          sets commit status to :error with a Gitlab::HTTP::RedirectionTooDeep error
    when Bamboo API returns an array of results and we only consider the last one
      behaves like reactive cache calculation
        #build_page
          returns a specific URL when status is 500
          returns a specific URL when response has no results
          returns a build URL when bamboo_url has no trailing slash
          bamboo_url has trailing slash
            returns a build URL
        #commit_status
          sets commit status to :error when status is 500
          sets commit status to "pending" when status is 404
          sets commit status to "pending" when response has no results
          sets commit status to "success" when build state contains Success
          sets commit status to "failed" when build state contains Failed
          sets commit status to "pending" when build state contains Pending
          sets commit status to :error when build state is unknown
          sets commit status to :error with a Net::OpenTimeout error
          sets commit status to :error with a Net::ReadTimeout error
          sets commit status to :error with a Net::WriteTimeout error
          sets commit status to :error with a Gitlab::HTTP::ReadTotalTimeout error
          sets commit status to :error with a EOFError error
          sets commit status to :error with a SocketError error
          sets commit status to :error with a OpenSSL::SSL::SSLError error
          sets commit status to :error with a OpenSSL::OpenSSLError error
          sets commit status to :error with a Errno::ECONNRESET error
          sets commit status to :error with a Errno::ECONNREFUSED error
          sets commit status to :error with a Errno::EHOSTUNREACH error
          sets commit status to :error with a Errno::ENETUNREACH error
          sets commit status to :error with a Gitlab::HTTP::BlockedUrlError error
          sets commit status to :error with a Gitlab::HTTP::RedirectionTooDeep error

Gitlab::Ci::Config::Entry::Job
  behaves like with inheritable CI config
    does prepend an Inheritable mixin
    all inheritable entries are covered
    all entries do have inherit flag
    for non-inheritable entries
      entry_key: :stage
        inheritable_class does not define entry
      entry_key: :only
        inheritable_class does not define entry
      entry_key: :except
        inheritable_class does not define entry
      entry_key: :rules
        inheritable_class does not define entry
      entry_key: :variables
        inheritable_class does not define entry
      entry_key: :inherit
        inheritable_class does not define entry
      entry_key: :script
        inheritable_class does not define entry
      entry_key: :type
        inheritable_class does not define entry
      entry_key: :needs
        inheritable_class does not define entry
      entry_key: :environment
        inheritable_class does not define entry
      entry_key: :coverage
        inheritable_class does not define entry
      entry_key: :release
        inheritable_class does not define entry
      entry_key: :parallel
        inheritable_class does not define entry
      entry_key: :allow_failure
        inheritable_class does not define entry
      entry_key: :dast_configuration
        inheritable_class does not define entry
      entry_key: :secrets
        inheritable_class does not define entry
    for inheritable entries
      entry_key: :before_script, entry_class: Gitlab::Ci::Config::Entry::Script
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :after_script, entry_class: Gitlab::Ci::Config::Entry::Script
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :cache, entry_class: Gitlab::Ci::Config::Entry::Caches
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :image, entry_class: Gitlab::Ci::Config::Entry::Image
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :services, entry_class: Gitlab::Ci::Config::Entry::Services
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :interruptible, entry_class: Gitlab::Config::Entry::Boolean
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :timeout, entry_class: Gitlab::Ci::Config::Entry::Timeout
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :retry, entry_class: Gitlab::Ci::Config::Entry::Retry
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :tags, entry_class: Gitlab::Ci::Config::Entry::Tags
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
      entry_key: :artifacts, entry_class: Gitlab::Ci::Config::Entry::Artifacts
        inheritable_class does define entry
        when is specified
          does inherit value
          when entry is specified
            does not inherit value
        when inheritable does not specify
          does not inherit value
  .nodes
    when filtering all the entry/node names
      is expected to include :before_script, :script, :stage, :type, :after_script, :cache, :image, :services, :only, :except, :rules, :needs, :variables, :artifacts, :environment, :coverage, :retry, :interruptible, :timeout, :release, :tags, :inherit, and :parallel
  .matching?
    when config is not a hash
      is expected to be falsey
    when config is a regular job
      is expected to be truthy
    when config is a bridge job
      is expected to be falsey
    when config is a hidden job
      is expected to be falsey
    when using the default job without script
      is expected to be falsey
    when using the default job with script
      is expected to be truthy
  validations
    when entry config value is correct
      #valid?
        is valid
      when job name is empty
        reports error
      when delayed job
        when start_in is specified
          is expected to be valid
      when has needs
        is expected to be valid
        returns scheduling_type as :dag
        when has dependencies
          is expected to be valid
        when it is a release
          is expected to be valid
      when rules are used
        is expected to be valid
    when entry value is not correct
      incorrect config value type
        #errors
          reports error about a config type
      when config is empty
        #valid
          is invalid
      when unknown keys detected
        #valid
          is not valid
      when script is not provided
        returns error about missing script entry
      when extends key is not a string
        returns error about wrong value type
      when parallel value is not correct
        when it is not a numeric value
          returns error about invalid type
        when it is lower than two
          returns error about value too low
        when it is an empty hash
          returns error about missing matrix
      when it uses both "when:" and "rules:"
        returns an error about when: being combined with rules
      when delayed job
        when start_in is specified
          is expected to be valid
        when start_in is empty
          returns error about invalid type
        when start_in is not formatted as a duration
          returns error about invalid type
        when start_in is longer than one week
          returns error about exceeding the limit
      when only: is used with rules:
        returns error about mixing only: with rules:
        and only: is blank
          returns error about mixing only: with rules:
        and rules: is blank
          returns error about mixing only: with rules:
      when except: is used with rules:
        returns error about mixing except: with rules:
        and except: is blank
          returns error about mixing except: with rules:
        and rules: is blank
          returns error about mixing except: with rules:
      when only: and except: are both used with rules:
        returns errors about mixing both only: and except: with rules:
        when only: and except: as both blank
          returns errors about mixing both only: and except: with rules:
        when rules: is blank
          returns errors about mixing both only: and except: with rules:
      when start_in specified without delayed specification
        returns error about invalid type
      when has dependencies
        that are not a array of strings
          returns error about invalid type
      when has needs
        when have dependencies that are not subset of needs
          returns error about invalid data
      when timeout value is not correct
        when it is higher than instance wide timeout
          returns error about value too high
        when it is not a duration
          returns error about wrong value
      when timeout value is correct
        returns correct timeout
      when it is a release
        when `release:description` is missing
          returns error
      when invalid rules are used
        with rules nested more than max allowed levels
          is expected not to be valid
        with rules with invalid keys
          is expected not to be valid
  #relevant?
    is a relevant entry
  #compose!
    when job config overrides default config
      overrides default config
    when job config does not override default config
      uses config from default entry
    with workflow rules
      name: "uses default only", has_workflow_rules?: false, only: nil, rules: nil, result: {:refs=>["branches", "tags"]}
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameUsesDefaultOnlyHasWorkflowRulesFalseOnlyNilRulesNilResultRefsBranchesTags
      name: "uses user only", has_workflow_rules?: false, only: ["branches"], rules: nil, result: {:refs=>["branches"]}
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameUsesUserOnlyHasWorkflowRulesFalseOnlyBranchesRulesNilResultRefsBranches
      name: "does not define only", has_workflow_rules?: false, only: nil, rules: [], result: nil
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameDoesNotDefineOnlyHasWorkflowRulesFalseOnlyNilRulesResultNil
      name: "does not define only", has_workflow_rules?: true, only: nil, rules: nil, result: nil
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameDoesNotDefineOnlyHasWorkflowRulesTrueOnlyNilRulesNilResultNil
      name: "uses user only", has_workflow_rules?: true, only: ["branches"], rules: nil, result: {:refs=>["branches"]}
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameUsesUserOnlyHasWorkflowRulesTrueOnlyBranchesRulesNilResultRefsBranches
      name: "does not define only", has_workflow_rules?: true, only: nil, rules: [], result: nil
        RSpec::ExampleGroups::GitlabCiConfigEntryJob::Compose::WithWorkflowRules::NameDoesNotDefineOnlyHasWorkflowRulesTrueOnlyNilRulesResultNil
    when workflow rules is used
      when rules are used
        does not define only
      when rules are not used
        does not define only
  when composed
    #value
      when entry is correct
        returns correct value
    when job is using tags
      when limit is reached
        returns error
      when limit is not reached
        returns a valid entry
  #manual_action?
    when job is a manual action
      is a manual action
    when job is not a manual action
      is not a manual action
  #delayed?
    when job is a delayed
      is a delayed
    when job is not a delayed
      is not a delayed
  #ignored?
    when job is a manual action
      when it is not specified if job is allowed to fail
        is an ignored job
      when job is allowed to fail
        is an ignored job
      when job is not allowed to fail
        is not an ignored job
      when job is dynamically allowed to fail
        is not an ignored job
    when job is not a manual action
      when it is not specified if job is allowed to fail
        is not an ignored job
        does not return allow_failure
      when job is allowed to fail
        is an ignored job
        does not return allow_failure_criteria
      when job is not allowed to fail
        is not an ignored job
        does not return allow_failure_criteria
      when job is dynamically allowed to fail
        is not an ignored job
        returns allow_failure_criteria

Banzai::ColorParser
  .parse
    HEX format
      parses the valid hex color #abc
      parses the valid hex color #ABC
      parses the valid hex color #d2d2d2
      parses the valid hex color #D2D2D2
      parses the valid hex color #123a
      parses the valid hex color #123A
      parses the valid hex color #123456aa
      parses the valid hex color #123456AA
      does not parse the invalid hex color #
      does not parse the invalid hex color #1
      does not parse the invalid hex color #12
      does not parse the invalid hex color #12g
      does not parse the invalid hex color #12G
      does not parse the invalid hex color #12345
      does not parse the invalid hex color #r2r2r2
      does not parse the invalid hex color #R2R2R2
      does not parse the invalid hex color #1234567
      does not parse the invalid hex color # 123
      does not parse the invalid hex color # 1234
      does not parse the invalid hex color # 123456
      does not parse the invalid hex color # 12345678
      does not parse the invalid hex color #1 2 3
      does not parse the invalid hex color #123 4
      does not parse the invalid hex color #12 34 56
      does not parse the invalid hex color #123456 78
    RGB format
      parses the valid rgb color rgb(0,0,0)
      parses the valid rgb color rgb(255,255,255)
      parses the valid rgb color rgb(0, 0, 0)
      parses the valid rgb color RGB(0,0,0)
      parses the valid rgb color rgb(0,0,0,0)
      parses the valid rgb color rgb(0,0,0,0.0)
      parses the valid rgb color rgb(0,0,0,.0)
      parses the valid rgb color rgb(0,0,0, 0)
      parses the valid rgb color rgb(0,0,0, 0.0)
      parses the valid rgb color rgb(0,0,0, .0)
      parses the valid rgb color rgb(0,0,0,1)
      parses the valid rgb color rgb(0,0,0,1.0)
      parses the valid rgb color rgba(0,0,0)
      parses the valid rgb color rgba(0,0,0,0)
      parses the valid rgb color RGBA(0,0,0)
      parses the valid rgb color rgb(0%,0%,0%)
      parses the valid rgb color rgba(0%,0%,0%,0%)
      does not parse the invalid rgb color FOOrgb(0,0,0)
      does not parse the invalid rgb color rgb(0,0,0)BAR
      does not parse the invalid rgb color rgb(0,0,-1)
      does not parse the invalid rgb color rgb(0,0,-0)
      does not parse the invalid rgb color rgb(0,0,256)
      does not parse the invalid rgb color rgb(0,0,0,-0.1)
      does not parse the invalid rgb color rgb(0,0,0,-0.0)
      does not parse the invalid rgb color rgb(0,0,0,-.1)
      does not parse the invalid rgb color rgb(0,0,0,1.1)
      does not parse the invalid rgb color rgb(0,0,0,2)
      does not parse the invalid rgb color rgba(0,0,0,)
      does not parse the invalid rgb color rgba(0,0,0,0.)
      does not parse the invalid rgb color rgba(0,0,0,1.)
      does not parse the invalid rgb color rgb(0,0,0%)
      does not parse the invalid rgb color rgb(101%,0%,0%)
    HSL format
      parses the valid hsl color hsl(0,0%,0%)
      parses the valid hsl color hsl(0,100%,100%)
      parses the valid hsl color hsl(540,0%,0%)
      parses the valid hsl color hsl(-720,0%,0%)
      parses the valid hsl color hsl(0deg,0%,0%)
      parses the valid hsl color hsl(0DEG,0%,0%)
      parses the valid hsl color hsl(0, 0%, 0%)
      parses the valid hsl color HSL(0,0%,0%)
      parses the valid hsl color hsl(0,0%,0%,0)
      parses the valid hsl color hsl(0,0%,0%,0.0)
      parses the valid hsl color hsl(0,0%,0%,.0)
      parses the valid hsl color hsl(0,0%,0%, 0)
      parses the valid hsl color hsl(0,0%,0%, 0.0)
      parses the valid hsl color hsl(0,0%,0%, .0)
      parses the valid hsl color hsl(0,0%,0%,1)
      parses the valid hsl color hsl(0,0%,0%,1.0)
      parses the valid hsl color hsla(0,0%,0%)
      parses the valid hsl color hsla(0,0%,0%,0)
      parses the valid hsl color HSLA(0,0%,0%)
      parses the valid hsl color hsl(1rad,0%,0%)
      parses the valid hsl color hsl(1.1rad,0%,0%)
      parses the valid hsl color hsl(.1rad,0%,0%)
      parses the valid hsl color hsl(-1rad,0%,0%)
      parses the valid hsl color hsl(1RAD,0%,0%)
      does not parse the invalid hsl color hsl(+0,0%,0%)
      does not parse the invalid hsl color hsl(0,0,0%)
      does not parse the invalid hsl color hsl(0,0%,0)
      does not parse the invalid hsl color hsl(0 deg,0%,0%)
      does not parse the invalid hsl color hsl(0,-0%,0%)
      does not parse the invalid hsl color hsl(0,101%,0%)
      does not parse the invalid hsl color hsl(0,-1%,0%)
      does not parse the invalid hsl color hsl(0,0%,0%,-0.1)
      does not parse the invalid hsl color hsl(0,0%,0%,-.1)
      does not parse the invalid hsl color hsl(0,0%,0%,1.1)
      does not parse the invalid hsl color hsl(0,0%,0%,2)
      does not parse the invalid hsl color hsl(0,0%,0%,)
      does not parse the invalid hsl color hsl(0,0%,0%,0.)
      does not parse the invalid hsl color hsl(0,0%,0%,1.)
      does not parse the invalid hsl color hsl(deg,0%,0%)
      does not parse the invalid hsl color hsl(rad,0%,0%)

Gitlab::GitalyClient::CommitService
  #diff_from_parent
    returns a Gitlab::GitalyClient::DiffStitcher
    encodes paths correctly
    when a commit has a parent
      sends an RPC request with the parent ID as left commit
    when a commit does not have a parent
      sends an RPC request with empty tree ref as left commit
  #commit_deltas
    when a commit has a parent
      sends an RPC request with the parent ID as left commit
    when a commit does not have a parent
      sends an RPC request with empty tree ref as left commit
  #diff_stats
    sends an RPC request and returns the stats
  #find_changed_paths
    sends an RPC request and returns the stats
  #tree_entries
    sends a get_tree_entries message
    with UTF-8 params strings
      handles string encodings correctly
    with pagination parameters
      responds with a pagination cursor
  #commit_count
    sends a commit_count message
    with UTF-8 params strings
      handles string encodings correctly
  #find_commit
    sends an RPC request
    caching
      when passed revision is a branch name
        calls Gitaly
      when passed revision is a commit ID
        returns a cached commit
      when caching of the ref name is enabled
        caches negative entries
        returns a cached commit
  #list_commits
    behaves like a ListCommits request
      sends a list_commits message
    with multiple revisions
      behaves like a ListCommits request
        sends a list_commits message
    with reverse: true
      behaves like a ListCommits request
        sends a list_commits message
    with pagination params
      behaves like a ListCommits request
        sends a list_commits message
  #list_new_commits
    with hook environment
      with allowed quarantine
        behaves like a #list_all_commits message
          sends a list_all_commits message
      with disallowed quarantine
        behaves like a #list_commits message
          sends a list_commits message
    without hook environment
      with allowed quarantine
        behaves like a #list_commits message
          sends a list_commits message
      with disallowed quarantine
        behaves like a #list_commits message
          sends a list_commits message
  #commit_stats
    sends an RPC request
  #find_commits
    sends an RPC request with NONE when default
    sends an RPC request
    sends an RPC request with an author
  #commits_by_message
    when only the query is provided
      sends an RPC request with the correct payload
    when all arguments are provided
      sends an RPC request with the correct payload
    when limit and offset are not integers
      sends an RPC request with the correct payload
    when revision and path contain non-ASCII characters
      sends an RPC request with the correct payload
  #list_commits_by_ref_name
    lists latest commits grouped by a ref name

Gitlab::ProjectAuthorizations
  user added to group and project
    returns the correct number of authorizations
    includes the correct projects
    includes the correct access levels
  unapproved access request
    group membership
      does not create authorization
    inherited group membership
      does not create authorization
    project membership
      does not create authorization
    shared group
      does not create authorization
    shared project
      does not create authorization
  user with minimal access to group
    group membership
      does not create authorization
    inherited group membership
      does not create authorization
    shared group
      does not create authorization
    shared project
      does not create authorization
  with nested groups
    includes nested groups
    inherits access levels when the user is not a member of a nested group
    uses the greatest access level when a user is a member of a nested group
  with shared projects
    creates proper authorizations
    even when the `lock_memberships_to_ldap` setting has been turned ON
      creates proper authorizations
    when the group containing the project has forbidden group shares for any of its projects
      does not create authorizations
  with shared groups
    group user
      creates proper authorizations
    with lower group access level than max access level for share
      creates proper authorizations
    parent group user
      creates proper authorizations
    child group user
      creates proper authorizations
    user without accepted access request
      does not have access to group and its projects
    unrelated project owner
      does not have access to group and its projects

PagesDomain
  associations
    is expected to belong to project required: false
    is expected to have many serverless_domain_clusters
  .for_project
    returns domains assigned to project
  validate domain
    is unique
      is expected to validate that :domain is case-insensitively unique
    hostname
      domain "my.domain.com" validity
        is expected to eq true
      domain "123.456.789" validity
        is expected to eq true
      domain "0x12345.com" validity
        is expected to eq true
      domain "0123123" validity
        is expected to eq true
      domain "_foo.com" validity
        is expected to eq false
      domain "reserved.com" validity
        is expected to eq false
      domain "a.reserved.com" validity
        is expected to eq false
      domain nil validity
        is expected to eq false
    HTTPS-only
      pages_https_only: true, certificate: nil, key: nil, auto_ssl_enabled: false, errors_on: [:certificate, :key]
        is adds the expected errors
      pages_https_only: true, certificate: nil, key: nil, auto_ssl_enabled: true, errors_on: []
        is adds the expected errors
      pages_https_only: true, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: nil, auto_ssl_enabled: false, errors_on: [:key]
        is adds the expected errors
      pages_https_only: true, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: nil, auto_ssl_enabled: true, errors_on: [:key]
        is adds the expected errors
      pages_https_only: true, certificate: nil, key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: false, errors_on: [:certificate, :key]
        is adds the expected errors
      pages_https_only: true, certificate: nil, key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: true, errors_on: [:key]
        is adds the expected errors
      pages_https_only: true, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: false, errors_on: []
        is adds the expected errors
      pages_https_only: true, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: true, errors_on: []
        is adds the expected errors
      pages_https_only: false, certificate: nil, key: nil, auto_ssl_enabled: false, errors_on: []
        is adds the expected errors
      pages_https_only: false, certificate: nil, key: nil, auto_ssl_enabled: true, errors_on: []
        is adds the expected errors
      pages_https_only: false, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: nil, auto_ssl_enabled: false, errors_on: [:key]
        is adds the expected errors
      pages_https_only: false, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: nil, auto_ssl_enabled: true, errors_on: [:key]
        is adds the expected errors
      pages_https_only: false, certificate: nil, key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: false, errors_on: [:key]
        is adds the expected errors
      pages_https_only: false, certificate: nil, key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: true, errors_on: [:key]
        is adds the expected errors
      pages_https_only: false, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: false, errors_on: []
        is adds the expected errors
      pages_https_only: false, certificate: "-----BEGIN CERTIFICATE-----\nMIIBrzCCARgCCQDbfQx2zdkNYTANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBB0\nZXN0LWNlcnRpZmljYXRlMCAXDTIwMDMxNjE0MjAzNFoYDzIyMjAwMTI4MTQyMDM0\nWjAbMRkwFwYDVQQDDBB0ZXN0LWNlcnRpZmljYXRlMIGfMA0GCSqGSIb3DQEBAQUA\nA4GNADCBiQKBgQCkvgn0vRnEUnWEjUs8h+UCUAa+bpkS+hPiopTld/YmBTv/aB41\nHWqU0VpK8JzTwqe6mnnJOCa/Ir9eLT1TQ3za++nhm+v92JJzgD9EDoy1rp6AvJI1\nPjfyR1Odja1Hl96hMvBClfS3ggyXAZAZPmHo5/Z8qYPHO7C7J99wgeot2wIDAQAB\nMA0GCSqGSIb3DQEBCwUAA4GBACc+chrTAuvnMBTedc4/dy16pEesK6oGjywYUd/0\n/FBr8Vry7QUXMSgfraza9S0V+JvFvZFqkkOyJKW+m30kThWzyc/2e+BRxTh/QrxP\n0j84QXtmnVtW4jsAwfBBfg78ST27eyp/WhruI6F/kZlXhfAed0RcPbRnbi3yvUPL\nLo4T\n-----END CERTIFICATE-----\n", key: "-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKS+CfS9GcRSdYSN\nSzyH5QJQBr5umRL6E+KilOV39iYFO/9oHjUdapTRWkrwnNPCp7qaeck4Jr8iv14t\nPVNDfNr76eGb6/3YknOAP0QOjLWunoC8kjU+N/JHU52NrUeX3qEy8EKV9LeCDJcB\nkBk+Yejn9nypg8c7sLsn33CB6i3bAgMBAAECgYA2D26w80T7WZvazYr86BNMePpd\nj2mIAqx32KZHzt/lhh40J/SRtX9+Kl0Y7nBoRR5Ja9u/HkAIxNxLiUjwg9r6cpg/\nuITEF5nMt7lAk391BuI+7VOZZGbJDsq2ulPd6lO+C8Kq/PI/e4kXcIjeH6KwQsuR\n5vrXfBZ3sQfflaiN4QJBANBt8JY2LIGQF8o89qwUpRL5vbnKQ4IzZ5+TOl4RLR7O\nAQpJ81tGuINghO7aunctb6rrcKJrxmEH1whzComybrMCQQDKV49nOBudRBAIgG4K\nEnLzsRKISUHMZSJiYTYnablof8cKw1JaQduw7zgrUlLwnroSaAGX88+Jw1f5n2Lh\nVlg5AkBDdUGnrDLtYBCDEQYZHblrkc7ZAeCllDOWjxUV+uMqlCv8A4Ey6omvY57C\nm6I8DkWVAQx8VPtozhvHjUw80rZHAkB55HWHAM3h13axKG0htCt7klhPsZHpx6MH\nEPjGlXIT+aW2XiPmK3ZlCDcWIenE+lmtbOpI159Wpk8BGXs/s/xBAkEAlAY3ymgx\n63BDJEwvOb2IaP8lDDxNsXx9XJNVvQbv5n15vNsLHbjslHfAhAbxnLQ1fLhUPqSi\nnNp/xedE1YxutQ==\n-----END PRIVATE KEY-----\n", auto_ssl_enabled: true, errors_on: []
        is adds the expected errors
  when certificate is specified
    saves validity time
  validate certificate
    serverless domain
      requires certificate and key to be present
    with matching key
      is expected to be valid
    when no certificate is specified
      is expected not to be valid
    when no key is specified
      is expected not to be valid
    for not matching key
      is expected not to be valid
    when certificate is expired
      when certificate is being changed
        adds error to certificate
      when certificate is already saved
        doesn't add error to certificate
    with ecdsa certificate
      is valid
      when curve is set explicitly by parameters
        adds errors to private key
  validations
    is expected to validate that :verification_code cannot be empty/falsy
  default values
    defaults wildcard to false
    defaults scope to project
    defaults usage to pages
  #verification_code
    is set automatically with 128 bits of SecureRandom data
  #keyed_verification_code
    is expected to eq "gitlab-pages-verification-code=e04c15702513e6a2236fac52951b4187"
  #verification_domain
    is expected to be nil
    is a well-known subdomain if the domain is present
  #url
    is expected to eq "https://my32.domain.com"
    without the certificate
      is expected to eq "http://my33.domain.com"
  #has_matching_key?
    is expected to be truthy
    for invalid key
      is expected to be falsey
  #has_intermediates?
    for self signed
      is expected to be truthy
    for missing certificate chain
      is expected to be falsey
    for trusted certificate chain
      is expected to be truthy
    with a LetsEncrypt bundle with an expired DST Root CA X3
      is expected to be truthy
  #expired?
    for valid
      is expected to be falsey
    for expired
      is expected to be truthy
  #subject
    is expected to eq "/CN=test-certificate"
  #certificate_text
    is expected not to be empty
  #https?
    when a certificate is present
      is expected to be https
    when no certificate is present
      is expected not to be https
  #update_daemon
    runs when the domain is created
    runs when the domain is destroyed
    schedules a PagesUpdateConfigurationWorker
    when usage is serverless
      does not call the UpdatePagesConfigurationService
    when the pages aren't deployed
      does not schedule a PagesUpdateConfigurationWorker
    configuration updates when attributes change
      attribute: :project, old_value: nil, new_value: :project1, update_expected: true
        runs if a relevant attribute has changed
      attribute: :project, old_value: :project1, new_value: :project1, update_expected: false
        runs if a relevant attribute has changed
      attribute: :project, old_value: :project1, new_value: :project2, update_expected: true
        runs if a relevant attribute has changed
      attribute: :project, old_value: :project1, new_value: nil, update_expected: true
        runs if a relevant attribute has changed
      attribute: :domain, old_value: "a.com", new_value: "a.com", update_expected: false
        runs if a relevant attribute has changed
      attribute: :domain, old_value: "a.com", new_value: "b.com", update_expected: true
        runs if a relevant attribute has changed
      attribute: :verification_code, old_value: "foo", new_value: "foo", update_expected: false
        runs if a relevant attribute has changed
      attribute: :verification_code, old_value: "foo", new_value: "bar", update_expected: false
        runs if a relevant attribute has changed
      attribute: :verified_at, old_value: nil, new_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: false
        runs if a relevant attribute has changed
      attribute: :verified_at, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: false
        runs if a relevant attribute has changed
      attribute: :verified_at, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: Wed, 15 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: false
        runs if a relevant attribute has changed
      attribute: :verified_at, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: nil, update_expected: false
        runs if a relevant attribute has changed
      attribute: :enabled_until, old_value: nil, new_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: true
        runs if a relevant attribute has changed
      attribute: :enabled_until, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: false
        runs if a relevant attribute has changed
      attribute: :enabled_until, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: Wed, 15 Dec 2021 01:28:11.887408512 UTC +00:00, update_expected: false
        runs if a relevant attribute has changed
      attribute: :enabled_until, old_value: Tue, 14 Dec 2021 01:28:11.887408512 UTC +00:00, new_value: nil, update_expected: true
        runs if a relevant attribute has changed
      TLS configuration
        updates when added
        updates when changed
        updates when removed
  #user_provided_key
    when certificate is provided by user
      returns key
    when certificate is provided by gitlab
      returns nil
  #user_provided_certificate
    when certificate is provided by user
      returns key
    when certificate is provided by gitlab
      returns nil
  #user_provided_key=
    when value has been changed
      assignes new value to key
      changes certificate source
    when value has not been not changed
      does not change certificate source
  #gitlab_provided_key=
    when value has been changed
      assignes new value to key
      changes certificate source
    when value has not been not changed
      does not change certificate source
  #user_provided_certificate=
    when value has been changed
      assignes new value to certificate
      changes certificate source
    when value has not been not changed
      does not change certificate source
  #gitlab_provided_certificate=
    when value has been changed
      assignes new value to certificate
      changes certificate source
    when value has not been not changed
      does not change certificate source
  #save
    when we failed to obtain ssl certificate
      clears failure if auto ssl is disabled
      does not clear failure on unrelated updates
  .for_removal
    when domain is not schedule for removal
      does not return domain
    when domain is scheduled for removal yesterday
      returns domain
    when domain is scheduled for removal tomorrow
      does not return domain
  .instance_serverless
    returns domains that are wildcard, instance-level, and serverless
  .need_auto_ssl_renewal
    contains only domains needing ssl renewal
  #pages_virtual_domain
    returns the virual domain when there are pages deployed for the project
    when there are no pages deployed for the project
      returns nil
  .find_by_domain_case_insensitive
    lookup is case-insensitive

NamespacesHelper
  #namespaces_as_json
    returns the user's groups
    returns the user's namespace
  #namespaces_options
    returns only allowed namespaces for user
    avoids duplicate groups when extra_group is used
    selects the new group by default
    falls back to current user selection
    returns only groups if groups_only option is true
    when admin mode is enabled
      returns groups without being a member for admin
    when admin mode is disabled
      returns only allowed namespaces for admin
    when admin mode is disabled
      selects existing group
    when nested groups are available
      includes groups nested in groups the user can administer
      orders the groups correctly
    include_groups_with_developer_maintainer_access parameter
      when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set for a project
        returns groups where user is a developer
      when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set globally
        return groups where default is not overridden
  #cascading_namespace_settings_popover_data
    when locked by an application setting
      returns expected hash
    when locked by an ancestor namespace
      returns expected hash
  #cascading_namespace_setting_locked?
    when `group` argument is `nil`
      returns `false`
    when `*_locked?` method does not exist
      returns `false`
    when `*_locked?` method does exist
      calls corresponding `*_locked?` method

EnvironmentSerializer
  behaves like avoid N+1 on environments serialization
    avoids N+1 database queries with grouping
    avoids N+1 database queries without grouping
    does not preload for environments that does not exist in the page
  when there is a collection of objects provided
    contains important elements of environment
    generates payload for collection
  when representing environments within folders
    when there is a single environment
      represents one standalone environment
    when there are multiple environments in folder
      represents one item that is a folder
    when there are multiple folders and standalone environments
      represents multiple items grouped within folders
  when used with pagination
    creates a paginated serializer
    when resource is paginatable relation
      when there is a single environment object in relation
        serializes environments
      when multiple environment objects are serialized
        serializes appropriate number of objects
        appends relevant headers
      when grouping environments within folders
        paginates grouped items including ordering
        appends correct total page count header
        appends correct page count headers

NotificationRecipient
  #notifiable?
    when emails are disabled
      returns false if group disabled
      returns false if project disabled
    when emails are enabled
      returns true if group enabled
      returns true if project enabled
  #has_access?
    user cannot read cross project
      returns false
    user cannot read build
      returns false
    user cannot read commit
      returns false
    target has no policy
      returns true
  #notification_setting
    for child groups
      when notification setting is global
        considers notification setting from the first parent without global setting
      when notification setting is not global
        considers notification setting from lowest group member in hierarchy
  #suitable_notification_level?
    when notification level is mention
      when type is mention
        returns true
      when type is not mention
        returns false
    when notification level is participating
      when type is participating
        returns true
      when type is mention
        returns true
      with custom action
        when action is failed_pipeline
          returns true
        when action is fixed_pipeline
          returns true
        when action is not fixed_pipeline or failed_pipeline
          returns false
    when notification level is custom
      when type is participating
        with custom event enabled
          returns true
        without custom event enabled
          returns true
      when type is mention
        with custom event enabled
          returns true
        without custom event enabled
          returns true
      when type is watch
        with custom event enabled
          returns true
        without custom event enabled
          returns false
        when custom_action is fixed_pipeline and success_pipeline event is enabled
          returns true
        with merge_when_pipeline_succeeds
          custom event enabled
            returns true
          custom event disabled
            returns false
    when notification level is watch
      when type is watch
        without excluded watcher events
          returns true
        with excluded watcher events
          returns false
      when type is not watch
        without excluded watcher events
          returns true
        with excluded watcher events
          returns true

ObjectStorage::MigrateUploadsWorker
  for AvatarUploader
    behaves like uploads migration worker
      .enqueue!
        is guarded by .sanity_check!
        sanity_check! fails
          does not enqueue a job
      .sanity_check!
        uploader types mismatch
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Multiple uploaders found/
        mount point not found
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Mount point [a-z:]+ not found in/
      #perform
        migrates files to remote storage
        reversed
          migrates files to local storage
        migration is unsuccessful
          does not migrate files to remote storage
    limits N+1 queries
      to N*5
  for FileUploader
    behaves like uploads migration worker
      .enqueue!
        is guarded by .sanity_check!
        sanity_check! fails
          does not enqueue a job
      .sanity_check!
        uploader types mismatch
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Multiple uploaders found/
        mount point not found
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Mount point [a-z:]+ not found in/
      #perform
        migrates files to remote storage
        reversed
          migrates files to local storage
        migration is unsuccessful
          does not migrate files to remote storage
    limits N+1 queries
      to N*5
  for DesignManagement::DesignV432x230Uploader
    behaves like uploads migration worker
      .enqueue!
        is guarded by .sanity_check!
        sanity_check! fails
          does not enqueue a job
      .sanity_check!
        uploader types mismatch
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Multiple uploaders found/
        mount point not found
          is expected to raise ObjectStorage::MigrateUploadsWorker::SanityCheckError with message matching /Mount point [a-z:]+ not found in/
      #perform
        migrates files to remote storage
        reversed
          migrates files to local storage
        migration is unsuccessful
          does not migrate files to remote storage

Members::UpdateService
  when current user cannot update the given member
    behaves like a service raising Gitlab::Access::AccessDeniedError
      raises Gitlab::Access::AccessDeniedError
    behaves like a service raising Gitlab::Access::AccessDeniedError
      raises Gitlab::Access::AccessDeniedError
  when current user can update the given member
    behaves like a service updating a member
      updates the member
      returns success status
      when member is downgraded to guest
        with Gitlab::Access::GUEST level as a string
          behaves like schedules to delete confidential todos
            is expected to eq 10
        with Gitlab::Access::GUEST level as an integer
          behaves like schedules to delete confidential todos
            is expected to eq 10
      when access_level is invalid
        raises an error
      when member is not valid
        returns error status
    behaves like a service updating a member
      updates the member
      returns success status
      when member is downgraded to guest
        with Gitlab::Access::GUEST level as a string
          behaves like schedules to delete confidential todos
            is expected to eq 10
        with Gitlab::Access::GUEST level as an integer
          behaves like schedules to delete confidential todos
            is expected to eq 10
      when access_level is invalid
        raises an error
      when member is not valid
        returns error status

MergeRequestDiffFile
  behaves like a BulkInsertSafe model
    when calling class methods directly
      raises an error when method is not bulk-insert safe
      does not raise an error when method is bulk-insert safe
    .bulk_insert!
      when all items are valid
        inserts them all
        returns an empty array
      when some items are invalid
        does not insert any of them and raises an error
        inserts them anyway when bypassing validations
  #diff
    when diff is not stored
      when the diff is marked as binary
        unpacks from base 64
        invalid base64
          returns the raw diff
      when the diff is not marked as binary
        returns the raw diff
    when diff is stored in DB
      returns UTF-8 string
    when diff is stored in external storage
      returns UTF-8 string
  #utf8_diff
    does not raise error when the diff is binary

Packages::Debian::ProcessChangesWorker
  #perform
    with mocked service
      calls ProcessChangesService
    with non existing package file
      returns early without error
    with nil package file id
      returns early without error
    with non existing user
      returns early without error
    with nil user id
      returns early without error
    when the service raises an error
      removes package file
    behaves like an idempotent worker
      is labeled as idempotent
      performs multiple times sequentially without raising an exception
      sets the Debian file type as changes

ErrorTracking::SentryClient::Issue
  #list_issues
    behaves like calls sentry api
      calls sentry api
    behaves like issues have correct return type
      returns objects of type Gitlab::ErrorTracking::Error
    behaves like issues have correct length
      is expected to eq 3
    when response has a pagination info
      parses the pagination
    error object created from sentry response
      error_object: :id, sentry_response: :id
        is expected to eq "11"
      error_object: :first_seen, sentry_response: :firstSeen
        is expected to eq "2018-12-17T12:00:14Z"
      error_object: :last_seen, sentry_response: :lastSeen
        is expected to eq "2018-12-31T12:00:11Z"
      error_object: :title, sentry_response: :title
        is expected to eq "gaierror: [Errno -2] Name or service not known"
      error_object: :type, sentry_response: :type
        is expected to eq "error"
      error_object: :user_count, sentry_response: :userCount
        is expected to eq 0
      error_object: :count, sentry_response: :count
        is expected to eq "21"
      error_object: :message, sentry_response: [:metadata, :value]
        is expected to eq "[Errno -2] Name or service not known"
      error_object: :culprit, sentry_response: :culprit
        is expected to eq "sentry.tasks.reports.deliver_organization_user_report"
      error_object: :short_id, sentry_response: :shortId
        is expected to eq "INTERNAL-4"
      error_object: :status, sentry_response: :status
        is expected to eq "unresolved"
      error_object: :frequency, sentry_response: [:stats, "24h"]
        is expected to eq [[1546437600, 0]]
      error_object: :project_id, sentry_response: [:project, :id]
        is expected to eq "1"
      error_object: :project_name, sentry_response: [:project, :name]
        is expected to eq "Internal"
      error_object: :project_slug, sentry_response: [:project, :slug]
        is expected to eq "internal"
      behaves like has correct external_url
        external_url
          is constructed correctly
    redirects
      behaves like no Sentry redirects
        does not follow redirects
    requests with sort parameter in sentry api
      calls the sentry api with sort params
    with invalid sort params
      throws an error
    Older sentry versions where keys are not present
      behaves like calls sentry api
        calls sentry api
      behaves like issues have correct return type
        returns objects of type Gitlab::ErrorTracking::Error
      behaves like issues have correct length
        is expected to eq 1
      behaves like has correct external_url
        external_url
          is constructed correctly
    essential keys missing in API response
      raises exception
    sentry api response too large
      raises exception
    behaves like maps Sentry exceptions
      HTTParty::Error
        is expected to raise ErrorTracking::SentryClient::Error with "Error when connecting to Sentry"
      Net::OpenTimeout
        is expected to raise ErrorTracking::SentryClient::Error with "Connection to Sentry timed out"
      SocketError
        is expected to raise ErrorTracking::SentryClient::Error with "Received SocketError when trying to connect to Sentry"
      OpenSSL::SSL::SSLError
        is expected to raise ErrorTracking::SentryClient::Error with "Sentry returned invalid SSL data"
      Errno::ECONNREFUSED
        is expected to raise ErrorTracking::SentryClient::Error with "Connection refused"
      StandardError
        is expected to raise ErrorTracking::SentryClient::Error with "Sentry request failed due to StandardError"
    when search term is present
      behaves like calls sentry api
        calls sentry api
      behaves like issues have correct return type
        returns objects of type Gitlab::ErrorTracking::Error
      behaves like issues have correct length
        is expected to eq 3
    when cursor is present
      behaves like calls sentry api
        calls sentry api
      behaves like issues have correct return type
        returns objects of type Gitlab::ErrorTracking::Error
      behaves like issues have correct length
        is expected to eq 3
  #issue_details
    error object created from sentry response
      has a correct external URL
      issue has a correct external base url
      has a correct GitLab issue url
      has an integrated attribute set to false
      has the correct tags
      error_object: :id, sentry_response: :id
        is expected to eq "11"
      error_object: :first_seen, sentry_response: :firstSeen
        is expected to eq "2018-11-06T21:19:55Z"
      error_object: :last_seen, sentry_response: :lastSeen
        is expected to eq "2018-11-06T21:19:55Z"
      error_object: :title, sentry_response: :title
        is expected to eq "This is an example Python exception"
      error_object: :type, sentry_response: :type
        is expected to eq "default"
      error_object: :user_count, sentry_response: :userCount
        is expected to eq 0
      error_object: :count, sentry_response: :count
        is expected to eq "1"
      error_object: :message, sentry_response: [:metadata, :value]
        is expected to eq nil
      error_object: :culprit, sentry_response: :culprit
        is expected to eq "raven.scripts.runner in main"
      error_object: :short_id, sentry_response: :shortId
        is expected to eq "PUMP-STATION-1"
      error_object: :status, sentry_response: :status
        is expected to eq "unresolved"
      error_object: :frequency, sentry_response: [:stats, "24h"]
        is expected to eq [[1541451600.0, 557], [1541455200.0, 473], [1541458800.0, 914], [1541462400.0, 991], [1541466000.0, 9...1523600.0, 111], [1541527200.0, 926], [1541530800.0, 772], [1541534400.0, 400], [1541538000.0, 943]]
      error_object: :project_id, sentry_response: [:project, :id]
        is expected to eq "2"
      error_object: :project_name, sentry_response: [:project, :name]
        is expected to eq "Pump Station"
      error_object: :project_slug, sentry_response: [:project, :slug]
        is expected to eq "pump-station"
      error_object: :first_release_last_commit, sentry_response: [:firstRelease, :lastCommit]
        is expected to eq nil
      error_object: :last_release_last_commit, sentry_response: [:lastRelease, :lastCommit]
        is expected to eq {}
      error_object: :first_release_short_version, sentry_response: [:firstRelease, :shortVersion]
        is expected to eq "1764232"
      error_object: :last_release_short_version, sentry_response: [:lastRelease, :shortVersion]
        is expected to eq "27de6b42eb4"
      error_object: :first_release_version, sentry_response: [:firstRelease, :version]
        is expected to eq "17642328ead24b51867165985996d04b29310337"
      error_object: :last_release_version, sentry_response: [:lastRelease, :version]
        is expected to eq "17642328ead24b51867165985996d04b29321448"
      when issue annotations exist
        has a correct GitLab issue url
      when no GitLab issue is linked
        does not find a GitLab issue
  #update_issue
    returns a truthy result
    behaves like calls sentry api
      calls sentry api
    error encountered
      raises the error

Gitlab::Usage::MetricDefinition
  has all definitons valid
  #with_instrumentation_class
    includes definitions with instrumentation_class
    with removed metric
      excludes removed definitions
  #key
    returns a symbol from name
  #validate
    attribute: :description, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :value_type, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :value_type, value: "test"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :status, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :milestone, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :data_category, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :key_path, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :product_group, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :time_frame, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :time_frame, value: "29d"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :data_source, value: "other"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :data_source, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :distribution, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :distribution, value: "test"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :tier, value: ["test", "ee"]
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :name, value: "count_<adjective_describing>_boards"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :repair_issue_url, value: nil
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :instrumentation_class, value: "Metric_Class"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    attribute: :instrumentation_class, value: "metricClass"
      raise exception
      with skip_validation
        raise exception if skip_validation: false
        does not raise exception if has skip_validation: true
    conditional validations
      when metric has broken status
        has to have repair issue url provided
  statuses
    status: "deprecated", skip_validation?: true
      returns true/false for skip_validation
    status: "removed", skip_validation?: true
      returns true/false for skip_validation
    status: "active", skip_validation?: false
      returns true/false for skip_validation
  .load_all!
    has empty list when there are no definition files
    has one metric when there is one file
    when the same metric is defined multiple times raises exception
  dump_metrics_yaml
    returns a YAML with both metrics in a sequence

ChronicDurationAttribute
  when default value is not set
    behaves like ChronicDurationAttribute reader
      contains dynamically created reader method
      outputs chronic duration formatted value
      when value is set to nil
        outputs nil
    behaves like ChronicDurationAttribute writer
      contains dynamically created writer method
      parses chronic duration input
      passes validation
      when negative input is used
        doesn't raise exception
        doesn't change value
        doesn't pass validation
      when empty input is used
        writes default value
        passes validation
      when nil input is used
        writes default value
        passes validation
        doesn't raise exception
  when default value is set
    behaves like ChronicDurationAttribute reader
      contains dynamically created reader method
      outputs chronic duration formatted value
      when value is set to nil
        outputs nil
    behaves like ChronicDurationAttribute writer
      contains dynamically created writer method
      parses chronic duration input
      passes validation
      when negative input is used
        doesn't raise exception
        doesn't change value
        doesn't pass validation
      when empty input is used
        writes default value
        passes validation
      when nil input is used
        writes default value
        passes validation
        doesn't raise exception

ChronicDurationAttribute - reader
  doesn't contain dynamically created writer method
  behaves like ChronicDurationAttribute reader
    contains dynamically created reader method
    outputs chronic duration formatted value
    when value is set to nil
      outputs nil

Gitlab::HashedStorage::Migrator
  #bulk_schedule_migration
    schedules job to HashedStorage::MigratorWorker
  #bulk_schedule_rollback
    schedules job to HashedStorage::RollbackerWorker
  #bulk_migrate
    enqueue jobs to HashedStorage::ProjectMigrateWorker
    rescues and log exceptions
    delegates each project in specified range to #migrate
    has all projects migrated and set as writable
  #bulk_rollback
    enqueue jobs to HashedStorage::ProjectRollbackWorker
    rescues and log exceptions
    delegates each project in specified range to #rollback
    has all projects rolledback and set as writable
  #migrate
    enqueues project migration job
    rescues and log exceptions
    migrates project storage
    has migrated project set as writable
    when project is already on hashed storage
      doesnt enqueue any migration job
      returns false
  #rollback
    enqueues project rollback job
    rescues and log exceptions
    rolls-back project storage
    has rolled-back project set as writable
    when project is already on legacy storage
      doesnt enqueue any rollback job
      returns false
  migration_pending?
    returns true when there are MigratorWorker jobs scheduled
    returns true when there are ProjectMigrateWorker jobs scheduled
    returns false when queues are empty
  rollback_pending?
    returns true when there are RollbackerWorker jobs scheduled
    returns true when there are jobs scheduled
    returns false when queues are empty
  abort_rollback!
    removes any rollback related scheduled job

ProcessCommitWorker
  #perform
    does not process the commit when the project does not exist
    does not process the commit when the user does not exist
    is labeled as idempotent
    performs multiple times sequentially without raising an exception
    processes the commit message
    updates the issue metrics
  #process_commit_message
    when pushing to the default branch
      closes issues that should be closed per the commit message
      creates cross references
    when pushing to a non-default branch
      does not close any issues
      does not create cross references
    when commit is a merge request merge commit to the default branch
      does not close any issues from the commit message
      still creates cross references
  #close_issues
    when the user can update the issues
      closes the issues
    when the user can not update the issues
      does not close the issues
  #update_issue_metrics
    when commit has issue reference
      when issue has no first_mentioned_in_commit_at set
        updates issue metrics
      when issue has first_mentioned_in_commit_at earlier than given committed_date
        doesn't update issue metrics
      when issue has first_mentioned_in_commit_at later than given committed_date
        doesn't update issue metrics
    when commit has no issue references
      doesn't execute any queries with false conditions
  #build_commit
    returns a Commit
    parses date strings into Time instances

IssueEntity
  has Issuable attributes
  has time estimation attributes
  when issue got moved
    when user cannot read target project
      does not return moved_to_id
    when user can read target project
      returns moved moved_to_id
  when issue got duplicated
    when user cannot read new issue
      does not return duplicated_to_id
    when user can read target project
      returns duplicated duplicated_to_id
  when issuable in active or archived project
    when project is active
      returns archived false
      returns nil for archived project doc
    when project is archived
      returns archived true
      returns archived project doc

Gitlab::Json
  .parse
    legacy_mode is disabled by default
      parses an object
      parses an array
      parses a string
      parses a true bool
      parses a false bool
    legacy_mode is enabled
      parses an object
      parses an array
      raises an error on a string
      raises an error on a true bool
      raises an error on a false bool
    feature flag is disabled
      parses an object
      parses an array
      parses a string
      parses a true bool
      parses a false bool
  .parse!
    legacy_mode is disabled by default
      parses an object
      parses an array
      parses a string
      parses a true bool
      parses a false bool
    legacy_mode is enabled
      parses an object
      parses an array
      raises an error on a string
      raises an error on a true bool
      raises an error on a false bool
    feature flag is disabled
      parses an object
      parses an array
      parses a string
      parses a true bool
      parses a false bool
  .dump
    dumps an object
    dumps an array
    dumps a string
    dumps a true bool
    dumps a false bool
  .generate
    generates JSON
    allows you to customise the output
  .pretty_generate
    generates pretty JSON
    allows you to customise the output
  the feature table is missing
    skips legacy mode handling
  the database is missing
    still parses json
    still generates json
  Gitlab::Json::GrapeFormatter
    grape_gitlab_json flag is enabled
      generates JSON
      uses Gitlab::Json
    grape_gitlab_json flag is disabled
      generates JSON
      uses Grape::Formatter::Json
    precompiled JSON
      renders the string directly
      calls #to_s on the object
      doesn't run the JSON formatter
  Gitlab::Json::PrecompiledJson
    #to_s
      obj is a string
        returns a string
      obj is an array
        returns a string
      obj is an array of un-stringables
        raises an error
      obj is something else
        raises an error
  Gitlab::Json::LimitedEncoder
    when object size is acceptable
      returns json string
    when object is too big
      raises LimitExceeded error
    when object contains ASCII-8BIT encoding
      does not raise encoding error
    when json_limited_encoder is disabled
      does not raise an error

Group Routable
  behaves like routable resource
    .find_by_full_path
      finds records by their full path
      returns nil for unknown paths
      includes route information when loading a record
      with redirect routes
        without follow_redirects option
          does not find records by their redirected path
        with follow_redirects option set to true
          finds records by their canonical path
          finds records by their redirected path
          returns nil for unknown paths
  behaves like routable resource with parent
    behaves like routable resource
      .find_by_full_path
        finds records by their full path
        returns nil for unknown paths
        includes route information when loading a record
        with redirect routes
          without follow_redirects option
            does not find records by their redirected path
          with follow_redirects option set to true
            finds records by their canonical path
            finds records by their redirected path
            returns nil for unknown paths
    #full_path
      is expected to eq "foo/group649"
      hits the cache when not preloaded
    #full_name
      is expected to eq "foo / group649"
      hits the cache when not preloaded
  Validations
    is expected to validate that :route cannot be empty/falsy
  Associations
    is expected to have one route dependent => destroy
    is expected to have many redirect_routes dependent => destroy
  Callbacks
    for a group
      creates route record on create
      updates route record on path change
      ensure route path uniqueness across different objects
    for a user
      creates the route for a record on create
      updates routes and nested routes on name change
  .where_full_path_in
    without any paths
      returns an empty relation
    without any valid paths
      returns an empty relation
    with valid paths
      returns the projects matching the paths
      returns projects regardless of the casing of paths
  #parent_loaded?
    is false when the parent is not loaded
    is true when the parent is loaded
  #route_loaded?
    is false when the route is not loaded
    is true when the route is loaded

Project Routable
  behaves like routable resource with parent
    behaves like routable resource
      .find_by_full_path
        finds records by their full path
        returns nil for unknown paths
        includes route information when loading a record
        with redirect routes
          without follow_redirects option
            does not find records by their redirected path
          with follow_redirects option set to true
            finds records by their canonical path
            finds records by their redirected path
            returns nil for unknown paths
    #full_path
      is expected to eq "namespace686/project923"
      hits the cache when not preloaded
    #full_name
      is expected to eq "Sidney Jones1408 / project923"
      hits the cache when not preloaded

Namespaces::ProjectNamespace Routable
  ignores project namespace when searching for generic namespace

Gitlab::Experimentation::ControllerConcern
  #set_experimentation_subject_id_cookie
    cookie is present
      does not change the cookie
    cookie is not present
      sets a permanent signed cookie
      DNT: 0
        sets a permanent signed cookie
      DNT: 1
        does nothing
    when not on gitlab.com
      when cookie was set
        cookie gets deleted
      when no cookie was set before
        does nothing
  #push_frontend_experiment
    pushes an experiment to the frontend
  #experiment_enabled?
    cookie is not present
      is expected to eq false
    cookie is present
      calls Gitlab::Experimentation.in_experiment_group? with the name of the experiment and the calculated experimentation_subject_index based on the uuid
      when subject is given
        uses the subject
    do not track
      when do not track is disabled
        is expected to eq true
      when do not track is enabled
        is expected to eq false
    URL parameter to force enable experiment
      returns true unconditionally
    Cookie parameter to force enable experiment
      returns true unconditionally
  #track_experiment_event
    when the experiment is enabled
      the user is part of the experimental group
        tracks the event with the right parameters
      the user is part of the control group
        tracks the event with the right parameters
      do not track is disabled
        does track the event
      do not track enabled
        does not track the event
      subject is provided
        provides the subject's hashed global_id as label
        provides the subject's hashed string representation as label
      no subject is provided but cookie is set
        uses the experimentation_subject_id as fallback
    when the experiment is disabled
      does not track the event
  #frontend_experimentation_tracking_data
    when the experiment is enabled
      the user is part of the experimental group
        pushes the right parameters to gon
      the user is part of the control group
        pushes the right parameters to gon
        does not send nil value to gon
      do not track disabled
        pushes the right parameters to gon
      do not track enabled
        does not push data to gon
    when the experiment is disabled
      does not push data to gon
  #record_experiment_user
    when the experiment is enabled
      the user is part of the experimental group
        calls add_user on the Experiment model
        with a cookie based rollout strategy
          calls tracking_group with a nil subject
        with a user based rollout strategy
          calls tracking_group with a user subject
      the user is part of the control group
        calls add_user on the Experiment model
    when the experiment is disabled
      does not call add_user on the Experiment model
    when there is no current_user
      does not call add_user on the Experiment model
    do not track
      is disabled
        calls add_user on the Experiment model
      is enabled
        does not call add_user on the Experiment model
  #record_experiment_group
    when DNT is enabled
      returns early without recording the group as an ExperimentSubject
    when the experiment is not active
      returns early without recording the group as an ExperimentSubject
    when a nil group is given
      returns early without recording the group as an ExperimentSubject
    when the experiment uses a cookie-based rollout strategy
      calls tracking_group with a nil subject
      records the group
    when the experiment uses a non-cookie-based rollout strategy
      calls tracking_group with the group as the subject
      records the group
  #record_experiment_conversion_event
    records the conversion event for the experiment & user
    when DNT is enabled
      does not record the conversion event
    when there is no current user
      does not record the conversion event
    when the experiment is not enabled
      does not record the conversion event
  #experiment_tracking_category_and_group
    returns a string with the experiment tracking category & group joined with a ":"

Jira::Requests::Projects::ListService
  #execute
    without jira_integration
      returns an error response
    when jira_integration is nil
      returns an error response
    with jira_integration
      when validations and params are ok
        behaves like a service that handles Jira API errors
          allows unknown exception classes to bubble
          logs the error
          exception_class: Errno::ECONNRESET, exception_message: "", expected_message: "A connection error occurred"
            handles the error
          exception_class: Errno::ECONNREFUSED, exception_message: "", expected_message: "A connection error occurred"
            handles the error
          exception_class: Errno::ETIMEDOUT, exception_message: "", expected_message: "A timeout error occurred"
            handles the error
          exception_class: Timeout::Error, exception_message: "", expected_message: "A timeout error occurred"
            handles the error
          exception_class: URI::InvalidURIError, exception_message: "", expected_message: "The Jira API URL"
            handles the error
          exception_class: SocketError, exception_message: "", expected_message: "The Jira API URL"
            handles the error
          exception_class: OpenSSL::SSL::SSLError, exception_message: "foo", expected_message: "An SSL error occurred while connecting to Jira: foo"
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "Unauthorized", expected_message: "The credentials for accessing Jira are not valid"
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "Forbidden", expected_message: "The credentials for accessing Jira are not allowed"
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "Bad Request", expected_message: "An error occurred while requesting data from Jira"
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "Foo", expected_message: "An error occurred while requesting data from Jira."
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "{\"errorMessages\":[\"foo\",\"bar\"]}", expected_message: "An error occurred while requesting data from Jira: foo and bar"
            handles the error
          exception_class: JIRA::HTTPError, exception_message: "{\"errorMessages\":[\"\"]}", expected_message: "An error occurred while requesting data from Jira."
            handles the error
          when the JSON in JIRA::HTTPError is unsafe
            when JSON is malformed
              returns the default error message
            when JSON contains tags
              sanitizes it
        when jira runs on a subpath
          takes the subpath into account
        when the request does not return any values
          returns a paylod with no projects returned
        when the request returns values
          returns a paylod with Jira projects
          when filtering projects by name
            returns a paylod with Jira procjets

Ci::DailyBuildGroupReportResult
  associations
    is expected to belong to last_pipeline required: false
    is expected to belong to project required: false
    is expected to belong to group required: false
  validations
    when attributes are valid
      returns no errors
    when data is invalid
      returns errors
  .upsert_reports
    creates or updates matching report results
    when given data is empty
      does nothing
  scopes
    .by_projects
      returns records by projects
    .by_group
      returns records by group
    .by_ref_path
      returns coverages by ref_path
    .ordered_by_date_and_group_name
      returns coverages ordered by data and group name
    .by_dates
      when daily coverages exist during those dates
        returns coverages
    .with_coverage
      returns data with coverage
    .with_default_branch
      when coverage for the default branch exist
        returns coverage with the default branch
      when coverage for the default branch does not exist
        returns an empty collection

Projects::ProtectDefaultBranchService
  #execute
    without a default branch
      does nothing
    with a default branch
      protects the default branch
  #protect_default_branch
    when branch protection is needed
      changes the HEAD of the project
      protects the default branch
    when branch protection is not needed
      changes the HEAD of the project
      does not protect the default branch
    when protected branch does not exist
      changes the HEAD of the project
      protects the default branch
    when protected branch already exists
      changes the HEAD of the project
      does not protect the default branch
  #create_protected_branch
    creates the protected branch
  #protect_branch?
    when default branch protection is disabled
      returns false
    when default branch protection is enabled
      returns false if the branch is already protected
      returns true if the branch is not yet protected
  #default_branch
    returns the default branch of the project
  #push_access_level
    when developers can push
      returns the DEVELOPER access level
    when developers can not push
      returns the MAINTAINER access level
  #merge_access_level
    when developers can merge
      returns the DEVELOPER access level
    when developers can not merge
      returns the MAINTAINER access level

Gitlab::ImportExport::Group::RelationTreeRestorer
  restores group tree
  when log_import_export_relation_creation feature flag is enabled
    logs top-level relation creation
  when log_import_export_relation_creation feature flag is disabled
    does not log top-level relation creation

Snippets::DestroyService
  #execute
    when snippet is nil
      returns a ServiceResponse error
    when ProjectSnippet
      when user is able to admin_project_snippet
        behaves like a successful destroy
          deletes the snippet
          returns ServiceResponse success
        behaves like deletes the snippet repository
          removes the snippet repository
          when the repository deletion service raises an error
            does not try to rollback repository
            behaves like an unsuccessful destroy
              does not delete the snippet
              returns ServiceResponse error
          when a destroy error is raised
            attempts to rollback the repository
            behaves like an unsuccessful destroy
              does not delete the snippet
              returns ServiceResponse error
          when repository is nil
            does not schedule anything and return success
        project statistics
          updates stats after deletion
          schedules a namespace statistics update
      when user is not able to admin_project_snippet
        behaves like an unsuccessful destroy
          does not delete the snippet
          returns ServiceResponse error
    when PersonalSnippet
      when user is able to admin_personal_snippet
        schedules a namespace statistics update
        behaves like a successful destroy
          deletes the snippet
          returns ServiceResponse success
        behaves like deletes the snippet repository
          removes the snippet repository
          when the repository deletion service raises an error
            does not try to rollback repository
            behaves like an unsuccessful destroy
              does not delete the snippet
              returns ServiceResponse error
          when a destroy error is raised
            attempts to rollback the repository
            behaves like an unsuccessful destroy
              does not delete the snippet
              returns ServiceResponse error
          when repository is nil
            does not schedule anything and return success
      when user is not able to admin_personal_snippet
        behaves like an unsuccessful destroy
          does not delete the snippet
          returns ServiceResponse error
    when the repository does not exists
      does not schedule anything and return success

Gitlab::Kubernetes::Helm::V2::InitCommand
  behaves like helm command generator
    #generate_script
      returns appropriate command
  on a rbac-enabled cluster
    behaves like helm command generator
      #generate_script
        returns appropriate command
  behaves like helm command
    HELM_VERSION
      is expected to match /\d+\.\d+\.\d+/
    #env
      is expected to be a kind of Hash
    #rbac?
      rbac is enabled
        is expected to be truthy
      rbac is not enabled
        is expected to be falsey
    #pod_resource
      rbac is enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the tiller serviceAccountName
      rbac is not enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the default serviceAccountName
    #config_map_resource
      returns a KubeClient resource with config map content for the application
    #service_account_resource
      rbac is enabled
        generates a Kubeclient resource for the tiller ServiceAccount
      rbac is not enabled
        generates nothing
    #cluster_role_binding_resource
      rbac is enabled
        generates a Kubeclient resource for the ClusterRoleBinding for tiller
        binds the account in #service_account_resource
      rbac is not enabled
        generates nothing

Gitlab::Database::MigrationHelpers::V2
  #rename_column_concurrently
    behaves like Setting up to rename a column
      creates the renamed column, syncing existing data
      installs triggers to sync new data
      when called inside a transaction block
        raises an error
      when the existing column has a default value
        raises an error
      when passing a batch column
        when the batch column does not exist
          raises an error
        when the batch column does exist
          passes it when creating the column
    when the column to rename does not exist
      raises an error
  #undo_cleanup_concurrent_column_rename
    behaves like Setting up to rename a column
      creates the renamed column, syncing existing data
      installs triggers to sync new data
      when called inside a transaction block
        raises an error
      when the existing column has a default value
        raises an error
      when passing a batch column
        when the batch column does not exist
          raises an error
        when the batch column does exist
          passes it when creating the column
    when the renamed column does not exist
      raises an error
  #undo_rename_column_concurrently
    behaves like Cleaning up from renaming a column
      when the helper is called repeatedly
        does not make repeated attempts to cleanup
      when the renamed column exists
        removes the sync triggers and renamed columns
  #cleanup_concurrent_column_rename
    behaves like Cleaning up from renaming a column
      when the helper is called repeatedly
        does not make repeated attempts to cleanup
      when the renamed column exists
        removes the sync triggers and renamed columns
  #create_table
    using a limit: attribute on .text
      creates the table as expected
  #with_lock_retries
-- transaction_open?()
   -> 0.0002s
    sets the migration class name in the logs
-- transaction_open?()
   -> 0.0002s
    does not raise on exhaustion by default
-- transaction_open?()
   -> 0.0002s
    defaults to disallowing subtransactions
    raise_on_exhaustion: true
-- transaction_open?()
   -> 0.0001s
      sets raise_on_exhaustion as requested
    raise_on_exhaustion: false
-- transaction_open?()
   -> 0.0002s
      sets raise_on_exhaustion as requested
    when in transaction
      when lock retries are enabled
        does not use Gitlab::Database::WithLockRetries and executes the provided block directly
      when lock retries are not enabled
        raises an error

Gitlab::Ci::Trace::Checksum
  when build pending state exists
    when matching persisted trace chunks exist
      calculates combined trace chunks CRC32 correctly
    when trace chunks were persisted in a wrong order
      makes trace checksum invalid but not corrupted
    when one of the trace chunks is missing
      makes trace checksum invalid and corrupted
    when checksums of persisted trace chunks do not match
      makes trace checksum invalid but not corrupted
    when persisted trace chunks are missing
      makes trace checksum invalid
  when build pending state is missing
    #state_crc32
      returns nil
    #valid?
      is expected not to be valid
  #trace_chunks
    does not load raw_data from a database store
  #last_chunk
    when there are no chunks
      returns nil
      is not a valid trace
      is not a corrupted trace
    when there are multiple chunks
      returns chunk with the highest index
      is not a valid trace
      is not a corrupted trace
  #trace_size
    returns total trace size in bytes

Ci::PipelinePolicy
  rules
    rules for protected ref
      when no one can push or merge to the branch
        does not include ability to update pipeline
      when developers can push to the branch
        includes ability to update pipeline
      when no one can create the tag
        does not include ability to update pipeline
      when no one can create the tag but it is not a tag
        includes ability to update pipeline
    when maintainer is allowed to push to pipeline branch
      enables update_pipeline if user is maintainer
    when user does not have access to internal CI
      disallows the user from reading the pipeline
    destroy_pipeline
      when user has owner access
        is enabled
      when user is not owner
        is disabled
    read_pipeline_variable
      when user has owner access
        is enabled
      when user is developer and the creator of the pipeline
        is enabled
      when user is developer and it is not the creator of the pipeline
        is disabled
      when user is not owner nor developer
        is disabled

ContainerRegistry::Blob
  is expected to respond to #repository
  is expected to delegate #registry to the #repository object
  is expected to delegate #client to the #repository object
  #path
    returns a valid path to the blob
  #digest
    return correct digest value
  #type
    returns a correct type
  #revision
    returns a correct blob SHA
  #short_revision
    return a short SHA
  #delete
    returns true when blob has been successfully deleted
  #data
    when locally stored
      returns a correct blob data
    when externally stored
      for a valid address
        returns correct data
      for a relative address
        returns correct data
      for invalid file
        raises an error

Clusters::Applications::CheckIngressIpAddressService
  #execute
    when the ingress ip address is available
      updates the external_ip for the app
    when the ingress external hostname is available
      updates the external_hostname for the app
    when the ingress ip address is not available
      does not error
    when the exclusive lease cannot be obtained
      does not call kubeclient
  #execute
    when the ingress ip address is available
      updates the external_ip for the app
    when the ingress external hostname is available
      updates the external_hostname for the app
    when the ingress ip address is not available
      does not error
    when the exclusive lease cannot be obtained
      does not call kubeclient

ForkProjectsFinder
  #execute
    without a user
      is expected to eq [#<Project id:972 group673/project1032>>]
    with a user
      is expected to eq [#<Project id:976 group676/project1036>>, #<Project id:975 group675/project1035>>]
    with a member
      is expected to eq [#<Project id:980 group679/project1040>>, #<Project id:979 group678/project1039>>, #<Project id:978 group677/project1038>>]

Gitlab::Pagination::Keyset::Paginator
  pagination
    when per_page is greater than the record count
      is expected to eq [#<Project id:981 namespace795/project1041>>, #<Project id:984 namespace798/project1044>>, #<Project ...ect1043>>, #<Project id:982 namespace796/project1042>>, #<Project id:985 namespace799/project1045>>]
      is expected not to have next page
      is expected not to have previous page
      has no next and previous cursor values
    when 0 records are returned
      is expected to be empty
      is expected not to have next page
      is expected not to have previous page
    when page size is smaller than the record count
      is expected to eq [#<Project id:981 namespace795/project1041>>, #<Project id:984 namespace798/project1044>>]
      is expected to have next page
      is expected not to have previous page
      has next page cursor
      does not have previous page cursor
      when on the second page
        is expected to eq [#<Project id:983 namespace797/project1043>>, #<Project id:982 namespace796/project1042>>]
        is expected to have next page
        is expected to have previous page
        and then going back to the first page
          is expected to eq [#<Project id:981 namespace795/project1041>>, #<Project id:984 namespace798/project1044>>]
          is expected to have next page
          is expected not to have previous page
      when jumping to the last page
        is expected to eq [#<Project id:982 namespace796/project1042>>, #<Project id:985 namespace799/project1045>>]
        is expected not to have next page
        is expected to have previous page
        when paginating backwards
          is expected to eq [#<Project id:984 namespace798/project1044>>, #<Project id:983 namespace797/project1043>>]
          is expected to have next page
          is expected to have previous page
        when jumping to the first page
          is expected to eq [#<Project id:981 namespace795/project1041>>, #<Project id:984 namespace798/project1044>>]
          is expected to have next page
          is expected not to have previous page
    default keyset direction parameter
      exposes the direction parameter in the cursor
  when unsupported order is given
    raises error
  when use_union_optimization option is true and ordering by two columns
    uses UNION queries

Issues::SetCrmContactsService
  #execute
    when the user has no permission
      returns expected error response
    when user has permission
      when the contact does not exist
        returns expected error response
      when the contact belongs to a different group
        returns expected error response
      replace
        updates the issue with correct contacts
      add
        updates the issue with correct contacts
      add by email
        updates the issue with correct contacts
      remove
        updates the issue with correct contacts
      remove by email
        updates the issue with correct contacts
      when attempting to add more than 6
        returns expected error message
      when trying to remove non-existent contact
        returns expected error message
      when combining params
        add and remove
          updates the issue with correct contacts
        replace and remove
          returns expected error response
        replace and add
          returns expected error response
      when trying to add an existing issue contact
        does not return an error
      when trying to add the same contact twice
        does not return an error
      when trying to remove a contact not attached to the issue
        does not return an error

Ci::ArchiveTraceService#execute
  when job is finished
    creates an archived trace
    when trace is already archived
      ignores an exception
      does not create an archived trace
      when live trace chunks still exist
        removes the trace chunks
        when associated data does not exist
          removes the trace artifact and builds a new one
    when job does not have trace
      leaves a warning message in sidekiq log
    when the job is out of archival attempts
      skips archiving
      leaves a warning message in sidekiq log
      job has archive and chunks
        removes trace chunks
        archive is not completed
          cleanups any stale archive data
    when the archival process is backed off
      skips archiving
      leaves a warning message in sidekiq log
    when job failed to archive trace but did not raise an exception
      leaves a warning message in sidekiq log
  when job is running
    increments Prometheus counter, sends crash report to Sentry and ignore an error for continuing to archive

Snippets::UpdateStatisticsService
  #execute
    with PersonalSnippet
      behaves like updates statistics
        returns a successful response
        expires statistics cache
        schedules a namespace storage statistics update
        when snippet statistics does not exist
          creates snippet statistics
        when snippet statistics exists
          updates snippet statistics
        when snippet does not have a repository
          returns an error response
    with ProjectSnippet
      updates projects statistics "snippets_size"
      behaves like updates statistics
        returns a successful response
        expires statistics cache
        schedules a namespace storage statistics update
        when snippet statistics does not exist
          creates snippet statistics
        when snippet statistics exists
          updates snippet statistics
        when snippet does not have a repository
          returns an error response

Projects::GroupsFinder
  #execute
    Public project
      behaves like finding related groups
        returns ancestor groups for this project
        when the project does not belong to any group
          is expected to eq []
        when shared groups option is on
          returns ancestor and all shared groups
          when shared_min_access_level is developer
            returns ancestor and shared groups with at least developer access
          when shared_visible_only is on
            returns ancestor and public shared groups
            when user has access to the private shared group
              returns ancestor and shared groups user has access to
        when skip group option is on
          excludes provided groups
        when user is not authorized
          returns ancestor groups for this project
          when visible shared groups are requested
            returns ancestor groups and public shared groups for this project
    Private project
      behaves like finding related groups
        returns ancestor groups for this project
        when the project does not belong to any group
          is expected to eq []
        when shared groups option is on
          returns ancestor and all shared groups
          when shared_min_access_level is developer
            returns ancestor and shared groups with at least developer access
          when shared_visible_only is on
            returns ancestor and public shared groups
            when user has access to the private shared group
              returns ancestor and shared groups user has access to
        when skip group option is on
          excludes provided groups
        when user is not authorized
          is expected to eq []
    Missing project
      is expected to eq []

Ci::JobArtifacts::CreateService
  #execute
    when artifacts file is uploaded
      saves artifact for the given type
      does not track the job user_id
      when metadata file is also uploaded
        saves metadata artifact
        sets expiration date according to application settings
        when expire_in params is set to a specific value
          sets expiration date according to the parameter
        when expire_in params is set to `never`
          sets expiration date according to the parameter
    when artifacts file already exists
      when sha256 of uploading artifact is the same of the existing one
        ignores the changes
      when sha256 of uploading artifact is different than the existing one
        returns error status
    when artifact type is dotenv
      calls parse service
    when artifact_type is metrics
      tracks the job user_id
    behaves like rescues object storage error
      handles Errno::EIO
    behaves like rescues object storage error
      handles Google::Apis::ServerError
    behaves like rescues object storage error
      handles Signet::RemoteServerError

Gitlab::ErrorTracking
  .track_and_raise_for_dev_exception
    when exceptions for dev should be raised
      raises the exception
    when exceptions for dev should not be raised
      logs the exception with all attributes passed
      calls Gitlab::ErrorTracking::Logger.error with formatted payload
  .track_and_raise_exception
    always raises the exception
    calls Gitlab::ErrorTracking::Logger.error with formatted payload
  .track_exception
    calls Raven.capture_exception
    calls Gitlab::ErrorTracking::Logger.error with formatted payload
    with filterable parameters
      filters parameters
    the exception implements :sentry_extra_data
      includes the extra data from the exception in the tracking information
    the exception implements :sentry_extra_data, which returns nil
      just includes the other extra info
    when the error is kind of an `ActiveRecord::StatementInvalid`
      injects the normalized sql query into extra
    when the `ActiveRecord::StatementInvalid` is wrapped in another exception
      injects the normalized sql query into extra
    when the `ActiveRecord::StatementInvalid` is a bad query
      injects the query as-is into extra
  event processors
    custom GitLab context when using Raven.capture_exception directly
      merges a default set of tags into the existing tags
      merges the current user information into the existing user information
    with sidekiq args
      when the args does not have anything sensitive
        ensures extra.sidekiq.args is a string
        does not filter parameters when sending to Sentry
      when the args has sensitive information
        filters sensitive arguments before sending and logging
    when the error is a GRPC error
      when the GRPC error contains a debug_error_string value
        sets the GRPC debug error string in the Sentry event and adds a custom fingerprint
      when the GRPC error does not contain a debug_error_string value
        does not do any processing on the event

Projects::Settings::DeployKeysPresenter
  inherits from Gitlab::View::Presenter::Simple
  deploy key groups
    with enabled keys
      returns correct deploy keys
    with available keys
      returns correct deploy keys
    with available project keys
      returns correct deploy keys
    with available public keys
      returns correct deploy keys
  #enabled_keys
    returns currently enabled keys
    does not contain enabled_keys inside available_keys
    returns the enabled_keys size
  #available_keys/#available_project_keys
    returns the current available_keys
    returns the current available_project_keys
    returns the available_project_keys size
  prevent N + 1 queries
    returns correct counts
    does not increase the query count

Gitlab::SlashCommands::Presenters::IssueMove
  is expected to be a kind of Hash
  shows the new issue
  mentions the old issue and the new issue in the pretext

notify/pipeline_failed_email.html.haml
  behaves like pipeline status changes email
    when the pipeline contains a failed job
      behaves like renders the pipeline status changes email correctly
        pipeline with user
          renders the email correctly
          behaves like correct pipeline information for pipelines for merge requests
            when pipeline for merge request
              renders a source ref of the pipeline
        pipeline without user
          renders the email correctly
    when the latest failed job is a bridge job
      behaves like renders the pipeline status changes email correctly
        pipeline with user
          renders the email correctly
          behaves like correct pipeline information for pipelines for merge requests
            when pipeline for merge request
              renders a source ref of the pipeline
        pipeline without user
          renders the email correctly

Labels::CreateService
  #execute
    in a project
      with color in hex-code
        creates a label
      with color in allowed name
        creates a label
      with color in up-case allowed name
        creates a label
      with color surrounded by spaces
        creates a label
      with unknown color
        doesn't create a label
      with no color
        doesn't create a label
    in a group
      with color in hex-code
        creates a label
      with color in allowed name
        creates a label
      with color in up-case allowed name
        creates a label
      with color surrounded by spaces
        creates a label
      with unknown color
        doesn't create a label
      with no color
        doesn't create a label
    in admin area
      with color in hex-code
        creates a label
      with color in allowed name
        creates a label
      with color in up-case allowed name
        creates a label
      with color surrounded by spaces
        creates a label
      with unknown color
        doesn't create a label
      with no color
        doesn't create a label

Gitlab::Metrics::Methods
  #define_metrics
    metrics access method not defined
      defines metrics accessing method
    metrics access method defined
      raises error when trying to redefine method
      metric is not cached
        calls fetch_metric
      metric is cached
        returns cached metric
  #fetch_metric
    when counter is not cached
      initializes counter metric
    when counter is cached
      uses class metric cache
      when metric is reloaded
        initializes counter metric
    when metric is configured with feature
      when feature is enabled
        initializes counter metric
      when feature is disabled
        returns NullMetric
  #define_metrics
    metrics access method not defined
      defines metrics accessing method
    metrics access method defined
      raises error when trying to redefine method
      metric is not cached
        calls fetch_metric
      metric is cached
        returns cached metric
  #fetch_metric
    when gauge is not cached
      initializes counter metric
    when gauge is cached
      uses class metric cache
      when metric is reloaded
        initializes gauge metric
    when metric is configured with feature
      when feature is enabled
        initializes gauge metric
      when feature is disabled
        returns NullMetric
  #define_metrics
    metrics access method not defined
      defines metrics accessing method
    metrics access method defined
      raises error when trying to redefine method
      metric is not cached
        calls fetch_metric
      metric is cached
        returns cached metric
  #fetch_metric
    when histogram is not cached
      initializes counter metric
    when histogram is cached
      uses class metric cache
      when metric is reloaded
        initializes histogram metric
    when metric is configured with feature
      when feature is enabled
        initializes histogram metric
      when feature is disabled
        returns NullMetric

ProjectHook
  associations
    is expected to belong to project required: false
  validations
    is expected to validate that :project cannot be empty/falsy
  behaves like includes Limitable concern
    validations
      is expected to be a kind of Limitable
      without plan limits configured
        can create new models
      with plan limits configured
        can create new models
        with an existing model
          cannot create new models exceeding the plan limits
  .push_hooks
    returns hooks for push events only
  .tag_push_hooks
    returns hooks for tag push events only
  #rate_limit
    returns the default limit
  #application_context
    includes the type and project

projects/merge_requests/show.html.haml
  when the merge request is open
    shows the "Mark as draft" button
  when the merge request is closed
    shows the "Reopen" button
    when source project does not exist
      does not show the "Reopen" button
  gitpod modal
    site_enabled: false, current_user: user, should_show: false
      handles rendering gitpod user enable modal
    site_enabled: true, current_user: user, should_show: true
      handles rendering gitpod user enable modal
    site_enabled: true, current_user: nil, should_show: true
      handles rendering gitpod user enable modal
    site_enabled: true, current_user: user_gitpod_enabled, should_show: false
      handles rendering gitpod user enable modal

Schedulable
  for a pipeline_schedule
    behaves like #schedule_next_run!
      saves the object and sets next_run_at
      sets next_run_at to nil on error
    behaves like before_save callback
      updates next_run_at
    behaves like .runnable_schedules
      returns the runnable schedules
  for a container_expiration_policy
    behaves like #schedule_next_run!
      saves the object and sets next_run_at
      sets next_run_at to nil on error
    behaves like before_save callback
      updates next_run_at
    behaves like .runnable_schedules
      returns the runnable schedules
  #next_run_at
    works

DiscussionDiffFileEntity
  when there is no merge request
    behaves like diff file discussion entity
      behaves like diff file base entity
        exposes essential attributes
        when diff file does not have a blob and content sha
          exposes some attributes as nil
  when there is a merge request
    exposes additional attributes
    exposes no diff lines
    behaves like diff file discussion entity
      behaves like diff file base entity
        exposes essential attributes
        when diff file does not have a blob and content sha
          exposes some attributes as nil

ContributedProjectsFinder
  activity without a current user
    is expected to contain exactly #<Project id:1075 namespace890/project1136>>
  activity with a current user
    is expected to contain exactly #<Project id:1079 namespace894/project1140>>, #<Project id:1080 namespace895/project1141>>, and #<Project id:1078 namespace893/project1139>>
  user with private profile
    does not return contributed projects

Gitlab::Database::Count
  .approximate_counts
    fallbacks
      gets results from first strategy
      gets more results from second strategy if some counts are missing
      does not get more results as soon as all counts are present
    default strategies
      with a read-only database
        only uses the ExactCountStrategy
      with a read-write database
        uses the available strategies

ProjectFeaturesCompatibility
  converts fields from 'true' to ProjectFeature::ENABLED
  converts fields from 'false' to ProjectFeature::DISABLED
  converts fields from true to ProjectFeature::ENABLED
  converts fields from false to ProjectFeature::DISABLED
  access levels
    access_level: "disabled", expected_result: 0
      accepts access level
    access_level: "private", expected_result: 10
      accepts access level
    access_level: "enabled", expected_result: 20
      accepts access level
    access_level: "public", expected_result: 30
      accepts access level

RateLimitedService
  RateLimitedError
    #headers
      returns a Hash of HTTP headers
    #log_request
      logs the request
  RateLimiterScopedAndKeyed
    #rate_limit!
      when :rate_limited_service_issues_create feature is globally disabled
        behaves like a service that does not attempt to throttle
          does not attempt to throttle
      when :rate_limited_service_issues_create feature is globally enabled
        behaves like a service that does attempt to throttle
          when rate limiting is not in effect
            does not raise an exception
          when rate limiting is in effect
            raises a RateLimitedError exception
      when :rate_limited_service_issues_create feature is enabled for project_with_feature_enabled
        for project_without_feature_enabled
          behaves like a service that does not attempt to throttle
            does not attempt to throttle
        for project_with_feature_enabled
          behaves like a service that does attempt to throttle
            when rate limiting is not in effect
              does not raise an exception
            when rate limiting is in effect
              raises a RateLimitedError exception
  #execute_without_rate_limiting
    bypasses rate limiting
      calls super
  #execute
    when rate_limit has not been called
      raises an RateLimitedNotSetupError exception
    when rate_limit has been called
      and applies rate limiting
        raises an RateLimitedService::RateLimitedError exception
      but does not apply rate limiting
        calls super

Gitlab::RackAttack
  .configure
    extends the request class
    configures the throttle response
    configures the safelist
    configures throttles if no dry-run was configured
    configures tracks if dry-run was configured for all throttles
    configures tracks and throttles with a selected set of dry-runs
    enables dry-runs for `throttle_unauthenticated_api` and `throttle_unauthenticated_web` when selecting `throttle_unauthenticated`
    user allowlist
      is empty
      reflects GITLAB_THROTTLE_USER_ALLOWLIST
  .throttled_response_headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3600, :epoch_time=>1609842570}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"60", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1830"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3600, :epoch_time=>1609844399}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"60", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3600, :epoch_time=>1609840800}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"60", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"3600"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3600, :epoch_time=>1609889400}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"60", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609891200", "RateLimit-ResetTime"=>"Wed, 06 Jan 2021 00:00:00 GMT", "Retry-After"=>"1800"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3400, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"57", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1800"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>3700, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"62", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1800"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>59, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"1", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1800"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>1 hour, :limit=>61, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"2", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609844400", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 11:00:00 GMT", "Retry-After"=>"1800"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>15 seconds, :limit=>10, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"40", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609842615", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 10:30:15 GMT", "Retry-After"=>"15"}
      generates accurate throttled headers
    matched: "throttle_unauthenticated", match_data: {:discriminator=>"127.0.0.1", :count=>3700, :period=>27 seconds, :limit=>10, :epoch_time=>1609842600}, headers: {"RateLimit-Name"=>"throttle_unauthenticated", "RateLimit-Limit"=>"23", "RateLimit-Observed"=>"3700", "RateLimit-Remaining"=>"0", "RateLimit-Reset"=>"1609842627", "RateLimit-ResetTime"=>"Tue, 05 Jan 2021 10:30:27 GMT", "Retry-After"=>"27"}
      generates accurate throttled headers

Gitlab::Ci::Reports::TestReports
  #get_suite
    when suite name is rspec
      is expected to eq "rspec"
      initializes a new test suite and returns it
      when suite name is already allocated
        does not initialize a new test suite
  #total_time
    returns the total time
  #total_count
    returns the total count
  #total_status
    when all test cases succeeded
      returns correct total status
    when there is a failed test case
      returns correct total status
    when there is a skipped test case
      returns correct total status
    when there is an error test case
      returns correct total status
  #with_attachment
    when test suites do not contain an attachment
      returns empty test suites
    when test suites contain an attachment
      returns test suites with attachment
  #suite_errors
    when a suite has normal spec errors or failures
      is expected to be empty
    when there is an error test case
      is expected to eq {"junit"=>"Existential parsing error"}
  #error_count
    when error test case exists
      returns the count
    when error test case do not exist
      returns nothing
  #failed_count
    when failed test case exists
      returns the count
    when failed test case do not exist
      returns nothing
  #success_count
    when success test case exists
      returns the count
    when success test case do not exist
      returns nothing
  #skipped_count
    when skipped test case exists
      returns the count
    when skipped test case do not exist
      returns nothing

gettext
  :compile
    creates a pot file and invokes the 'gettext:po_to_json' task
  :regenerate
    when the locale folder is not found
      raises an error
    where there are existing /**/gitlab.po files
      does not remove that locale
    when there are locale folders without a gitlab.po file
      removes those folders
    when the gitlab.pot file cannot be generated
      prints an error
    when gettext:find changes the revision dates
      resets the changes
  :lint
    when all PO files are valid

Linting po files: |============================================================|
      completes without error
    when there are invalid PO files

Linting po files: |============================================================|
      raises an error
    when the .pot file is invalid

Linting po files: |============================================================|
      raises an error

Ci::RunScheduledBuildService
  when user can update build
    when build is scheduled
      when scheduled_at is expired
        can run the build
        when build requires resource
          transits to waiting for resource status
      when scheduled_at is not expired
        can not run the build
    when build is not scheduled
      can not run the build
  when user can not update build
    when build is scheduled
      can not run the build

Gitlab::VisibilityLevelChecker
  #level_restricted?
    when visibility level is allowed
      returns false with nil for visibility level
    when visibility level is restricted
      for public project
        for non-admin user
          returns true and visibility name
        for admin user
          returns false and a nil visibility level
      overridden visibility
        when restricted
          returns true and visibility name
        when misspelled
          returns false with nil for visibility level
        when import_data is missing
          returns false with nil for visibility level

Gitlab::SlashCommands::Presenters::IssueShow
  is expected to be a kind of Hash
  shows the issue
  with upvotes
    shows the upvote count
  with labels
    shows the labels
  confidential issue
    shows an ephemeral response

Ci::DeleteUnitTestsWorker
  #perform
    executes a service
  behaves like an idempotent worker
    is labeled as idempotent
    performs multiple times sequentially without raising an exception
    only deletes old unit tests and their failures

Packages::DependencyLink
  relationships
    is expected to belong to package required: false inverse_of => dependency_links
    is expected to belong to dependency required: false inverse_of => dependency_links
    is expected to have one nuget_metadatum inverse_of => dependency_link
  validations
    is expected to validate that :package cannot be empty/falsy
    is expected to validate that :dependency cannot be empty/falsy
    package_id and package_dependency_id uniqueness for dependency_type
      is not valid
  with multiple links
    .with_dependency_type
      returns links of the given type
    .for_package
      returns the link for the given package

Gitlab::Kubernetes::Helm::V2::InstallCommand
  behaves like helm command generator
    #generate_script
      returns appropriate command
  when rbac is true
    behaves like helm command generator
      #generate_script
        returns appropriate command
  when there is a pre-install script
    behaves like helm command generator
      #generate_script
        returns appropriate command
  when there is a post-install script
    behaves like helm command generator
      #generate_script
        returns appropriate command
  when there is no version
    behaves like helm command generator
      #generate_script
        returns appropriate command
  behaves like helm command
    HELM_VERSION
      is expected to match /\d+\.\d+\.\d+/
    #env
      is expected to be a kind of Hash
    #rbac?
      rbac is enabled
        is expected to be truthy
      rbac is not enabled
        is expected to be falsey
    #pod_resource
      rbac is enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the tiller serviceAccountName
      rbac is not enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the default serviceAccountName
    #config_map_resource
      returns a KubeClient resource with config map content for the application
    #service_account_resource
      rbac is enabled
        generates a Kubeclient resource for the tiller ServiceAccount
      rbac is not enabled
        generates nothing
    #cluster_role_binding_resource
      rbac is enabled
        generates a Kubeclient resource for the ClusterRoleBinding for tiller
        binds the account in #service_account_resource
      rbac is not enabled
        generates nothing

InjectEnterpriseEditionModule
  #prepend_mod_with
    behaves like expand the extension with
      when extension namespace is set at top-level
        calls prepend with the extension module
      when extension namespace is set at another namespace
        calls prepend with the extension module from the additional namespace
      when extension namespace exists but not the extension
        does not call prepend
      when extension namespace does not exist
        does not call prepend
  #extend_mod_with
    behaves like expand the extension with
      when extension namespace is set at top-level
        calls extend with the extension module
      when extension namespace is set at another namespace
        calls extend with the extension module from the additional namespace
      when extension namespace exists but not the extension
        does not call extend
      when extension namespace does not exist
        does not call extend
  #include_mod_with
    behaves like expand the extension with
      when extension namespace is set at top-level
        calls include with the extension module
      when extension namespace is set at another namespace
        calls include with the extension module from the additional namespace
      when extension namespace exists but not the extension
        does not call include
      when extension namespace does not exist
        does not call include
  #prepend_mod
    behaves like expand the assumed extension with
      when extension namespace is set at top-level
        calls prepend with the extension module
      when extension namespace exists but not the extension
        does not call prepend
      when extension namespace does not exist
        does not call prepend
  #extend_mod
    behaves like expand the assumed extension with
      when extension namespace is set at top-level
        calls extend with the extension module
      when extension namespace exists but not the extension
        does not call extend
      when extension namespace does not exist
        does not call extend
  #include_mod
    behaves like expand the assumed extension with
      when extension namespace is set at top-level
        calls include with the extension module
      when extension namespace exists but not the extension
        does not call include
      when extension namespace does not exist
        does not call include

LfsDownloadObject
  #headers
    returns specified Hash
    with nil headers
      returns a Hash
  #has_authorization_header?
    returns false
    with uppercase form
      returns true
    with lowercase form
      returns true
  validations
    is expected to validate that :size looks like a number greater than or equal to 0
    oid attribute
      must be 64 characters long
      must contain only hexadecimal characters
    link attribute
      only http and https protocols are valid
      cannot be empty
      when localhost or local network addresses
        are allowed
          is expected to be valid
        are not allowed
          is expected to be invalid
    headers attribute
      only nil and Hash values are valid

Gitlab::Ci::Config::Entry::Service
  when configuration is a string
    #valid?
      is valid
    #value
      returns valid hash
    #image
      returns service's image name
    #alias
      returns service's alias
    #command
      returns service's command
    #ports
      returns service's ports
  when configuration is a hash
    #valid?
      is valid
    #value
      returns valid hash
    #image
      returns service's image name
    #alias
      returns service's alias
    #command
      returns service's command
    #entrypoint
      returns service's entrypoint
    when configuration has ports
      when with_image_ports metadata is not enabled
        #valid?
          is not valid
      when with_image_ports metadata is enabled
        #valid?
          is valid
          when unknown port keys detected
            is not valid
        #ports
          returns image's ports
  when entry value is not correct
    #errors
      saves errors
    #valid?
      is not valid
  when unexpected key is specified
    #errors
      saves errors
    #valid?
      is not valid
  when service has ports
    alias field is mandatory
  when service does not have ports
    alias field is optional

FinderWithGroupHierarchy
  when specifying group
    returns only the group by default
  when specifying group_id
    returns only the group by default
  when including items from group ancestors
    returns group and its ancestors
    ignores groups which user can not read
    returns them all when skip_authorization is true
  when including items from group descendants
    returns items from group and its descendants
    ignores items from groups which user can not read
    returns them all when skip_authorization is true

Gitlab::Ci::Reports::Security::Report
  is expected to eq "sast"
  is expected to delegate #project_id to the #pipeline object
  #add_scanner
    stores given scanner params in the map
    returns the added scanner
  #add_identifier
    stores given identifier params in the map
    returns the added identifier
  #add_finding
    enriches given finding and stores it in the collection
  #clone_as_blank
    creates a blank report with copied type and pipeline
  #replace_with!
    replaces report contents with other reports contents
  #merge!
    invokes the merge with other report and then replaces this report contents by merge result
  #primary_scanner
    is expected to eq #<Gitlab::Ci::Reports::Security::Scanner:0x00007fecb448ee70 @external_id="external_id_1", @name="Find Security Bugs", @vendor="Security Scanner Vendor", @version="1.0.0">
  #add_error
    when the message is not given
      adds a new error to report with the generic error message
    when the message is given
      adds a new error to report
  errored?
    when the report does not have any errors
      is expected to be falsey
    when the report has errors
      is expected to be truthy
  #primary_scanner_order_to
    when the primary scanner of the receiver is nil
      when the primary scanner of the other is nil
        is expected to equal 1
      when the primary scanner of the other is not nil
        is expected to equal 1
    when the primary scanner of the receiver is not nil
      when the primary scanner of the other is nil
        is expected to equal -1
      when the primary scanner of the other is not nil
        compares two scanners
  #has_signatures?
    when the findings of the report does not have signatures
      is expected to be falsey
    when the findings of the report have signatures
      is expected to be truthy

Gitlab::Shell
  is expected to respond to #remove_repository
  memoized secret_token
    creates and links the secret token file
  projects commands
    #remove_repository
      returns true when the command succeeds
      keeps the namespace directory
    #mv_repository
      returns true when the command succeeds
      returns false when the command fails
  namespace actions
    #add_namespace
      creates a namespace
    #repository_exists?
      when the repository does not exist
        returns false
      when the repository exists
        returns true
    #remove
      removes the namespace
    #mv_namespace
      renames the namespace

Terraform::RemoteStateHandler
  #find_with_lock
    without a state name
      raises an exception
    with a state name
      with no matching state
        raises an exception
      with a matching state
        returns the state
  when state locking is not being used
    #handle_with_lock
      allows to modify a state using database locking
      returns nil
    #lock!
      raises an error
  when using locking
    #handle_with_lock
      handles a locked state using exclusive read lock
      raises exception if lock has not been acquired before
      user does not have permission to modify state
        raises an exception
    #lock!
      allows to lock state if it does not exist yet
      allows to lock state if it exists and is not locked
      raises an exception when trying to unlocked state locked by someone else
    #unlock!
      unlocks the state
      with no lock ID (force-unlock)
        unlocks the state
      with different lock ID
        raises an exception

Routing::PseudonymizationHelper
  when url has params to mask
    with controller for MR
      behaves like masked url
        generates masked page url
    with controller for issue
      behaves like masked url
        generates masked page url
    with controller for groups with subgroups and project
      behaves like masked url
        generates masked page url
    with controller for groups and subgroups
      behaves like masked url
        generates masked page url
    with controller for blob with file path
      behaves like masked url
        generates masked page url
    when assignee_username is present
      behaves like masked url
        generates masked page url
    when author_username is present
      behaves like masked url
        generates masked page url
    when some query params are not required to be masked
      behaves like masked url
        generates masked page url
    when query string has keys with the same names as path params
      behaves like masked url
        generates masked page url
  when url has no params to mask
    returns root url
      masked_page_url
  when it raises exception
    calls error tracking
      sends error to sentry and returns nil
  when feature flag is disabled
    returns nil

Gitlab::Database::Partitioning::TimePartition
  .from_sql
    uses specified table name
    uses specified partition name
    parses start date
    parses end date
    with MINVALUE as a start date
      sets from to nil
    with MAXVALUE as an end date
      raises a NotImplementedError
  #partition_name
    uses table as prefix
    uses Year-Month (from) as suffix
    without from date
      uses 000000 as suffix for first partition
    with partition name explicitly given
      uses given partition name
  #to_sql
    transforms to a CREATE TABLE statement
    without from date
      uses MINVALUE instead
  object equality - #eql
    treats objects identical with identical attributes
    different table leads to in-equality
    different from leads to in-equality
    different to leads to in-equality
    different partition_name leads to in-equality
    nil partition_name is ignored if auto-generated matches
  Comparable, #<=>
    sorts by partition name, i.e. by month - MINVALUE partition first
    returns nil for partitions of different tables

projects/commit/show.html.haml
  inline diff view
    has limited width
  parallel diff view
    spans full width
  in the context of a merge request
    shows that it is in the context of a merge request

Banzai::ReferenceParser::LabelParser
  #nodes_visible_to_user
    when the link has a data-issue attribute
      behaves like referenced feature visibility
        when feature is disabled
          does not create reference
        when feature is enabled only for team members
          does not create reference for non member
          creates reference for member
        when feature is enabled
          creates reference
  #referenced_by
    when the link has a data-label attribute
      using an existing label ID
        returns an Array of labels
      using a non-existing label ID
        returns an empty Array

Banzai::Filter::WikiLinkFilter
  doesn't rewrite absolute links
  doesn't rewrite links to project uploads
  when links are rewritable
    stores original url in the data-canonical-src attribute
  when links are not rewritable
    does not store original url in the data-canonical-src attribute
  when links point to the relative wiki path
    does not rewrite links
  when links point to the uploads folder
    with an "a" html tag
      rewrites links
    with "img" html tag
      inside an "a" html tag
        rewrites links
      outside an "a" html tag
        rewrites links
    with "video" html tag
      rewrites links
    with "audio" html tag
      rewrites links
  invalid links
    doesn't rewrite invalid invalid_links like http://:8080
    doesn't rewrite invalid invalid_links like http://
    doesn't rewrite invalid invalid_links like http://:8080/path

shared/_global_alert.html.haml
  renders the title
  variants
    renders an info alert by default
    renders a warning variant
    renders a success variant
    renders a danger variant
    renders a tip variant
  dismissible option
    shows the dismiss button by default
    does not show the dismiss button when dismissible is false
  fixed layout
    does not add layout limited class
    adds container classes
    does not add container classes if is_contained is true
  fluid layout
    adds layout limited class
    does not add container classes

AlertManagement::Alerts::Todo::CreateService
  #execute
    when the user is anonymous
      behaves like permissions error
        returns an error
    when the user does not have permission
      behaves like permissions error
        returns an error
    when user has permission
      creates a todo
      returns the alert and todo in the payload
      when the user has a marked todo for the alert
        when todo is pending
          does not create a todo
          returns an error
        when todo is done
          is expected to equal true
          is expected to change `Todo.count` by 1

Resolvers::DesignManagement::Version::DesignAtVersionResolver
  #resolve
    passing combinations of arguments
      passing no arguments
        behaves like a bad argument
          raises an appropriate error
      passing all arguments
        behaves like a bad argument
          raises an appropriate error
      passing any two arguments
        behaves like a bad argument
          raises an appropriate error
    passing id
      finds the design
      when the user cannot see designs
        returns nothing
    passing design_id
      finds the design
      when the user cannot see designs
        returns nothing
    passing filename
      finds the design
      when the user cannot see designs
        returns nothing
    attempting to retrieve an object not visible at this version
      passing id
        does not find the design
      passing design_id
        does not find the design
      passing filename
        does not find the design

Gitlab::Kubernetes::Helm::V3::PatchCommand
  behaves like helm command generator
    #generate_script
      returns appropriate command
  when rbac is true
    behaves like helm command generator
      #generate_script
        returns appropriate command
  when there is no version
    is expected to raise ArgumentError with "version is required"
  #pod_name
    is expected to eq "install-app-name"
  behaves like helm command
    HELM_VERSION
      is expected to match /\d+\.\d+\.\d+/
    #env
      is expected to be a kind of Hash
    #rbac?
      rbac is enabled
        is expected to be truthy
      rbac is not enabled
        is expected to be falsey
    #pod_resource
      rbac is enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the tiller serviceAccountName
      rbac is not enabled
        is expected to be an instance of Kubeclient::Resource
        generates a pod that uses the default serviceAccountName
    #config_map_resource
      returns a KubeClient resource with config map content for the application
    #service_account_resource
      rbac is enabled
        generates a Kubeclient resource for the tiller ServiceAccount
      rbac is not enabled
        generates nothing
    #cluster_role_binding_resource
      rbac is enabled
        generates a Kubeclient resource for the ClusterRoleBinding for tiller
        binds the account in #service_account_resource
      rbac is not enabled
        generates nothing

ChatNames::FindUserService
  #execute
    find user mapping
      when existing user is requested
        returns the existing chat_name
        updates the last used timestamp if one is not already set
        only updates an existing timestamp once within a certain time frame
      when different user is requested
        returns existing user

Mutations::Terraform::State::Delete
  is expected to eq "TerraformStateDelete"
  is expected to require graphql authorizations :admin_terraform_state
  #resolve
    user does not have permission
      raises an error
    user has permission
      deletes the state
    with invalid params
      raises an error

Metrics::Dashboard::TransientEmbedService
  .valid_params?
    is expected to be truthy
    missing embedded
      is expected to be falsey
    not embedded
      is expected to be falsey
    missing embed_json
      is expected to be falsey
  #get_dashboard
    caches the unprocessed dashboard for subsequent calls
    caches unique requests separately
    behaves like valid embedded dashboard service response
      behaves like valid dashboard service response for schema
        returns a json representation of the dashboard
    behaves like raises error for users with insufficient permissions
      when the user does not have sufficient access
        behaves like misconfigured dashboard service response
          returns an appropriate message and status code
      when the user is anonymous
        behaves like misconfigured dashboard service response
          returns an appropriate message and status code
    when embed_json cannot be parsed as json
      behaves like misconfigured dashboard service response
        returns an appropriate message and status code

Gitlab::NullRequestStore
  #store
    returns an empty hash
  #active?
    returns falsey
  #read
    returns nil
  #[]
    returns nil
  #write
    returns the same value
  #[]=
    returns the same value
  #exist?
    returns falsey
  #fetch
    returns the block result
  #delete
    when a block is given
      yields the key to the block
      returns the block result
    when a block is not given
      returns nil

ExperimentSubject
  associations
    is expected to belong to experiment required: false
    is expected to belong to user required: false
    is expected to belong to namespace required: false
    is expected to belong to project required: false
  validations
    is expected to validate that :experiment cannot be empty/falsy
    must_have_one_subject_present
      fails when no subject is present
      passes when user subject is present
      passes when namespace subject is present
      passes when project subject is present
      fails when more than one subject is present
  .valid_subject?
    when passing a Group, Namespace, User or Project
      is expected to equal true
      is expected to equal true
      is expected to equal true
      is expected to equal true
    when passing another object
      is expected to equal false

Integrations::Bugzilla
  Validations
    when integration is active
      is expected to validate that :project_url cannot be empty/falsy
      is expected to validate that :issues_url cannot be empty/falsy
      is expected to validate that :new_issue_url cannot be empty/falsy
      behaves like issue tracker integration URL attribute
        is expected to allow :project_url to be ‹"https://example.com"›
        is expected not to allow :project_url to be ‹"example.com"›
        is expected not to allow :project_url to be ‹"ftp://example.com"›
        is expected not to allow :project_url to be ‹"herp-and-derp"›
      behaves like issue tracker integration URL attribute
        is expected to allow :issues_url to be ‹"https://example.com"›
        is expected not to allow :issues_url to be ‹"example.com"›
        is expected not to allow :issues_url to be ‹"ftp://example.com"›
        is expected not to allow :issues_url to be ‹"herp-and-derp"›
      behaves like issue tracker integration URL attribute
        is expected to allow :new_issue_url to be ‹"https://example.com"›
        is expected not to allow :new_issue_url to be ‹"example.com"›
        is expected not to allow :new_issue_url to be ‹"ftp://example.com"›
        is expected not to allow :new_issue_url to be ‹"herp-and-derp"›
    when integration is inactive
      is expected not to validate that :project_url cannot be empty/falsy
      is expected not to validate that :issues_url cannot be empty/falsy
      is expected not to validate that :new_issue_url cannot be empty/falsy

Gitlab::WikiPages::FrontMatterParser
  #parse
    there is front matter
      is expected to have attributes {:content => "This is the content\n", :error => (be nil), :front_matter => (include {:a => 1, :b => 2, :c => ["foo", "bar"]})}
    there is no content
      is expected to have attributes {:content => "", :error => (be nil), :front_matter => {}}
    there is no front_matter
      is expected to have attributes {:content => "This is the content", :front_matter => (be empty)}
      is expected to have attributes {:reason => :no_match}
    the feature flag is disabled
      is expected to have attributes {:content => "---\na: 1\nb: 2\nc:\n - foo\n - bar\ndate: I am safe. Not actually a date\n---\nThis is the content\n", :front_matter => (be empty)}
    the feature flag is enabled for the gated object
      is expected to have attributes {:content => "This is the content\n", :front_matter => (include {:a => 1, :b => 2, :c => ["foo", "bar"]}), :reason => (be nil)}
    the end divider is ...
      is expected to have attributes {:front_matter => (include {:a => 1, :b => 2, :c => ["foo", "bar"]})}
    the front-matter is not a mapping
      is expected to have attributes {:reason => :not_mapping}
    there is nothing in the front-matter block
      is expected to have attributes {:reason => :no_match}
    there is a string in the YAML block
      is expected to have attributes {:reason => :not_mapping}
    there is dangerous YAML in the block
      is expected to have attributes {:error => (be present), :reason => :parse_error}
    there is acceptably long YAML in the front-matter block
      is expected to have attributes {:front_matter => (include {:title => (be present)})}
    there is suspiciously long YAML in the front-matter block
      is expected to have attributes {:reason => :too_long}
    TOML front matter
      is expected to have attributes {:reason => :not_yaml}
    TOML style fences, advertised as YAML
      is expected to have attributes {:front_matter => (include {:title => "My title"})}
    YAML, advertised as something else
      is expected to have attributes {:reason => :not_yaml}
    there is text content in the YAML block, in comments
      is expected to have attributes {:front_matter => (include {:foo => 1})}
    there is text content in the YAML block
      is expected to have attributes {:reason => :not_mapping}

Gitlab::Checks::DiffCheck
  #validate!
    when commits is empty
      does not call find_changed_paths
    when commits is not empty
      when deletion is true
        does not call find_changed_paths
      with LFS not enabled
        does not invoke :lfs_file_locks_validation
      with LFS enabled
        when change is sent by a different user
          raises an error if the user is not allowed to update the file
        when change is sent by the author of the lock
          doesn't raise any error

LimitedCapacity::Worker
  required methods
    is expected to raise NotImplementedError
    is expected to raise NotImplementedError
    is expected to raise NotImplementedError
  Sidekiq options
    does not retry failed jobs
    does not deduplicate jobs
  .perform_with_capacity
    enqueues jobs
  #perform
    with capacity
      calls perform_work
      re-enqueues itself
      reports prometheus metrics
      updates the running set
    with capacity and without work
      does not re-enqueue itself
    without capacity
      does not call perform_work
      does not re-enqueue itself
    when perform_work fails
      does not re-enqueue itself
      removes itself from the running set
      reports prometheus metrics
  #remove_failed_jobs
    removes failed jobs
  #report_prometheus_metrics
    reports number of running jobs

ProtectedBranchesFinder
  #execute
    returns all protected branches of project by default
    when search param is present
      filters by search param
    when there are more protected branches than the limit
      returns limited protected branches of project

Packages::Debian::GroupDistributionKey
  behaves like Debian Distribution Key
    relationships
      is expected to belong to distribution class_name => Packages::Debian::GroupDistribution required: false inverse_of => key
    validations
      #distribution
        is expected to validate that :distribution cannot be empty/falsy
      #private_key
        is expected to validate that :private_key cannot be empty/falsy
        is expected to allow :private_key to be ‹"-----BEGIN PGP PRIVATE KEY BLOCK-----\n..."›
        is expected not to allow :private_key to be ‹"A"›, producing a custom validation error on failure
      #passphrase
        is expected to validate that :passphrase cannot be empty/falsy
        is expected to allow :passphrase to be ‹"P@$$w0rd"›
        is expected to allow :passphrase to be ‹"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"›
        is expected not to allow :passphrase to be ‹"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"›
      #public_key
        is expected to validate that :public_key cannot be empty/falsy
        is expected to allow :public_key to be ‹"-----BEGIN PGP PUBLIC KEY BLOCK-----\n..."›
        is expected not to allow :public_key to be ‹"A"›, producing a custom validation error on failure
      #fingerprint
        is expected to validate that :passphrase cannot be empty/falsy
        is expected to allow :passphrase to be ‹"abc"›
        is expected to allow :passphrase to be ‹"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"›
        is expected not to allow :passphrase to be ‹"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"›

Gitlab::Ci::Config::External::File::Project
  #matching?
    when a file and project is specified
      returns true
    with only file is specified
      returns false
    with only project is specified
      returns false
    with a missing local key
      returns false
  #valid?
    when a valid path is used
      returns true
      when user does not have permission to access file
        returns false
    when a valid path with custom ref is used
      returns true
    when an empty file is used
      returns false
    when non-existing ref is used
      returns false
    when non-existing file is requested
      returns false
    when file is not a yaml file
      returns false
  #expand_context
    inherits user, and target project and sha

Gitlab::Database::PartitioningMigrationHelpers::IndexHelpers
  #add_concurrent_partitioned_index
    when the index does not exist on the parent table
      creates the index on each partition, and the parent table
    when the index exists on the parent table
      does not attempt to create any indexes
    when additional index options are given
      forwards them to the index helper methods
    when a name argument for the index is not given
      raises an error
    when the given table is not a partitioned table
      raises an error
    when run inside a transaction block
      raises an error
  #remove_concurrent_partitioned_index_by_name
    when the index exists
      drops the index on the parent table, cascading to all partitions
    when the index does not exist
      does not attempt to drop the index
    when the given table is not a partitioned table
      raises an error
    when run inside a transaction block
      raises an error

Ci::FreezePeriod
  is expected to belong to project required: false
  is expected to respond to #freeze_start
  is expected to respond to #freeze_end
  is expected to respond to #cron_timezone
  cron validations
    allows valid cron patterns
    does not allow invalid cron patterns on freeze_start
    does not allow invalid cron patterns on freeze_end
    does not allow an invalid timezone
    when cron contains trailing whitespaces
      strips the attribute

Gitlab::Suggestions::SuggestionSet
  #project
    returns the project associated with the suggestions
  #branch
    returns the branch associated with the suggestions
  #valid?
    returns true if no errors are found
    returns false if an error is found
  #error_message
    returns an error message if an error is found
    returns nil if no errors are found
  #actions
    returns an array of hashes with proper key/value pairs
  #file_paths
    returns an array of unique file paths associated with the suggestions

Banzai::ReferenceParser::MentionedUserParser
  #gather_references
    when the link has a data-group attribute
      using an existing group ID
        returns empty list of users
    when the link has a data-project attribute
      using an existing project ID
        returns empty list of users
    when the link has a data-user attribute
      returns an Array of users

Gitlab::Config::Entry::Undefined
  #leaf?
    is leaf node
  #valid?
    is always valid
  #errors
    is does not contain errors
  #value
    returns nil
  #relevant?
    is not relevant
  #specified?
    is not defined
  #type
    returns nil

gitlab:external_diffs rake tasks
  force_object_storage task
    forces externally stored merge request diffs to object storage
    limits batches according to BATCH_SIZE, START_ID, and END_ID

Gitlab::Analytics::CycleAnalytics::StageEvents::IssueStageEnd
  behaves like value stream analytics event
    is expected to be a kind of String
    is expected to be a kind of Symbol
    is expected to include ApplicationRecord(abstract)
    is expected to respond to #timestamp_projection
    is expected to respond to #html_description
    is expected to be a kind of Array
    #apply_query_customization
      expects an ActiveRecord::Relation object as argument and returns a modified version of it
    #hash_code
      returns a hash that uniquely identifies an event
      does not differ when the same object is built with the same params
  behaves like LEFT JOIN-able value stream analytics event
    can use the event as LEFT JOIN
    when looking at the record with data
      contains the timestamp expression
    when looking at the record without data
      returns nil for the timestamp expression

PrometheusMetricsFinder
  #execute
    with params
      with appropriate indexes
        with project
          is expected to eq [#<PrometheusMetric id: 1, project_id: 1207, title: [FILTERED], query: "avg(metric)", y_label: "y_lab...65 +0000", common: false, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">]
        with group
          is expected to contain exactly #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml"> and #<PrometheusMetric id: 1, project_id: 1207, title: [FILTERED], query: "avg(metric)", y_label: "y_labe...865 +0000", common: false, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
        with title
          is expected to contain exactly #<PrometheusMetric id: 1, project_id: 1207, title: [FILTERED], query: "avg(metric)", y_label: "y_labe...865 +0000", common: false, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml"> and #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
        with y_label
          is expected to contain exactly #<PrometheusMetric id: 1, project_id: 1207, title: [FILTERED], query: "avg(metric)", y_label: "y_labe...865 +0000", common: false, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml"> and #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
        with common
          is expected to contain exactly #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml"> and #<PrometheusMetric id: 3, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "Unique ...0", common: true, identifier: "identifier", dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
        with ordered
          is expected to eq [#<PrometheusMetric id: 3, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "Unique...534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">]
        with indentifier
          raises an error
          with common
            is expected to contain exactly #<PrometheusMetric id: 3, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "Unique ...0", common: true, identifier: "identifier", dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
          with id
            raises an error
        with id
          is expected to contain exactly #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
        with multiple params
          is expected to contain exactly #<PrometheusMetric id: 2, project_id: nil, title: [FILTERED], query: "avg(metric)", y_label: "y_label...2534 +0000", common: true, identifier: nil, dashboard_path: ".gitlab/dashboards/dashboard_path.yml">
      without an appropriate index
        raises an error
    without params
      raises an error

Gitlab::StaticSiteEditor::Config::GeneratedConfig
  #data
    returns data for the frontend component
    when namespace is a subgroup
      returns data for the frontend component
    when file has .md.erb extension
      is expected to include {:branch => "main", :is_supported_content => true}
    when file path is nested
      is expected to include {:base_url => "/namespace/project/-/sse/master%2Flib%2FREADME.md"}
    when branch is not master or main
      is expected to include {:is_supported_content => false}
    when file does not have a markdown extension
      is expected to include {:is_supported_content => false}
    when file does not have an extension
      is expected to include {:is_supported_content => false}
    when file does not exist
      is expected to include {:is_supported_content => false}
    when repository is empty
      is expected to include {:is_supported_content => false}
    when return_url is not a valid URL
      is expected to include {:return_url => nil}
    when return_url has a javascript scheme
      is expected to include {:return_url => nil}
    when return_url is missing
      is expected to include {:return_url => nil}
    when a commit for the ref cannot be found
      is expected to include {:commit_id => nil}

PersonalAccessTokens::ExpiringWorker
  #perform
    when a token needs to be notified
      uses notification service to send the email
      marks the notification as delivered
    when no tokens need to be notified
      doesn't use notification service to send the email
      doesn't change the notification delivered of the token
    when a token is an impersonation token
      doesn't use notification service to send the email
      doesn't change the notification delivered of the token

Gitlab::Bullet::Exclusions
  #execute
    with preferred method of path and method name
      behaves like loads exclusion results
        is expected to match [["_path_", "_method_"]]
    with file pattern
      behaves like loads exclusion results
        is expected to match [["_file_pattern_"]]
    with file name and line range
      behaves like loads exclusion results
        is expected to match [["file_name.rb", 5..10]]
    without exclusions
      behaves like loads exclusion results
        is expected to match [[]]
    without exclusions key in config
      behaves like loads exclusion results
        is expected to match []
    when config file does not exist
      provides an empty array for exclusions
  #validate_paths!
    when validating scenarios
      when using paths with method name
        when source file for exclusion exists
          is expected not to raise Exception
        when source file for exclusion does not exist
          is expected to raise RuntimeError
      when using path only
        when source file for exclusion exists
          is expected not to raise Exception
        when source file for exclusion does not exist
          is expected to raise RuntimeError
      when path_with_method is false for a file pattern
        is expected not to raise Exception

Gitlab::JwtAuthenticatable
  .secret
    returns 32 bytes
    accepts a trailing newline
    raises an exception if the secret file cannot be read
    raises an exception if the secret file contains the wrong number of bytes
  .write_secret
    uses mode 0600
    writes base64 data
  .decode_jwt_for_issuer
    accepts a correct header
    raises an error when the JWT is not signed
    raises an error when the header is signed with the wrong secret
    raises an error when the issuer is incorrect

Mutations::Todos::MarkAllDone
  is expected to require graphql authorizations :update_user
  #resolve
    marks all pending todos as done
    behaves as expected if there are no todos for the requesting user
    when user is not logged in
      fails with the expected error

Ci::JobTokenScope::RemoveProjectService
  #execute
    behaves like editable job token scope
      when job token scope is disabled for the given project
        behaves like returns error
          returns an error response
      when user does not have permissions to edit the job token scope
        behaves like returns error
          returns an error response
      when user has permissions to edit the job token scope
        when target project is not provided
          behaves like returns error
            returns an error response
        when target project is provided
          when user does not have permissions to read the target project
            behaves like returns error
              returns an error response
      when user has permissions on source and target project
        removes the project from the scope
      when target project is same as the source project
        behaves like returns error
          returns an error response

JsonSchemaValidator
  #validates_each
    when filename is set
      when data is valid
        returns no errors
      when data is invalid
        returns json schema is invalid
    when filename is not set
      raises an ArgumentError
    when filename is invalid
      raises a FilenameError
    hash_conversion option
      when hash_conversion is enabled
        returns no errors

projects/diffs/_viewer.html.haml
  when there is a render error
    renders the error
  when the viewer is collapsed
    renders the collapsed view
  when there is no render error
    prepares the viewer
    renders the viewer

ErrorTracking::BaseService
  #compose_response
    returns bad_request error when response has an error key
    returns server error when response has missing key error_type
    returns no content when response is nil
    when result has no errors key
      raises NotImplementedError
      when parse_response is implemented
        returns successful response
        returns successful response with changes from passed block

Gitlab::Git::KeepAround
  does not fail if we attempt to reference bad commit
  stores a reference to the specified commit sha so it isn't garbage collected
  attempting to call keep around on truncated ref does not fail
  for multiple SHAs
    skips non-existent SHAs
    skips already-kept-around SHAs

Ci::GroupVariablePresenter
  inherits from Gitlab::View::Presenter::Delegated
  #initialize
    takes a variable and optional params
    exposes variable
    forwards missing methods to variable
  #placeholder
    is expected to eq "GROUP_VARIABLE"
  #form_path
    is expected to eq "/groups/group708/-/settings/ci_cd"
  #edit_path
    is expected to eq "/groups/group709/-/variables"
  #delete_path
    is expected to eq "/groups/group710/-/variables"

API::Helpers::RelatedResourcesHelpers
  #expose_path
    empty relative URL root
      returns the existing path
    slash relative URL root
      returns the existing path
    with relative URL root
      returns the existing path
  #expose_url
    respects the protocol if it is HTTP
    respects the protocol if it is HTTPS
    accepts the host if it contains an underscore
    accepts port to be nil
    includes port if provided
    includes the relative_url before the path if it is set
    includes the path after the host

BulkImports::Groups::Loaders::GroupLoader
  #load
    when path is missing
      raises an error
    when destination namespace is not a group
      raises an error
    when group exists
      raises an error
    when there are other group errors
      raises an error with those errors
    when user can create group
      when there is no parent group
        calls Group Create Service to create a new group
      when there is parent group
        calls Group Create Service to create a new group
    when user cannot create group
      when there is no parent group
        does not create new group
      when there is parent group
        does not create new group

Ci::PipelineArtifacts::CoverageReportService
  #execute
    when pipeline has coverage reports
      when pipeline is finished
        creates a pipeline artifact
        persists the default file name
        sets expire_at to 1 week
      when pipeline artifact has already been created
WARNING: Using `expect { }.not_to raise_error(SpecificErrorClass)` risks false positives, since literally any other error would cause the expectation to pass, including those raised by Ruby (e.g. `NoMethodError`, `NameError` and `ArgumentError`), meaning the code you are intending to test may not even get reached. Instead consider using `expect { }.not_to raise_error` or `expect { }.to raise_error(DifferentSpecificErrorClass)`. This message can be suppressed by setting: `RSpec::Expectations.configuration.on_potential_false_positives = :nothing`. Called from /builds/gitlab-org/gitlab/spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb:41:in `block (5 levels) in <top (required)>'.
        do not raise an error and do not persist the same artifact twice
    when pipeline is running and coverage report does not exist
      does not persist data

Mutations::Terraform::State::Lock
  is expected to eq "TerraformStateLock"
  is expected to require graphql authorizations :admin_terraform_state
  #resolve
    user does not have permission
      raises an error
    user has permission
      locks the state
      state is already locked
        does not modify the existing lock
    with invalid params
      raises an error

Snippets::CountService
  #new
    raises an error if no author or project
    uses the SnippetsFinder to scope snippets by user
    allows scoping to project
  #execute
DEPRECATION WARNING: `.reorder(nil)` with `.first` / `.first!` no longer takes non-deterministic result in Rails 6.2. To continue taking non-deterministic result, use `.take` / `.take!` instead. (called from snippet_counts at /builds/gitlab-org/gitlab/app/services/snippets/count_service.rb:73)
    returns a hash of counts
DEPRECATION WARNING: `.reorder(nil)` with `.first` / `.first!` no longer takes non-deterministic result in Rails 6.2. To continue taking non-deterministic result, use `.take` / `.take!` instead. (called from snippet_counts at /builds/gitlab-org/gitlab/app/services/snippets/count_service.rb:73)
    only counts snippets the user has access to
    returns an empty hash if select returns nil

Banzai::Filter::InlineClusterMetricsFilter
  behaves like a metrics embed filter
    when the document has an external link
      leaves regular non-metrics links unchanged
    when the document contains an embeddable link
      leaves the original link unchanged
      appends a metrics charts placeholder
      in a paragraph
        appends a metrics charts placeholder after the enclosing paragraph

Ci::CompareTestReportsService
  #execute
    when head pipeline has test reports
      returns status and data
    when base and head pipelines have test reports
      returns status and data
    when head pipeline has corrupted test reports
      returns a parsed TestReports success status and failure on the individual suite
    test failure history
      loads recent failures on limited test cases to avoid building up a huge DB query

Gitlab::DependencyLinker::PackageJsonLinker
  .support?
    supports package.json
    does not support other files
  #link
    does not link the module name
    links the homepage
    links the repository URL
    links the license
    links dependencies
    links dependencies to URL detected on value
    does not link to NPM when invalid git URL
    links GitHub repos
    links Git repos
    does not link scripts with the same key as a package

InstanceConfigurationHelper
  #instance_configuration_cell_html
    boolean are valid values to display
    if not block is passed
      returns the parameter if present
      returns "-" if the parameter is blank
    if a block is passed
      returns the result of the block
      returns "-" if the parameter is blank
  #instance_configuration_human_size_cell
    returns "-" if the parameter is blank
    accepts the value in bytes
    returns the value in human size readable format

Mutations::Security::CiConfiguration::ConfigureSecretDetection
  is expected to require graphql authorizations :push_code
  #resolve
    raises an error if the resource is not accessible to the user
    when user does not have enough permissions
      raises an error
    when user is a maintainer of a different project
      raises an error
    when the user does not have permission to create a new branch
      returns an array of errors
    when the user can create a merge request
      when service successfully generates a path to create a new merge request
        returns a success path
      when service can not generate any path to create a new merge request
        returns an array of errors

SystemNotes::BaseService
  #noteable
    is expected to eq #<Double (anonymous)>
    returns nil if no arguments are given
  #project
    is expected to eq #<Double (anonymous)>
    returns nil if no arguments are given
  #author
    is expected to eq #<Double (anonymous)>
    returns nil if no arguments are given

5-Minute-Production-App.gitlab-ci.yml
  the created pipeline
    creates only build job
    when AWS variables are set
      creates all jobs
      pipeline branch is protected
        does not create a destroy job

Gitlab::Kas::Client
  #initialize
    kas is not enabled
      raises a configuration error
    internal url is not set
      raises a configuration error
  gRPC calls
    #get_connected_agents
      is expected to eq [#<Double (anonymous)>]
    #list_agent_config_files
      is expected to eq [#<Double (anonymous)>]
    with grpcs
      uses a ChannelCredentials object

MemberSerializer
  group member
    handles last group owner assignment
    behaves like members.json
      is expected to match schema "members"
  project member
    does not invoke group owner assignment
    behaves like members.json
      is expected to match schema "members"

Banzai::Filter::InlineDiffFilter
  adds inline diff span tags for deletions when using square brackets
  adds inline diff span tags for deletions when using curley braces
  does not add inline diff span tags when a closing tag is not provided
  adds inline span tags for additions when using square brackets
  adds inline span tags for additions  when using curley braces
  does not add inline diff span tags when a closing addition tag is not provided
  does not add inline diff span tags when the tags do not match
  prevents user-land html being injected
  preserves content inside pre tags
  preserves content inside code tags
  preserves content inside tt tags

Types::NamespaceType
  is expected to eq "Namespace"
  has the expected fields
  is expected to require graphql authorizations :read_namespace

Gitlab::ExclusiveLeaseHelpers
  #in_lock
    when unique key is not set
      raises an error
    when the lease is not obtained yet
      calls the given block
      calls the given block continuously
      cancels the exclusive lease after the block
    when the lease is obtained already
      retries to obtain a lease and raises an error
      when ttl is specified
        receives the specified argument
      when retry count is specified
        retries for the specified times
        when lease is granted after retry
          yields block with true
      when we specify no retries
        never sleeps
      when sleep second is specified
        receives the specified argument
      when sleep second is specified as a lambda
        receives the specified argument

AuditEventService
  #security_event
    creates an event and logs to a file
    formats from and to fields
    authentication event
      creates an authentication event
      tracks exceptions when the event cannot be created
      with IP address
        from_context: "192.168.0.2", from_author_sign_in: "192.168.0.3", output: "192.168.0.2"
          is expected to receive new(hash_including(:ip_address=>"192.168.0.2")) 1 time
        from_context: nil, from_author_sign_in: "192.168.0.3", output: "192.168.0.3"
          is expected to receive new(hash_including(:ip_address=>"192.168.0.3")) 1 time
  #log_security_event_to_file
    logs security event to file

GpgKeySubkey
  associations
    is expected to belong to gpg_key required: false
  validations
    is expected to validate that :gpg_key_id cannot be empty/falsy
    is expected to validate that :fingerprint cannot be empty/falsy
    is expected to validate that :keyid cannot be empty/falsy

Gitlab::Graphql::BatchKey
  is equal to keys of the same object, regardless of lookahead or object name
  delegates attribute lookup methods to the inner object
  allows the object to be named more meaningfully
  works as a hash key
  #requires?
    returns false if the lookahead was not provided
    lookahead was provided
      returns false if the path is empty
      it selects the field
        returns true
      it does not select the field
        returns false

Resolvers::DesignManagement::DesignAtVersionResolver
  #resolve
    returns the specified design
    when the user cannot see designs
      raises ResourceNotAvailable
    the ID belongs to a design on another issue
      raises ResourceNotAvailable
      the current object does not constrain the issue
        returns the object

Gitlab::LoopHelpers
  #loop_until
    when limit is not given
      raises an error
    when timeout is specified
      returns false after it's expired
      executes the block at least once
    when iteration limit is specified
      returns false after it's expired
      executes the block once

RuboCop::Cop::RSpec::EnvAssignment
  with a key using single quotes
    behaves like an offensive and correction ENV#[]= call
      registers an offense for `ENV['FOO'] = 'bar'` and corrects
  with a key using double quotes
    behaves like an offensive and correction ENV#[]= call
      registers an offense for `ENV["FOO"] = 'bar'` and corrects

Gitlab::SearchContext::ControllerConcern
  exposing @project
    behaves like has the proper context
      aggregate_failures
    when the project is owned by a group
      behaves like has the proper context
        aggregate_failures
  exposing @group
    behaves like has the proper context
      aggregate_failures
  exposing @snippet, @snippets
    behaves like has the proper context
      aggregate_failures
  exposing @ref
    behaves like has the proper context
      aggregate_failures

RepositoryRemoveRemoteWorker
  #perform
    returns nil when project does not exist
    when project exists
      does nothing when cannot obtain lease
      does nothing when obtain a lease

Ci::CreatePipelineService
  creation errors and warnings
    when created successfully
      when warnings are raised
        contains only warnings
      when no warnings are raised
        contains no warnings
    when failed to create the pipeline
      when warnings are raised
        contains both errors and warnings
      when no warnings are raised
        contains only errors

Gitlab::HookData::GroupBuilder
  #build
    data
      on create
        is expected to eq "group_create"
        behaves like includes the required attributes
          includes the required attributes
        behaves like does not include old path attributes
          does not include old path attributes
      on destroy
        is expected to eq "group_destroy"
        behaves like includes the required attributes
          includes the required attributes
        behaves like does not include old path attributes
          does not include old path attributes
      on rename
        is expected to eq "group_rename"
        includes old path details
        behaves like includes the required attributes
          includes the required attributes

Terraform::StatesFinder
  #execute
    is expected to contain exactly #<Terraform::State id: 15, project_id: 1267, created_at: "2021-12-14 01:55:07.582166820 +0000", updat...y_user_id: nil, uuid: "7a57343474b0a10fe0a304b32cdba7ee", name: "state-4", versioning_enabled: true> and #<Terraform::State id: 16, project_id: 1267, created_at: "2021-12-14 01:55:07.588924879 +0000", updat...y_user_id: nil, uuid: "abf3eb1bb37bcc50da0d102ca78e84c7", name: "state-5", versioning_enabled: true>
    user does not have permission
      is expected to be empty
    filtering by name
      name does not match
        is expected to be empty
      name does match
        is expected to contain exactly #<Terraform::State id: 15, project_id: 1267, created_at: "2021-12-14 01:55:07.582166820 +0000", updat...y_user_id: nil, uuid: "7a57343474b0a10fe0a304b32cdba7ee", name: "state-4", versioning_enabled: true>

BulkImports::Common::Pipelines::EntityFinisher
  updates the entity status to finished
  when entity is in a final finished or failed state
    does nothing
    does nothing
  when all entity trackers failed
    marks entity as failed

MigrateExternalDiffsWorker
  #perform
    migrates the listed diff
    does nothing if the diff is missing

Types::BaseEdge
  supports field authorization on edge fields

UpdateHighestRoleWorker
  #perform
    when user is not found
      does not update or deletes any highest role
    when user is found
      when user is active and not internal
        when user highest role exists
          updates the highest role for the user
        when user highest role does not exist
          creates the highest role for the user
      when user is either inactive or internal
        additional_attributes: {:state=>"blocked"}
          deletes highest role
        additional_attributes: {:user_type=>:alert_bot}
          deletes highest role
        when user highest role does not exist
          does not delete a highest role

AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker
  is labeled as low urgency
  behaves like refreshes user's project authorizations
    #perform
      refreshes user's authorized projects
      when the user is not found
        does nothing
      behaves like an idempotent worker
        is labeled as idempotent
        performs multiple times sequentially without raising an exception
        does not change authorizations when run twice

Gitlab::Git::Changes
  #includes_branches?
    has changes for branches
      is expected to be truthy
    has no changes for branches
      is expected to be falsey
  #includes_tags?
    has changes for tags
      is expected to be truthy
    has no changes for tags
      is expected to be falsey
  #add_branch_change
    adds the branch change to the collection
    does not add the change as a tag change
  #add_tag_change
    adds the tag change to the collection
    does not add the change as a branch change

Mutations::Terraform::State::Unlock
  is expected to eq "TerraformStateUnlock"
  is expected to require graphql authorizations :admin_terraform_state
  #resolve
    user does not have permission
      raises an error
    user has permission
      unlocks the state
      state is already unlocked
        does not modify the state
    with invalid params
      raises an error

Gitlab::DataBuilder::WikiPage
  .build
    is expected to be a kind of Hash
    is expected to eq "wiki_page"
    is expected to eq {:avatar_url=>"https://www.gravatar.com/avatar/bed6ab8e57ec6cdc5020639053c52d30?s=80&d=identicon", :email=>"[REDACTED]", :id=>2102, :name=>"Sidney Jones2315", :username=>"user1074"}
    is expected to eq {:avatar_url=>nil, :ci_config_path=>nil, :default_branch=>"master", :description=>nil, :git_http_url=...1104/project1350.git", :visibility_level=>0, :web_url=>"http://localhost/namespace1104/project1350"}
    is expected to eq {:default_branch=>"main", :git_http_url=>"http://localhost/namespace1104/project1350.wiki.git", :git_...amespace1104/project1350.wiki", :web_url=>"http://localhost/namespace1104/project1350/-/wikis/home"}
    is expected to include {:slug => "Page-1", :title => "Page 1", :content => "Content for wiki page", :format => :markdown, :message => nil, "content" => "Content for wiki page"}
    is expected to include {:url => "http://localhost/namespace1104/project1350/-/wikis/Page-1"}
    is expected to include {:action => "create"}
    is expected to include {:diff_url => "http://localhost/namespace1104/project1350/-/wikis/Page-1/diff?version_id=2a71f0217264767374e550f9bc006911ad405d7a"}

BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline
  #run
    creates entities for the subgroups
  #load
    creates entities for the given data
  pipeline parts
    is expected to includes the BulkImports::Pipeline module
    is expected to includes the BulkImports::Pipeline::Runner module
    has extractors
    has transformers

projects/environments/terminal
  when environment has external URL
    shows external URL button
  when environment does not have external URL
    shows external URL button

Gitlab::CryptoHelper
  .sha256
    generates SHA256 digest Base46 encoded
  .aes256_gcm_encrypt
    is Base64 encoded string without new line character
    encrypts using static iv
    with provided iv
      encrypts using provided iv
  .aes256_gcm_decrypt
    when token was encrypted using static nonce
      correctly decrypts encrypted string
      decrypts a value when it ends with a new line character
    when token was encrypted using random nonce
      correctly decrypts encrypted string

Gitlab::Ci::Config::Entry::Release::Assets::Link
  validation
    when entry config value is correct
      #value
        returns link configuration
      #valid?
        is valid
    when entry value is not correct
      #errors
        when name is not a string
          reports error
        when name is not present
          reports error
        when url is not addressable
          reports error
        when url is not present
          reports error
        when there is an unknown key present
          reports error

Gitlab::Database::PostgresqlAdapter::EmptyQueryPing
  #active?
    uses an empty query to check liveness
    returns true if no error was signaled
    returns false when an error occurs

ServiceHookPresenter
  #logs_details_path
    is expected to eq "/namespace1107/project1353/-/services/drone_ci/hook_logs/1"
  #logs_retry_path
    is expected to eq "/namespace1108/project1354/-/services/drone_ci/hook_logs/2/retry"

Types::Ci::PipelineType
  is expected to eq "Pipeline"
  is expected to expose permissions using Types::PermissionTypes::Ci::Pipeline
  contains attributes related to a pipeline

Issues::AfterCreateService
  #execute
    creates a pending todo for new assignee
    deletes milestone issues count cache
    with a regular issue
      behaves like does not track incident management event
        does not track the event
    with an incident issue
      behaves like an incident management tracked event
        .track_event
          tracks the event using redis

Gitlab::FormBuilders::GitlabUiFormBuilder
  #gitlab_ui_checkbox_component
    without optional arguments
      renders correct html
    with optional arguments
      renders help text
      passes arguments to `check_box` method
      passes arguments to `label` method
  #gitlab_ui_radio_component
    without optional arguments
      renders correct html
    with optional arguments
      renders help text
      passes arguments to `radio_button` method
      passes arguments to `label` method

Gitlab::GitlabImport::Client
  all OAuth2 client options are symbols
  uses membership and simple flags
  #projects
    behaves like pagination params
      allows page_limit param
      allows per_page param
      allows starting_page param
  #issues
    behaves like pagination params
      allows page_limit param
      allows per_page param
      allows starting_page param
  #issue_comments
    behaves like pagination params
      allows page_limit param
      allows per_page param
      allows starting_page param

WikiDirectory
  validations
    is expected to validate that :slug cannot be empty/falsy
  .group_pages
    returns a nested array of entries
  #initialize
    when there are entries
      sets the slug attribute
      sets the entries attribute
    when there are no entries
      sets the slug attribute
      sets the entries attribute to an empty array
  #title
    returns the basename of the directory, with hyphens replaced by spaces
  #to_partial_path
    returns the relative path to the partial to be used

GroupDestroyWorker
  #perform
    deletes the project

Ci::PipelineBridgeStatusService
  #execute
    when pipeline has upstream bridge
      calls inherit_status_from_downstream on upstream bridge
      when bridge job status raises state machine errors
        tracks the exception

UserSerializer
  serializer with merge request context
    returns a user with can_merge option

PipelineHooksWorker
  #perform
    when pipeline exists
      executes hooks for the pipeline
    when pipeline does not exist
      does not raise exception
  behaves like worker with data consistency
    .get_data_consistency_feature_flag_enabled?
      returns true
    .get_data_consistency
      returns correct data consistency

Packages::Nuget::PackageMetadataPresenter
  #json_url
    is expected to end with "/api/v4/projects/1289/packages/nuget/metadata/NugetPackage10/1.0.10.json"
  #archive_url
    is expected to end with "/api/v4/projects/1289/packages/nuget/download/NugetPackage10/1.0.10/NugetPackage10.1.0.10.nupkg"
  #catalog_entry
    returns an entry structure

UserStatusCleanup::BatchWorker
  is labeled as idempotent
  performs multiple times sequentially without raising an exception
  #perform
    cleans up the records
    when no records are scheduled for cleanup
      does nothing

Gitlab::RepositorySizeErrorMessage
  error messages
    #commit_error
      returns the correct message
    #merge_error
      returns the correct message
    #push_error
      with exceeded_limit value
        returns the correct message
      without exceeded_limit value
        returns the correct message
    #new_changes_error
      when additional repo storage is available
        returns the correct message
      when no additional repo storage is available
        returns the correct message

ResourceEvents::MergeIntoNotesService
  #execute
    merges label events into notes in order of created_at
    squashes events with same time and author into single note
    fetches only notes created after last_fetched_at
    preloads the note author's status

clusters/clusters/gcp/_form
  with all feature flags enabled
    has a cloud run checkbox

RuboCop::Cop::PreferClassMethodsOverModule
  flags violation when using module ClassMethods and corrects
  doesn't flag violation when using class_methods
  doesn't flag violation when module is not extending ActiveSupport::Concern
  doesn't flag violation when ClassMethods is used inside a class
  doesn't flag violation when not using either class_methods or ClassMethods

Resolvers::ProjectPipelineStatisticsResolver
  is expected to have nullable GraphQL type PipelineAnalytics
  #resolve
    returns the pipelines statistics for a given project
    when the user does not have access to the CI/CD analytics data
      returns nil

JiraConnect::AppDataSerializer
  #as_json
    uses the subscription entity
    includes a group path with already subscribed namespaces as skip_groups
    is expected to include {:subscriptions_path => "/-/jira_connect/subscriptions"}
    is expected to include {:login_path => "/-/jira_connect/users"}
    when signed in
      is expected to include {:login_path => nil}

Gitlab::Middleware::BasicHealthCheck
  #call
    outside IP
      returns a 404
      forwards the call for other paths
    with X-Forwarded-For headers
      returns 200 response when endpoint is allowed
      returns 404 when whitelist is not configured
    whitelisted IP
      returns 200 response when endpoint is hit
      forwards the call for other paths

PagesDomainPresenter
  needs_validation?
    pages_verification_enabled: false, traits: :unverified, expected: false
      is expected to eq false
    pages_verification_enabled: false, traits: [], expected: false
      is expected to eq false
    pages_verification_enabled: true, traits: :unverified, expected: true
      is expected to eq true
    pages_verification_enabled: true, traits: [], expected: false
      is expected to eq false
  show_auto_ssl_failed_warning?
    is expected to eq false
    when we failed to obtain Let's Encrypt's certificate
      is expected to eq true
      when Let's Encrypt integration is disabled
        is expected to eq false
      when domain is unverified
        is expected to eq false

JiraConnect::SyncDeploymentsWorker
  behaves like worker with data consistency
    .get_data_consistency_feature_flag_enabled?
      returns true
    .get_data_consistency
      returns correct data consistency
  #perform
    when the object exists
      calls the Jira sync service
    when the object does not exist
      does not call the sync service

Tooling::Crystalball::CoverageLinesExecutionDetector
  #detect
    is expected to eq ["file.rb"]
    with no changes
      is expected to eq []
    with previously uncovered file
      is expected to eq ["file.rb"]
    with path outside of root
      is expected to eq []
    with path in excluded prefix
      is expected to eq []

RuboCop::Cop::Gitlab::DelegatePredicateMethods
  registers offense for single predicate method with allow_nil:true
  registers offense for multiple predicate methods with allow_nil:true
  registers no offense for non-predicate method with allow_nil:true
  registers no offense with predicate method with allow_nil:false
  registers no offense with predicate method without allow_nil

Approval
  presence validation
    is expected to validate that :merge_request_id cannot be empty/falsy
    is expected to validate that :user_id cannot be empty/falsy
  uniqueness validation
    is expected to validate that :user_id is case-sensitively unique within the scope of :merge_request_id

Users::DismissCalloutService
  #execute
    behaves like dismissing user callout
      creates a new user callout
      returns a user callout
      sets the dismissed_at attribute to current time
      updates an existing callout dismissed_at time
      does not update an invalid record with dismissed_at time

Import::ManifestProviderRepoEntity
  behaves like exposes required fields for import entity
    exposes required fields
      correctly exposes id
      correctly exposes full name
      correctly exposes sanitized name
      correctly exposes provider link

Gitlab::CodeNavigationPath
  when there is an artifact with code navigation data
    when a pipeline exist for a sha
      returns path to a file in the artifact
      when passed commit sha is nil
        returns path to a file in the artifact
    when a pipeline exist for the latest commits
      returns path to a file in the artifact

Gitlab::ImportExport::DesignRepoRestorer
  bundle a design Git repo
    restores the repo successfully

RuboCop::Cop::Gitlab::PolicyRuleBoolean
  registers offense for &&
  registers offense for ||
  registers offense for if
  registers offense for ternary operator
  registers no offense for &
  registers no offense for |

DiffViewer::Image
  .can_render?
    returns false if both old and new blob are absent
    returns true if the old blob is present
    returns true if the new blob is present
    returns true if both old and new blobs are present

DiffViewerEntity
  serializes diff file viewer

Gitlab::Graphql::Pagination::Connections
-- create_table(:_test_testing_pagination_nodes, {:force=>true})
   -> 0.0036s
  OffsetPaginatedRelation
    maps to Gitlab::Graphql::Pagination::OffsetActiveRecordRelationConnection
  ActiveRecord::Relation
    maps to Gitlab::Graphql::Pagination::Keyset::Connection
  ExternallyPaginatedArray
    maps to Gitlab::Graphql::Pagination::ExternallyPaginatedArrayConnection
  Array
    maps to Gitlab::Graphql::Pagination::ArrayConnection
-- drop_table(:_test_testing_pagination_nodes, {:force=>true})
   -> 0.0016s

Gitlab::SidekiqMiddleware::DuplicateJobs::Client
  with until_executing strategy
    behaves like client duplicate job
      #call
        adds a correct duplicate tag to the jobs
        without scheduled deduplication
          does not mark a job that's scheduled in the future as a duplicate
        with scheduled deduplication
          adds a correct duplicate tag to the jobs
  with until_executed strategy
    behaves like client duplicate job
      #call
        adds a correct duplicate tag to the jobs
        without scheduled deduplication
          does not mark a job that's scheduled in the future as a duplicate
        with scheduled deduplication
          adds a correct duplicate tag to the jobs

admin mode on tasks
  with a regular user
    matches the expected admin mode
  with an admin
    matches the expected admin mode

AlertManagement::AlertPresenter
  #issue_description
    with an empty payload
      is expected to eq "**Start time:** 14 December 2021, 1:56AM (UTC)  \n**Severity:** critical  \n**GitLab alert:** http://localhost/namespace1144/project1390/-/alert_management/2/details\n"
    with optional alert attributes
      is expected to eq "**Start time:** 14 December 2021, 1:56AM (UTC)  \n**Severity:** critical  \n**full_query:** `metric ...tem.  \n**GitLab alert:** http://localhost/namespace1144/project1390/-/alert_management/3/details\n"
    with incident markdown
      is expected to eq "**Start time:** 14 December 2021, 1:56AM (UTC)  \n**Severity:** critical  \n**GitLab alert:** http:/...localhost/namespace1144/project1390/-/alert_management/2/details\n\n\n---\n\n**`markdown example`**"
    with metrics_dashboard_url
      is expected to eq "**Start time:** 14 December 2021, 1:56AM (UTC)  \n**Severity:** critical  \n**GitLab alert:** http:/.../localhost/namespace1144/project1390/-/alert_management/2/details\n\n[](https://gitlab.com/metrics)"
  #start_time
    formats the start time of the alert
  #details_url
    returns the details URL
  #details
    renders the payload as inline hash

Experiments::RecordConversionEventWorker#perform
  when the experiment is active
    is labeled as idempotent
    performs multiple times sequentially without raising an exception
    records the event
  when the experiment is not active
    records the event

Gitlab::ImportExport::LegacyRelationTreeSaver
  #serialize
    when export_reduce_relation_batch_size feature flag is enabled
      uses FastHashSerializer
    when export_reduce_relation_batch_size feature flag is disabled
      uses FastHashSerializer

Gitlab::Utils::DelegatorOverride::Validator
  #add_allowlist
    adds a method name to the allowlist
  #add_target
    adds the target class
  #expand_on_ancestors
    adds the allowlist in the ancestors
  #validate_overrides!
    does not raise an error when the overrides are allowed
    raises an error when there is an override

Gitlab::Graphql::NegatableArguments
  #negated
    defines :not argument
    defines any arguments passed as block
    defines all arguments passed as block even if called multiple times
    allows to specify custom argument name

Gitlab::ImportExport::AfterExportStrategyBuilder
  .build!
    initializes strategy with attributes param
    when klass param is
      null it returns the default strategy
      not a valid class it raises StrategyNotFoundError exception
      not a descendant of AfterExportStrategy

Gitlab::GithubImport::BulkImporting
  #build_database_rows
    returns an Array containing the rows to insert
    does not import objects that have already been imported
  #bulk_insert
    bulk inserts rows into the database

Types::MergeRequestStateEnum
  is expected to eq "MergeRequestState"
  exposes all the existing merge request states
  behaves like issuable state
    exposes all the existing issuable states

Gitlab::PhabricatorImport::Conduit::UsersResponse
  #users
    builds the correct users representation

BaseContainerService
  #initialize
    accepts container and current_user
    treats current_user as optional

Gitlab::SidekiqMiddleware::ExtraDoneLogMetadata
  #call
    merges Application#logging_extras in to job
    does not raise when the worker does not respond to #done_log_extra_metadata

admin/application_settings/_repository_storage.html.haml
  additional storage config
    lists them all
  fewer storage configs
    lists only configured storages

ProtectedBranch::MergeAccessLevel
  is expected to validate that :access_level is either ‹40›, ‹30›, or ‹0›

AccessibilityReportsComparerEntity
  #as_json
    when base report has error and head has a different error
      contains correct compared accessibility report details
    when base report has error and head has the same error
      contains correct compared accessibility report details
    when base report has no error and head has errors
      contains correct compared accessibility report details

Types::DesignManagement::DesignVersionEventEnum
  is expected to eq "DesignVersionEvent"
  exposes the correct event states

Peek::Views::Memory
  with process_action.action_controller notification
    returns empty results when it has not yet fired
    returns memory instrumentation data when it has fired

OneTrustHelper
  #one_trust_enabled?
    with ecomm_instrumentation feature flag disabled
      is expected to be falsey
    with ecomm_instrumentation feature flag enabled
      when no id is set
        is expected to be falsey

Gitlab::HashedPath
  #to_s
    when path contains a single value
      returns the disk path
    when path contains multiple values
      returns the disk path

API::Entities::DeployKeysProject
  #as_json
    includes basic fields

API::Validations::Validators::ProjectPortable
  valid portable
    does not raise a validation error
  empty params
    raises a validation error
  not portable
    raises a validation error

Sidebars::Projects::Menus::RepositoryMenu
  #render?
    when project repository is empty
      returns false
    when project repository is not empty
      when user can download code
        returns true
      when user cannot download code
        returns false

RuboCop::Cop::RSpec::TimecopFreeze
  when calling Timecop.freeze
    registers an offense and corrects
  when calling a different method on Timecop
    does not register an offense

RuboCop::Cop::QA::SelectorUsage
  in a QA file
    has no error
  outside of QA
    data-qa-selector
      behaves like non-qa file usage
        reports an offense
    qa class
      behaves like non-qa file usage
        reports an offense

Gitlab::Ci::Build::Port
  when port is defined as an integer
    populates the object
  when port is defined as hash
    populates the object

RuboCop::QAHelpers
  #in_qa_file?
    returns true for a node in the qa/ directory
    returns false for a node outside the qa/ directory

groups/runners/sort_dropdown.html.haml
  render
    when a sort option is not selected
      renders a default sort option
    when a sort option is selected
      renders the selected sort option

Mailer retries
  sets retries for mailers to 3

Gitlab::Chat
  .available?
    returns true when the chatops feature is available
    returns false when the chatops feature is not available

Gitlab::Database::BackgroundMigration::BatchMetrics
  #time_operation
    tracks the duration of the operation using monotonic time

Constraints::FeatureConstrainer
  #matches
    calls Feature.enabled? with the correct arguments

Gitlab::SidekiqMiddleware::SizeLimiter::Server
  yields block
  calls the Compressor

Types::Ci::Config::JobType
  is expected to eq "CiConfigJob"
  exposes the expected fields

Packages::Rubygems::Metadatum
  relationships
    is expected to belong to package required: false
  validations
    is expected to validate that :package cannot be empty/falsy
    #rubygems_package_type
      will not allow a package with a different package_type

Gitlab::ActionCable::RequestStoreCallbacks
  .wrapper
    enables RequestStore in the inner block

Gitlab::Git::Patches::Patch
  #size
    is correct

Evidences::ReleaseSerializer
  represents an Evidence::ReleaseEntity entity

Types::Packages::PackageTypeEnum
  exposes all package types

FromUnion
  behaves like from set operator
    #from_union
      selects from the results of the UNION
      supports the use of a custom alias for the sub query
      supports keeping duplicate rows

Gitlab::SidekiqMiddleware::WorkerContext::Server
  #call
    applies a class context
    doesn't fail for unknown workers
    feature category
      takes the feature category from the worker
      when the worker is not owned
        takes the feature category from the surrounding context

errors/access_denied
  does not fail to render when there is no message provided

Gitlab::Database::AsyncIndexes
  .create_pending_indexes!
    takes 2 pending indexes and creates those

UploaderHelper
  #extension_match?
    returns false if file does not exist

Ci::CodequalityMrDiffEntity
  #as_json
    when quality report has degradations
      contains correct codequality mr diff report
Knapsack report was generated. Preview:
{
  "spec/models/merge_request_spec.rb": 227.87205425799948,
  "spec/policies/project_policy_spec.rb": 108.22286489399994,
  "spec/services/git/branch_push_service_spec.rb": 129.82362319499953,
  "spec/finders/group_members_finder_spec.rb": 104.82423891899998,
  "spec/uploaders/design_management/design_v432x230_uploader_spec.rb": 68.48216199200033,
  "spec/lib/gitlab/usage_data_metrics_spec.rb": 71.78426303300148,
  "spec/models/ci/runner_spec.rb": 31.60623311100062,
  "spec/policies/project_statistics_policy_spec.rb": 43.96543845999986,
  "spec/services/merge_requests/merge_service_spec.rb": 40.933501942001385,
  "spec/services/boards/lists/move_service_spec.rb": 36.18515005699919,
  "spec/policies/blob_policy_spec.rb": 25.47289008900043,
  "spec/models/integrations/bamboo_spec.rb": 17.090555155999027,
  "spec/lib/gitlab/ci/config/entry/job_spec.rb": 11.913097849001133,
  "spec/lib/banzai/color_parser_spec.rb": 9.144105172999843,
  "spec/lib/gitlab/gitaly_client/commit_service_spec.rb": 16.912589997000396,
  "spec/lib/gitlab/project_authorizations_spec.rb": 22.967806795000797,
  "spec/models/pages_domain_spec.rb": 13.48794416400051,
  "spec/helpers/namespaces_helper_spec.rb": 20.87066208500073,
  "spec/serializers/environment_serializer_spec.rb": 19.87195944099949,
  "spec/models/notification_recipient_spec.rb": 18.181568221998532,
  "spec/uploaders/workers/object_storage/migrate_uploads_worker_spec.rb": 17.434572112999376,
  "spec/services/members/update_service_spec.rb": 18.876238836000994,
  "spec/models/merge_request_diff_file_spec.rb": 12.380091287999676,
  "spec/workers/packages/debian/process_changes_worker_spec.rb": 18.75968407399887,
  "spec/lib/error_tracking/sentry_client/issue_spec.rb": 11.1113796919999,
  "spec/lib/gitlab/usage/metric_definition_spec.rb": 10.523299641001358,
  "spec/models/concerns/chronic_duration_attribute_spec.rb": 12.942810880002071,
  "spec/lib/gitlab/hashed_storage/migrator_spec.rb": 15.621425033001287,
  "spec/workers/process_commit_worker_spec.rb": 14.432824391000395,
  "spec/serializers/issue_entity_spec.rb": 11.530809424000836,
  "spec/lib/gitlab/json_spec.rb": 2.3346384940014104,
  "spec/models/concerns/routable_spec.rb": 5.673020393000115,
  "spec/lib/gitlab/experimentation/controller_concern_spec.rb": 4.094696117001149,
  "spec/services/jira/requests/projects/list_service_spec.rb": 10.669822690999354,
  "spec/models/ci/daily_build_group_report_result_spec.rb": 10.962043741999878,
  "spec/services/projects/protect_default_branch_service_spec.rb": 8.32332150700131,
  "spec/lib/gitlab/import_export/group/relation_tree_restorer_spec.rb": 9.351339468999868,
  "spec/services/snippets/destroy_service_spec.rb": 7.2866619559990795,
  "spec/lib/gitlab/kubernetes/helm/v2/init_command_spec.rb": 9.898116033000406,
  "spec/lib/gitlab/database/migration_helpers/v2_spec.rb": 2.847867671000131,
  "spec/lib/gitlab/ci/trace/checksum_spec.rb": 8.305170547999296,
  "spec/policies/ci/pipeline_policy_spec.rb": 8.010174588000154,
  "spec/lib/container_registry/blob_spec.rb": 7.484925802998987,
  "spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb": 9.788322369000525,
  "spec/finders/fork_projects_finder_spec.rb": 10.33676362299957,
  "spec/lib/gitlab/pagination/keyset/paginator_spec.rb": 3.668697255998268,
  "spec/services/issues/set_crm_contacts_service_spec.rb": 6.185727500000212,
  "spec/services/ci/archive_trace_service_spec.rb": 7.800591842000358,
  "spec/services/snippets/update_statistics_service_spec.rb": 6.366079088000333,
  "spec/finders/projects/groups_finder_spec.rb": 4.791423091999604,
  "spec/services/ci/job_artifacts/create_service_spec.rb": 7.530689159000758,
  "spec/lib/gitlab/error_tracking_spec.rb": 4.322462522999558,
  "spec/presenters/projects/settings/deploy_keys_presenter_spec.rb": 8.454742598998564,
  "spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb": 4.897813035000581,
  "spec/views/notify/pipeline_failed_email.html.haml_spec.rb": 7.158079634000387,
  "spec/services/labels/create_service_spec.rb": 5.054704135000065,
  "spec/lib/gitlab/metrics/methods_spec.rb": 2.1702353059990855,
  "spec/models/hooks/project_hook_spec.rb": 5.001453337999919,
  "spec/views/projects/merge_requests/show.html.haml_spec.rb": 7.0404367730006925,
  "spec/models/concerns/schedulable_spec.rb": 4.727092835999429,
  "spec/serializers/discussion_diff_file_entity_spec.rb": 5.53463658200053,
  "spec/finders/contributed_projects_finder_spec.rb": 6.39854585500143,
  "spec/lib/gitlab/database/count_spec.rb": 6.8721254439988115,
  "spec/models/concerns/project_features_compatibility_spec.rb": 5.660291374000735,
  "spec/services/concerns/rate_limited_service_spec.rb": 4.977810389000297,
  "spec/lib/gitlab/rack_attack_spec.rb": 1.9091895929996099,
  "spec/lib/gitlab/ci/reports/test_reports_spec.rb": 3.030892288999894,
  "spec/tasks/gettext_rake_spec.rb": 8.668160556999283,
  "spec/services/ci/run_scheduled_build_service_spec.rb": 5.191980015999434,
  "spec/lib/gitlab/visibility_level_checker_spec.rb": 4.312588946999313,
  "spec/lib/gitlab/slash_commands/presenters/issue_show_spec.rb": 4.21370422200016,
  "spec/workers/ci/delete_unit_tests_worker_spec.rb": 6.273120136000216,
  "spec/models/packages/dependency_link_spec.rb": 4.472939667000901,
  "spec/lib/gitlab/kubernetes/helm/v2/install_command_spec.rb": 2.247431912999673,
  "spec/config/inject_enterprise_edition_module_spec.rb": 2.508422569000686,
  "spec/models/lfs_download_object_spec.rb": 2.5285225880015787,
  "spec/lib/gitlab/ci/config/entry/service_spec.rb": 4.7319638219996705,
  "spec/finders/concerns/finder_with_group_hierarchy_spec.rb": 4.182337533999089,
  "spec/lib/gitlab/ci/reports/security/report_spec.rb": 4.078698469000301,
  "spec/lib/gitlab/shell_spec.rb": 4.0311762020010065,
  "spec/services/terraform/remote_state_handler_spec.rb": 3.4961825919999683,
  "spec/helpers/routing/pseudonymization_helper_spec.rb": 3.1875033899996197,
  "spec/lib/gitlab/database/partitioning/time_partition_spec.rb": 3.4803333330000896,
  "spec/views/projects/commit/show.html.haml_spec.rb": 2.6107108520009206,
  "spec/lib/banzai/reference_parser/label_parser_spec.rb": 4.01766715300073,
  "spec/lib/banzai/filter/wiki_link_filter_spec.rb": 1.8759491729997535,
  "spec/views/shared/_global_alert.html.haml_spec.rb": 3.2759073649995116,
  "spec/services/alert_management/alerts/todo/create_service_spec.rb": 3.1361764329994912,
  "spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb": 4.691875104999781,
  "spec/lib/gitlab/kubernetes/helm/v3/patch_command_spec.rb": 2.8313882799993735,
  "spec/services/chat_names/find_user_service_spec.rb": 2.3471614080008294,
  "spec/graphql/mutations/terraform/state/delete_spec.rb": 1.1932686020008987,
  "spec/services/metrics/dashboard/transient_embed_service_spec.rb": 2.2221030139990035,
  "spec/lib/gitlab/null_request_store_spec.rb": 0.8730104799997207,
  "spec/models/experiment_subject_spec.rb": 1.3392139740008133,
  "spec/models/integrations/bugzilla_spec.rb": 1.4867510659987602,
  "spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb": 1.4109740309995686,
  "spec/lib/gitlab/checks/diff_check_spec.rb": 4.1442864860000554,
  "spec/workers/concerns/limited_capacity/worker_spec.rb": 0.9094467689992598,
  "spec/finders/protected_branches_finder_spec.rb": 2.928766794000694,
  "spec/models/packages/debian/group_distribution_key_spec.rb": 1.414824920000683,
  "spec/lib/gitlab/ci/config/external/file/project_spec.rb": 3.058037847000378,
  "spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb": 1.137835546000133,
  "spec/models/ci/freeze_period_spec.rb": 1.2557690989997354,
  "spec/lib/gitlab/suggestions/suggestion_set_spec.rb": 2.8525096390003455,
  "spec/lib/banzai/reference_parser/mentioned_user_parser_spec.rb": 2.899931687001299,
  "spec/lib/gitlab/config/entry/undefined_spec.rb": 0.6678706929997134,
  "spec/tasks/gitlab/external_diffs_rake_spec.rb": 3.1604713409997203,
  "spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb": 1.4219492499996704,
  "spec/finders/prometheus_metrics_finder_spec.rb": 1.4090507599994453,
  "spec/lib/gitlab/static_site_editor/config/generated_config_spec.rb": 2.352265036999597,
  "spec/workers/personal_access_tokens/expiring_worker_spec.rb": 1.0807866390005074,
  "spec/lib/gitlab/bullet/exclusions_spec.rb": 1.034588750999319,
  "spec/lib/gitlab/jwt_authenticatable_spec.rb": 0.7505678380002792,
  "spec/graphql/mutations/todos/mark_all_done_spec.rb": 2.917965175000063,
  "spec/services/ci/job_token_scope/remove_project_service_spec.rb": 1.7758752890003962,
  "spec/validators/json_schema_validator_spec.rb": 1.9445467810000991,
  "spec/views/projects/diffs/_viewer.html.haml_spec.rb": 2.836305889999494,
  "spec/services/error_tracking/base_service_spec.rb": 0.7090588699993532,
  "spec/lib/gitlab/git/keep_around_spec.rb": 2.760833274000106,
  "spec/presenters/ci/group_variable_presenter_spec.rb": 1.4901629659998434,
  "spec/lib/api/helpers/related_resources_helpers_spec.rb": 0.8150888229993143,
  "spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb": 1.4472617989995342,
  "spec/services/ci/pipeline_artifacts/coverage_report_service_spec.rb": 3.2843733040008374,
  "spec/graphql/mutations/terraform/state/lock_spec.rb": 2.2072674249993725,
  "spec/services/snippets/count_service_spec.rb": 2.3021686900010536,
  "spec/lib/banzai/filter/inline_cluster_metrics_filter_spec.rb": 2.356070837000516,
  "spec/services/ci/compare_test_reports_service_spec.rb": 2.710894775998895,
  "spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb": 1.5515635529991414,
  "spec/helpers/instance_configuration_helper_spec.rb": 1.010372663000453,
  "spec/graphql/mutations/security/ci_configuration/configure_secret_detection_spec.rb": 2.6311920520001877,
  "spec/services/system_notes/base_service_spec.rb": 0.7912182949985436,
  "spec/lib/gitlab/ci/templates/5_minute_production_app_ci_yaml_spec.rb": 2.9711427020010888,
  "spec/lib/gitlab/kas/client_spec.rb": 1.4608861569995497,
  "spec/serializers/member_serializer_spec.rb": 2.457567460998689,
  "spec/lib/banzai/filter/inline_diff_filter_spec.rb": 1.398697811000602,
  "spec/graphql/types/namespace_type_spec.rb": 0.6283070350000344,
  "spec/lib/gitlab/exclusive_lease_helpers_spec.rb": 1.1340247059997637,
  "spec/services/audit_event_service_spec.rb": 1.853140125000209,
  "spec/models/gpg_key_subkey_spec.rb": 0.7087418900009652,
  "spec/lib/gitlab/graphql/batch_key_spec.rb": 0.7872518050007784,
  "spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb": 1.8022126979994937,
  "spec/lib/gitlab/loop_helpers_spec.rb": 1.7004750240012072,
  "spec/rubocop/cop/rspec/env_assignment_spec.rb": 0.6064064059992234,
  "spec/lib/gitlab/search_context/controller_concern_spec.rb": 2.3028572100010933,
  "spec/workers/repository_remove_remote_worker_spec.rb": 1.675120476000302,
  "spec/services/ci/create_pipeline_service/creation_errors_and_warnings_spec.rb": 1.9373068300010345,
  "spec/lib/gitlab/hook_data/group_builder_spec.rb": 0.7638491569996404,
  "spec/finders/terraform/states_finder_spec.rb": 1.3819303820000641,
  "spec/lib/bulk_imports/common/pipelines/entity_finisher_spec.rb": 1.4761897659991519,
  "spec/workers/migrate_external_diffs_worker_spec.rb": 1.6678230060006172,
  "spec/graphql/types/base_edge_spec.rb": 2.5937809830011247,
  "spec/workers/update_highest_role_worker_spec.rb": 1.4830805159999727,
  "spec/workers/authorized_project_update/user_refresh_with_low_urgency_worker_spec.rb": 1.585319731000709,
  "spec/lib/gitlab/git/changes_spec.rb": 0.7785108459993353,
  "spec/graphql/mutations/terraform/state/unlock_spec.rb": 1.797583327999746,
  "spec/lib/gitlab/data_builder/wiki_page_spec.rb": 1.5156480850000662,
  "spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb": 1.2366314299997612,
  "spec/views/projects/environments/terminal.html.haml_spec.rb": 1.8978819219992147,
  "spec/lib/gitlab/crypto_helper_spec.rb": 0.8184297539992258,
  "spec/lib/gitlab/ci/config/entry/release/assets/link_spec.rb": 1.0036942930000805,
  "spec/lib/gitlab/database/postgresql_adapter/empty_query_ping_spec.rb": 0.6935788210012106,
  "spec/presenters/service_hook_presenter_spec.rb": 2.7365514950015495,
  "spec/graphql/types/ci/pipeline_type_spec.rb": 0.6290151349985535,
  "spec/services/issues/after_create_service_spec.rb": 1.5673734320007497,
  "spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb": 0.8286856830000033,
  "spec/lib/gitlab/gitlab_import/client_spec.rb": 1.243369289999464,
  "spec/models/wiki_directory_spec.rb": 0.8373544219994074,
  "spec/workers/group_destroy_worker_spec.rb": 1.7349498820003646,
  "spec/services/ci/pipeline_bridge_status_service_spec.rb": 1.6440717170007701,
  "spec/serializers/user_serializer_spec.rb": 1.4297610390003683,
  "spec/workers/pipeline_hooks_worker_spec.rb": 1.0053949329994794,
  "spec/presenters/packages/nuget/package_metadata_presenter_spec.rb": 1.379417531999934,
  "spec/workers/user_status_cleanup/batch_worker_spec.rb": 1.042403651999848,
  "spec/lib/gitlab/repository_size_error_message_spec.rb": 0.8206876139993255,
  "spec/services/resource_events/merge_into_notes_service_spec.rb": 1.8768394040016574,
  "spec/views/projects/clusters/clusters/gcp/_form.html.haml_spec.rb": 1.8978248719995463,
  "spec/rubocop/cop/prefer_class_methods_over_module_spec.rb": 0.70414903100027,
  "spec/graphql/resolvers/project_pipeline_statistics_resolver_spec.rb": 1.0901515379991906,
  "spec/serializers/jira_connect/app_data_serializer_spec.rb": 0.9590960859986808,
  "spec/lib/gitlab/middleware/basic_health_check_spec.rb": 0.7535026770001423,
  "spec/presenters/pages_domain_presenter_spec.rb": 1.0067275330002303,
  "spec/workers/jira_connect/sync_deployments_worker_spec.rb": 1.154454404999342,
  "spec/tooling/lib/tooling/crystalball/coverage_lines_execution_detector_spec.rb": 0.6785518520009646,
  "spec/rubocop/cop/gitlab/delegate_predicate_methods_spec.rb": 0.6680235929998162,
  "spec/models/approval_spec.rb": 1.472612425999614,
  "spec/services/users/dismiss_callout_service_spec.rb": 0.8842307899994921,
  "spec/serializers/import/manifest_provider_repo_entity_spec.rb": 1.0766461900002469,
  "spec/lib/gitlab/code_navigation_path_spec.rb": 1.0742919399999664,
  "spec/lib/gitlab/import_export/design_repo_restorer_spec.rb": 1.3141649560002406,
  "spec/rubocop/cop/gitlab/policy_rule_boolean_spec.rb": 0.7252572189991042,
  "spec/models/diff_viewer/image_spec.rb": 0.7082216310009244,
  "spec/serializers/diff_viewer_entity_spec.rb": 1.007921432999865,
  "spec/lib/gitlab/graphql/pagination/connections_spec.rb": 0.8172029739998834,
  "spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/client_spec.rb": 0.7096700699985377,
  "spec/tasks/admin_mode_spec.rb": 0.919878577999043,
  "spec/presenters/alert_management/alert_presenter_spec.rb": 1.1410522549995221,
  "spec/workers/experiments/record_conversion_event_worker_spec.rb": 0.7360689479992288,
  "spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb": 0.8403496720002295,
  "spec/lib/gitlab/utils/delegator_override/validator_spec.rb": 0.6248812249996263,
  "spec/lib/gitlab/graphql/negatable_arguments_spec.rb": 0.7337402590001147,
  "spec/lib/gitlab/import_export/after_export_strategy_builder_spec.rb": 0.807289343998491,
  "spec/lib/gitlab/github_import/bulk_importing_spec.rb": 0.7030756200001633,
  "spec/graphql/types/merge_request_state_enum_spec.rb": 0.6598369629991794,
  "spec/lib/gitlab/phabricator_import/conduit/users_response_spec.rb": 0.5503682489998027,
  "spec/services/base_container_service_spec.rb": 0.6134709859998111,
  "spec/lib/gitlab/sidekiq_middleware/extra_done_log_metadata_spec.rb": 0.6400048239993339,
  "spec/views/admin/application_settings/_repository_storage.html.haml_spec.rb": 0.6519449930001429,
  "spec/models/protected_branch/merge_access_level_spec.rb": 0.5681165969999711,
  "spec/serializers/accessibility_reports_comparer_entity_spec.rb": 0.674719341999662,
  "spec/graphql/types/design_management/design_version_event_enum_spec.rb": 0.749858196999412,
  "spec/lib/peek/views/memory_spec.rb": 0.618498144998739,
  "spec/helpers/one_trust_helper_spec.rb": 0.6893027410005743,
  "spec/lib/gitlab/hashed_path_spec.rb": 0.6339868439990823,
  "spec/lib/api/entities/deploy_keys_project_spec.rb": 1.1973354120000295,
  "spec/lib/api/validations/validators/project_portable_spec.rb": 0.8554722720000427,
  "spec/lib/sidebars/projects/menus/repository_menu_spec.rb": 0.8631828210000094,
  "spec/rubocop/cop/rspec/timecop_freeze_spec.rb": 0.6045606560001033,
  "spec/rubocop/cop/qa/selector_usage_spec.rb": 0.6177391949986486,
  "spec/lib/gitlab/ci/build/port_spec.rb": 0.7814046560015413,
  "spec/rubocop/qa_helpers_spec.rb": 0.6559519129987166,
  "spec/views/groups/runners/_sort_dropdown.html.haml_spec.rb": 0.6829232910004066,
  "spec/initializers/mailer_retries_spec.rb": 0.747646148000058,
  "spec/lib/gitlab/chat_spec.rb": 0.6481355029991391,
  "spec/lib/gitlab/database/background_migration/batch_metrics_spec.rb": 0.6173450549995323,
  "spec/lib/constraints/feature_constrainer_spec.rb": 0.6174595150005189,
  "spec/lib/gitlab/sidekiq_middleware/size_limiter/server_spec.rb": 0.6419213540011697,
  "spec/graphql/types/ci/config/job_type_spec.rb": 0.6282117039991135,
  "spec/models/packages/rubygems/metadatum_spec.rb": 0.9242552979994798,
  "spec/lib/gitlab/action_cable/request_store_callbacks_spec.rb": 0.593027646000337,
  "spec/lib/gitlab/git/patches/patch_spec.rb": 0.5331269299986161,
  "spec/serializers/evidences/release_serializer_spec.rb": 0.5757746479994239,
  "spec/graphql/types/packages/package_type_enum_spec.rb": 0.7193933489998017,
  "spec/models/concerns/from_union_spec.rb": 0.7107127199997194,
  "spec/lib/gitlab/sidekiq_middleware/worker_context/server_spec.rb": 0.7786283860004914,
  "spec/views/errors/access_denied.html.haml_spec.rb": 0.7386176279997017,
  "spec/lib/gitlab/database/async_indexes_spec.rb": 0.6210365850001835,
  "spec/uploaders/uploader_helper_spec.rb": 0.5892808560001868,
  "spec/serializers/ci/codequality_mr_diff_entity_spec.rb": 0.5409309000006033
}

Knapsack global time execution for tests: 28m 19s

Pending: (Failures listed here are expected and do not affect your suite's status)

  1) MergeRequest modules behaves like AtomicInternalId .has_internal_id Validation when presence validation is not required when creating an object does not raise an error if the internal id is blank
     # No reason given
     # ./spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb:49

  2) MergeRequest modules behaves like AtomicInternalId .has_internal_id Validation when presence validation is not required when updating an object does not raise an error if the internal id is blank
     # No reason given
     # ./spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb:57

  3) DesignManagement::DesignV432x230Uploader behaves like builds correct paths #cache_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  4) DesignManagement::DesignV432x230Uploader behaves like builds correct paths #work_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  5) DesignManagement::DesignV432x230Uploader behaves like builds correct paths #relative_path is relative
     # Path not set, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:40

  6) DesignManagement::DesignV432x230Uploader behaves like builds correct paths .base_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  7) DesignManagement::DesignV432x230Uploader object_store is REMOTE behaves like builds correct paths #cache_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  8) DesignManagement::DesignV432x230Uploader object_store is REMOTE behaves like builds correct paths #work_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  9) DesignManagement::DesignV432x230Uploader object_store is REMOTE behaves like builds correct paths #relative_path is relative
     # Path not set, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:40

  10) DesignManagement::DesignV432x230Uploader object_store is REMOTE behaves like builds correct paths .absolute_path behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

  11) DesignManagement::DesignV432x230Uploader object_store is REMOTE behaves like builds correct paths .base_dir behaves like matches the method pattern 
     # No pattern provided, skipping.
     # ./spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb:8

Finished in 28 minutes 22 seconds (files took 47.13 seconds to load)
4080 examples, 0 failures, 11 pending

Tue Dec 14 01:56:50 UTC 2021
section_end:1639447011:step_script
section_start:1639447011:archive_cache
Saving cache for successful job
Not uploading cache ruby-gems-v1-9 due to policy
Not uploading cache gitaly-ruby-gems-v1-9 due to policy
section_end:1639447011:archive_cache
section_start:1639447011:upload_artifacts_on_success
Uploading artifacts for successful job
Uploading artifacts...
coverage/: found 5 matching files and directories  
crystalball/: found 2 matching files and directories 
deprecations/: found 4 matching files and directories 
knapsack/: found 3 matching files and directories  
rspec_flaky/: found 5 matching files and directories 
rspec_profiling/: found 1 matching files and directories 
WARNING: tmp/capybara/: no matching files          
tmp/memory_test/: found 2 matching files and directories 
log/*.log: found 19 matching files and directories 
Uploading artifacts as "archive" to coordinator... ok  id=1880797998 responseStatus=201 Created token=QEZ25EQM
Uploading artifacts...
junit_rspec.xml: found 1 matching files and directories 
Uploading artifacts as "junit" to coordinator... ok  id=1880797998 responseStatus=201 Created token=QEZ25EQM
section_end:1639447015:upload_artifacts_on_success
section_start:1639447015:cleanup_file_variables
Cleaning up project directory and file based variables
section_end:1639447016:cleanup_file_variables
Job succeeded