From b5629168dcbcf9de8471fe80a56923b91f1141e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Francisco=20Javier=20L=C3=B3pez?= <fjlopez@gitlab.com>
Date: Thu, 18 Feb 2021 10:53:54 +0100
Subject: [PATCH] Remove nil values from snippet blobs

Snippets Vue code, doesn't expect to receive any nil blob,
and it doesn't make sense to have it. In this commit, we
remove nil values from the list.
---
 app/models/snippet.rb                                  |  6 ++++--
 .../321834-fj-remove-nil-values-from-snippet-blobs.yml |  5 +++++
 spec/controllers/projects/snippets_controller_spec.rb  |  6 +++---
 spec/models/snippet_spec.rb                            | 10 ++++++++++
 spec/presenters/snippet_presenter_spec.rb              |  2 +-
 5 files changed, 23 insertions(+), 6 deletions(-)
 create mode 100644 changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml

diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index ab8782ed87f26..b68e166af48c0 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -216,8 +216,10 @@ def blob
   def blobs
     return [] unless repository_exists?
 
-    branch = default_branch
-    list_files(branch).map { |file| Blob.lazy(repository, branch, file) }
+    files = list_files(default_branch)
+    items = files.map { |file| [default_branch, file] }
+
+    repository.blobs_at(items).compact
   end
 
   def hook_attrs
diff --git a/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml b/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml
new file mode 100644
index 0000000000000..ffbe850246ebf
--- /dev/null
+++ b/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug when snippet blobs array contain a nil value
+merge_request: 54552
+author:
+type: fixed
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index f9221c5a4ef3f..793ffbbfad960 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -207,14 +207,14 @@ def mark_as_spam
         subject
 
         expect(assigns(:snippet)).to eq(project_snippet)
-        expect(assigns(:blobs)).to eq(project_snippet.blobs)
+        expect(assigns(:blobs).map(&:name)).to eq(project_snippet.blobs.map(&:name))
         expect(response).to have_gitlab_http_status(:ok)
       end
 
       it 'does not show the blobs expanded by default' do
         subject
 
-        expect(project_snippet.blobs.map(&:expanded?)).to be_all(false)
+        expect(assigns(:blobs).map(&:expanded?)).to be_all(false)
       end
 
       context 'when param expanded is set' do
@@ -223,7 +223,7 @@ def mark_as_spam
         it 'shows all blobs expanded' do
           subject
 
-          expect(project_snippet.blobs.map(&:expanded?)).to be_all(true)
+          expect(assigns(:blobs).map(&:expanded?)).to be_all(true)
         end
       end
     end
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 623767d19e092..c194a98fdd8c9 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -496,6 +496,16 @@
       it 'returns array of blobs' do
         expect(snippet.blobs).to all(be_a(Blob))
       end
+
+      context 'when file does not exist' do
+        it 'removes nil values from the blobs array' do
+          allow(snippet).to receive(:list_files).and_return(%w(LICENSE non_existent_snippet_file))
+
+          blobs = snippet.blobs
+          expect(blobs.count).to eq 1
+          expect(blobs.first.name).to eq 'LICENSE'
+        end
+      end
     end
   end
 
diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb
index a1d987ed78f26..b0387206bd90b 100644
--- a/spec/presenters/snippet_presenter_spec.rb
+++ b/spec/presenters/snippet_presenter_spec.rb
@@ -159,7 +159,7 @@
       let(:snippet) { create(:snippet, :repository, author: user) }
 
       it 'returns repository first blob' do
-        expect(subject).to eq snippet.blobs.first
+        expect(subject.name).to eq snippet.blobs.first.name
       end
     end
   end
-- 
GitLab