diff options
author | Michael Kozono <mkozono@gmail.com> | 2017-11-14 23:15:30 -0800 |
---|---|---|
committer | Michael Kozono <mkozono@gmail.com> | 2017-12-01 15:26:41 -0800 |
commit | d530085685105e2d7cd6d87ba866756683f0488d (patch) | |
tree | 7e9ea7cbafff093b81855f67ca8edf76f9d1015f | |
parent | c25b7c0e3f6d43b5fb77e53bbd0dd4495b8e0c69 (diff) | |
download | gitlab-ce-d530085685105e2d7cd6d87ba866756683f0488d.tar.gz |
Refactor specs
4 files changed, 183 insertions, 337 deletions
diff --git a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb index 953793a353c..c794a2f152b 100644 --- a/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb +++ b/spec/lib/gitlab/background_migration/populate_untracked_uploads_spec.rb @@ -1,46 +1,36 @@ require 'spec_helper' describe Gitlab::BackgroundMigration::PopulateUntrackedUploads, :migration, :sidekiq, schema: 20171103140253 do + include TrackUntrackedUploadsHelpers + let!(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) } let!(:uploads) { table(:uploads) } - let(:user1) { create(:user) } - let(:user2) { create(:user) } - let(:project1) { create(:project) } - let(:project2) { create(:project) } - let(:appearance) { create(:appearance) } - context 'with untracked files and tracked files in untracked_files_for_uploads' do - before do - fixture = Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') + let!(:appearance) { create(:appearance, logo: uploaded_file, header_logo: uploaded_file) } + let!(:user1) { create(:user, :with_avatar) } + let!(:user2) { create(:user, :with_avatar) } + let!(:project1) { create(:project, :with_avatar) } + let!(:project2) { create(:project, :with_avatar) } - # Tracked, by doing normal file upload - uploaded_file = fixture_file_upload(fixture) - user1.update!(avatar: uploaded_file) - project1.update!(avatar: uploaded_file) + before do UploadService.new(project1, uploaded_file, FileUploader).execute # Markdown upload - appearance.update!(logo: uploaded_file) - - # Untracked, by doing normal file upload then later deleting records from DB - uploaded_file = fixture_file_upload(fixture) - user2.update!(avatar: uploaded_file) - project2.update!(avatar: uploaded_file) UploadService.new(project2, uploaded_file, FileUploader).execute # Markdown upload - appearance.update!(header_logo: uploaded_file) # File records created by PrepareUntrackedUploads - untracked_files_for_uploads.create!(path: found_path(appearance.logo.file.file)) - untracked_files_for_uploads.create!(path: found_path(appearance.header_logo.file.file)) - untracked_files_for_uploads.create!(path: found_path(user1.avatar.file.file)) - untracked_files_for_uploads.create!(path: found_path(user2.avatar.file.file)) - untracked_files_for_uploads.create!(path: found_path(project1.avatar.file.file)) - untracked_files_for_uploads.create!(path: found_path(project2.avatar.file.file)) + untracked_files_for_uploads.create!(path: appearance.uploads.first.path) + untracked_files_for_uploads.create!(path: appearance.uploads.last.path) + untracked_files_for_uploads.create!(path: user1.uploads.first.path) + untracked_files_for_uploads.create!(path: user2.uploads.first.path) + untracked_files_for_uploads.create!(path: project1.uploads.first.path) + untracked_files_for_uploads.create!(path: project2.uploads.first.path) untracked_files_for_uploads.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project1.full_path}/#{project1.uploads.last.path}") untracked_files_for_uploads.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project2.full_path}/#{project2.uploads.last.path}") + # Untrack 4 files user2.uploads.delete_all - project2.uploads.delete_all - appearance.uploads.last.destroy + project2.uploads.delete_all # 2 files: avatar and a Markdown upload + appearance.uploads.where("path like '%header_logo%'").delete_all end it 'adds untracked files to the uploads table' do @@ -119,33 +109,36 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do let(:upload_class) { Gitlab::BackgroundMigration::PopulateUntrackedUploads::Upload } describe '#ensure_tracked!' do - let(:user1) { create(:user) } + let!(:user1) { create(:user, :with_avatar) } + let!(:untracked_file) { described_class.create!(path: user1.uploads.first.path) } context 'when the file is already in the uploads table' do - let(:untracked_file) { described_class.create!(path: "uploads/-/system/user/avatar/#{user1.id}/avatar.jpg") } + it 'does not add an upload' do + expect do + untracked_file.ensure_tracked! + end.not_to change { upload_class.count }.from(1) + end + end + context 'when the file is not already in the uploads table' do before do - upload_class.create!(path: "uploads/-/system/user/avatar/#{user1.id}/avatar.jpg", uploader: 'AvatarUploader', model_type: 'User', model_id: user1.id, size: 1234) + user1.uploads.delete_all end - it 'does not add an upload' do + it 'adds an upload' do expect do untracked_file.ensure_tracked! - end.not_to change { upload_class.count }.from(1) + end.to change { upload_class.count }.from(0).to(1) end end end describe '#add_to_uploads' do - let(:fixture) { Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') } - let(:uploaded_file) { fixture_file_upload(fixture) } - - context 'for an appearance logo file path' do - let(:model) { create(:appearance) } - let(:untracked_file) { described_class.create!(path: found_path(model.logo.file.file)) } + shared_examples_for 'add_to_uploads_non_markdown_files' do + let!(:expected_upload_attrs) { model.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') } + let!(:untracked_file) { described_class.create!(path: expected_upload_attrs['path']) } before do - model.update!(logo: uploaded_file) model.uploads.delete_all end @@ -154,129 +147,68 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do untracked_file.add_to_uploads end.to change { model.reload.uploads.count }.from(0).to(1) - expect(model.uploads.first.attributes).to include({ - "path" => "uploads/-/system/appearance/logo/#{model.id}/rails_sample.jpg", - "uploader" => "AttachmentUploader" - }.merge(rails_sample_jpg_attrs)) + expect(model.uploads.first.attributes).to include(expected_upload_attrs) end end - context 'for an appearance header_logo file path' do - let(:model) { create(:appearance) } - let(:untracked_file) { described_class.create!(path: found_path(model.header_logo.file.file)) } + context 'for an appearance logo file path' do + let(:model) { create(:appearance, logo: uploaded_file) } - before do - model.update!(header_logo: uploaded_file) - model.uploads.delete_all - end + it_behaves_like 'add_to_uploads_non_markdown_files' + end - it 'creates an Upload record' do - expect do - untracked_file.add_to_uploads - end.to change { model.reload.uploads.count }.from(0).to(1) + context 'for an appearance header_logo file path' do + let(:model) { create(:appearance, header_logo: uploaded_file) } - expect(model.uploads.first.attributes).to include({ - "path" => "uploads/-/system/appearance/header_logo/#{model.id}/rails_sample.jpg", - "uploader" => "AttachmentUploader" - }.merge(rails_sample_jpg_attrs)) - end + it_behaves_like 'add_to_uploads_non_markdown_files' end context 'for a pre-Markdown Note attachment file path' do - let(:model) { create(:note) } - let(:untracked_file) { described_class.create!(path: found_path(model.attachment.file.file)) } - - before do - model.update!(attachment: uploaded_file) - upload_class.delete_all + class Note < ActiveRecord::Base + has_many :uploads, as: :model, dependent: :destroy end - it 'creates an Upload record' do - expect do - untracked_file.add_to_uploads - end.to change { upload_class.count }.from(0).to(1) + let(:model) { create(:note, :with_attachment) } - expect(upload_class.first.attributes).to include({ - "path" => "uploads/-/system/note/attachment/#{model.id}/rails_sample.jpg", - "model_id" => model.id, - "model_type" => "Note", - "uploader" => "AttachmentUploader" - }.merge(rails_sample_jpg_attrs)) - end + it_behaves_like 'add_to_uploads_non_markdown_files' end context 'for a user avatar file path' do - let(:model) { create(:user) } - let(:untracked_file) { described_class.create!(path: found_path(model.avatar.file.file)) } + let(:model) { create(:user, :with_avatar) } - before do - model.update!(avatar: uploaded_file) - model.uploads.delete_all - end - - it 'creates an Upload record' do - expect do - untracked_file.add_to_uploads - end.to change { model.reload.uploads.count }.from(0).to(1) - - expect(model.uploads.first.attributes).to include({ - "path" => "uploads/-/system/user/avatar/#{model.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - end + it_behaves_like 'add_to_uploads_non_markdown_files' end context 'for a group avatar file path' do - let(:model) { create(:group) } - let(:untracked_file) { described_class.create!(path: found_path(model.avatar.file.file)) } - - before do - model.update!(avatar: uploaded_file) - model.uploads.delete_all - end + let(:model) { create(:group, :with_avatar) } - it 'creates an Upload record' do - expect do - untracked_file.add_to_uploads - end.to change { model.reload.uploads.count }.from(0).to(1) - - expect(model.uploads.first.attributes).to include({ - "path" => "uploads/-/system/group/avatar/#{model.id}/rails_sample.jpg", - "model_id" => model.id, - "model_type" => "Namespace", # Explicitly calling this out because it was unexpected to me (I assumed it should be "Group") - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - end + it_behaves_like 'add_to_uploads_non_markdown_files' end context 'for a project avatar file path' do - let(:model) { create(:project) } - let(:untracked_file) { described_class.create!(path: found_path(model.avatar.file.file)) } - - before do - model.update!(avatar: uploaded_file) - model.uploads.delete_all - end - - it 'creates an Upload record' do - expect do - untracked_file.add_to_uploads - end.to change { model.reload.uploads.count }.from(0).to(1) + let(:model) { create(:project, :with_avatar) } - expect(model.uploads.first.attributes).to include({ - "path" => "uploads/-/system/project/avatar/#{model.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - end + it_behaves_like 'add_to_uploads_non_markdown_files' end context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do let(:model) { create(:project) } - let(:untracked_file) { described_class.new(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{model.full_path}/#{model.uploads.first.path}") } + let(:expected_upload_attrs) { {} } + + # UntrackedFile.path is different than Upload.path + let(:untracked_file) { create_untracked_file("/#{model.full_path}/#{model.uploads.first.path}") } before do - UploadService.new(model, uploaded_file, FileUploader).execute # Markdown upload - untracked_file.save! + # Upload the file + UploadService.new(model, uploaded_file, FileUploader).execute + + # Create the untracked_files_for_uploads record + untracked_file + + # Save the expected upload attributes + expected_upload_attrs = model.reload.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') + + # Untrack the file model.reload.uploads.delete_all end @@ -286,18 +218,15 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do end.to change { model.reload.uploads.count }.from(0).to(1) hex_secret = untracked_file.path.match(/\/(\h+)\/rails_sample.jpg/)[1] - expect(model.uploads.first.attributes).to include({ - "path" => "#{hex_secret}/rails_sample.jpg", - "uploader" => "FileUploader" - }.merge(rails_sample_jpg_attrs)) + expect(model.uploads.first.attributes).to include(expected_upload_attrs) end end end describe '#mark_as_tracked' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/logo/1/some_logo.jpg") } - it 'saves the record with tracked set to true' do + untracked_file = create_untracked_file("/-/system/appearance/logo/1/some_logo.jpg") + expect do untracked_file.mark_as_tracked end.to change { untracked_file.tracked }.from(false).to(true) @@ -307,253 +236,218 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do end describe '#upload_path' do - context 'for an appearance logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/logo/1/some_logo.jpg") } + def assert_upload_path(file_path, expected_upload_path) + untracked_file = create_untracked_file(file_path) + expect(untracked_file.upload_path).to eq(expected_upload_path) + end + + context 'for an appearance logo file path' do it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/appearance/logo/1/some_logo.jpg') + assert_upload_path('/-/system/appearance/logo/1/some_logo.jpg', 'uploads/-/system/appearance/logo/1/some_logo.jpg') end end context 'for an appearance header_logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/header_logo/1/some_logo.jpg") } - it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/appearance/header_logo/1/some_logo.jpg') + assert_upload_path('/-/system/appearance/header_logo/1/some_logo.jpg', 'uploads/-/system/appearance/header_logo/1/some_logo.jpg') end end context 'for a pre-Markdown Note attachment file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/note/attachment/1234/some_attachment.pdf") } - it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/note/attachment/1234/some_attachment.pdf') + assert_upload_path('/-/system/note/attachment/1234/some_attachment.pdf', 'uploads/-/system/note/attachment/1234/some_attachment.pdf') end end context 'for a user avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/user/avatar/1234/avatar.jpg") } - it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/user/avatar/1234/avatar.jpg') + assert_upload_path('/-/system/user/avatar/1234/avatar.jpg', 'uploads/-/system/user/avatar/1234/avatar.jpg') end end context 'for a group avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/group/avatar/1234/avatar.jpg") } - it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/group/avatar/1234/avatar.jpg') + assert_upload_path('/-/system/group/avatar/1234/avatar.jpg', 'uploads/-/system/group/avatar/1234/avatar.jpg') end end context 'for a project avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/project/avatar/1234/avatar.jpg") } - it 'returns the file path relative to the CarrierWave root' do - expect(untracked_file.upload_path).to eq('uploads/-/system/project/avatar/1234/avatar.jpg') + assert_upload_path('/-/system/project/avatar/1234/avatar.jpg', 'uploads/-/system/project/avatar/1234/avatar.jpg') end end context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do - let(:project) { create(:project) } - let(:random_hex) { SecureRandom.hex } - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project.full_path}/#{random_hex}/Some file.jpg") } - it 'returns the file path relative to the project directory in uploads' do - expect(untracked_file.upload_path).to eq("#{random_hex}/Some file.jpg") + project = create(:project) + random_hex = SecureRandom.hex + + assert_upload_path("/#{project.full_path}/#{random_hex}/Some file.jpg", "#{random_hex}/Some file.jpg") end end end describe '#uploader' do - context 'for an appearance logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/logo/1/some_logo.jpg") } + def assert_uploader(file_path, expected_uploader) + untracked_file = create_untracked_file(file_path) + + expect(untracked_file.uploader).to eq(expected_uploader) + end + context 'for an appearance logo file path' do it 'returns AttachmentUploader as a string' do - expect(untracked_file.uploader).to eq('AttachmentUploader') + assert_uploader('/-/system/appearance/logo/1/some_logo.jpg', 'AttachmentUploader') end end context 'for an appearance header_logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/header_logo/1/some_logo.jpg") } - it 'returns AttachmentUploader as a string' do - expect(untracked_file.uploader).to eq('AttachmentUploader') + assert_uploader('/-/system/appearance/header_logo/1/some_logo.jpg', 'AttachmentUploader') end end context 'for a pre-Markdown Note attachment file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/note/attachment/1234/some_attachment.pdf") } - it 'returns AttachmentUploader as a string' do - expect(untracked_file.uploader).to eq('AttachmentUploader') + assert_uploader('/-/system/note/attachment/1234/some_attachment.pdf', 'AttachmentUploader') end end context 'for a user avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/user/avatar/1234/avatar.jpg") } - it 'returns AvatarUploader as a string' do - expect(untracked_file.uploader).to eq('AvatarUploader') + assert_uploader('/-/system/user/avatar/1234/avatar.jpg', 'AvatarUploader') end end context 'for a group avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/group/avatar/1234/avatar.jpg") } - it 'returns AvatarUploader as a string' do - expect(untracked_file.uploader).to eq('AvatarUploader') + assert_uploader('/-/system/group/avatar/1234/avatar.jpg', 'AvatarUploader') end end context 'for a project avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/project/avatar/1234/avatar.jpg") } - it 'returns AvatarUploader as a string' do - expect(untracked_file.uploader).to eq('AvatarUploader') + assert_uploader('/-/system/project/avatar/1234/avatar.jpg', 'AvatarUploader') end end context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do - let(:project) { create(:project) } - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg") } - it 'returns FileUploader as a string' do - expect(untracked_file.uploader).to eq('FileUploader') + project = create(:project) + + assert_uploader("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", 'FileUploader') end end end describe '#model_type' do - context 'for an appearance logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/logo/1/some_logo.jpg") } + def assert_model_type(file_path, expected_model_type) + untracked_file = create_untracked_file(file_path) + expect(untracked_file.model_type).to eq(expected_model_type) + end + + context 'for an appearance logo file path' do it 'returns Appearance as a string' do - expect(untracked_file.model_type).to eq('Appearance') + assert_model_type('/-/system/appearance/logo/1/some_logo.jpg', 'Appearance') end end context 'for an appearance header_logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/header_logo/1/some_logo.jpg") } - it 'returns Appearance as a string' do - expect(untracked_file.model_type).to eq('Appearance') + assert_model_type('/-/system/appearance/header_logo/1/some_logo.jpg', 'Appearance') end end context 'for a pre-Markdown Note attachment file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/note/attachment/1234/some_attachment.pdf") } - it 'returns Note as a string' do - expect(untracked_file.model_type).to eq('Note') + assert_model_type('/-/system/note/attachment/1234/some_attachment.pdf', 'Note') end end context 'for a user avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/user/avatar/1234/avatar.jpg") } - it 'returns User as a string' do - expect(untracked_file.model_type).to eq('User') + assert_model_type('/-/system/user/avatar/1234/avatar.jpg', 'User') end end context 'for a group avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/group/avatar/1234/avatar.jpg") } - it 'returns Namespace as a string' do - expect(untracked_file.model_type).to eq('Namespace') + assert_model_type('/-/system/group/avatar/1234/avatar.jpg', 'Namespace') end end context 'for a project avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/project/avatar/1234/avatar.jpg") } - it 'returns Project as a string' do - expect(untracked_file.model_type).to eq('Project') + assert_model_type('/-/system/project/avatar/1234/avatar.jpg', 'Project') end end context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do - let(:project) { create(:project) } - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg") } - it 'returns Project as a string' do - expect(untracked_file.model_type).to eq('Project') + project = create(:project) + + assert_model_type("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", 'Project') end end end describe '#model_id' do - context 'for an appearance logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/logo/1/some_logo.jpg") } + def assert_model_id(file_path, expected_model_id) + untracked_file = create_untracked_file(file_path) + + expect(untracked_file.model_id).to eq(expected_model_id) + end + context 'for an appearance logo file path' do it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1') + assert_model_id('/-/system/appearance/logo/1/some_logo.jpg', '1') end end context 'for an appearance header_logo file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/appearance/header_logo/1/some_logo.jpg") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1') + assert_model_id('/-/system/appearance/header_logo/1/some_logo.jpg', '1') end end context 'for a pre-Markdown Note attachment file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/note/attachment/1234/some_attachment.pdf") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1234') + assert_model_id('/-/system/note/attachment/1234/some_attachment.pdf', '1234') end end context 'for a user avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/user/avatar/1234/avatar.jpg") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1234') + assert_model_id('/-/system/user/avatar/1234/avatar.jpg', '1234') end end context 'for a group avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/group/avatar/1234/avatar.jpg") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1234') + assert_model_id('/-/system/group/avatar/1234/avatar.jpg', '1234') end end context 'for a project avatar file path' do - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/-/system/project/avatar/1234/avatar.jpg") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq('1234') + assert_model_id('/-/system/project/avatar/1234/avatar.jpg', '1234') end end context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do - let(:project) { create(:project) } - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg") } - it 'returns the ID as a string' do - expect(untracked_file.model_id).to eq(project.id.to_s) + project = create(:project) + + assert_model_id("/#{project.full_path}/#{SecureRandom.hex}/Some file.jpg", project.id.to_s) end end end describe '#file_size' do - let(:fixture) { Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') } - let(:uploaded_file) { fixture_file_upload(fixture) } - context 'for an appearance logo file path' do - let(:appearance) { create(:appearance) } - let(:untracked_file) { described_class.create!(path: found_path(appearance.logo.file.file)) } - - before do - appearance.update!(logo: uploaded_file) - end + let(:appearance) { create(:appearance, logo: uploaded_file) } + let(:untracked_file) { described_class.create!(path: appearance.uploads.first.path) } it 'returns the file size' do expect(untracked_file.file_size).to eq(35255) @@ -565,12 +459,8 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do end context 'for a project avatar file path' do - let(:project) { create(:project) } - let(:untracked_file) { described_class.create!(path: found_path(project.avatar.file.file)) } - - before do - project.update!(avatar: uploaded_file) - end + let(:project) { create(:project, avatar: uploaded_file) } + let(:untracked_file) { described_class.create!(path: project.uploads.first.path) } it 'returns the file size' do expect(untracked_file.file_size).to eq(35255) @@ -583,7 +473,7 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do context 'for a project Markdown attachment (notes, issues, MR descriptions) file path' do let(:project) { create(:project) } - let(:untracked_file) { described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}/#{project.full_path}/#{project.uploads.first.path}") } + let(:untracked_file) { create_untracked_file("/#{project.full_path}/#{project.uploads.first.path}") } before do UploadService.new(project, uploaded_file, FileUploader).execute @@ -598,10 +488,8 @@ describe Gitlab::BackgroundMigration::PopulateUntrackedUploads::UntrackedFile do end end end -end -# The path returned by the find command in PrepareUntrackedUploads -# AKA the path relative to CarrierWave.root, without a leading slash. -def found_path(absolute_path) - absolute_path.sub(%r{\A#{CarrierWave.root}/}, '') + def create_untracked_file(path_relative_to_upload_dir) + described_class.create!(path: "#{Gitlab::BackgroundMigration::PrepareUntrackedUploads::RELATIVE_UPLOAD_DIR}#{path_relative_to_upload_dir}") + end end diff --git a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb index d0dd6b7c157..d61135912dd 100644 --- a/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb +++ b/spec/lib/gitlab/background_migration/prepare_untracked_uploads_spec.rb @@ -1,13 +1,9 @@ require 'spec_helper' describe Gitlab::BackgroundMigration::PrepareUntrackedUploads, :migration, :sidekiq, schema: 20171103140253 do - let!(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) } + include TrackUntrackedUploadsHelpers - let(:user1) { create(:user) } - let(:user2) { create(:user) } - let(:project1) { create(:project) } - let(:project2) { create(:project) } - let(:appearance) { create(:appearance) } + let!(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) } matcher :be_scheduled_migration do |*expected| match do |migration| @@ -22,20 +18,18 @@ describe Gitlab::BackgroundMigration::PrepareUntrackedUploads, :migration, :side end context 'when files were uploaded before and after hashed storage was enabled' do - before do - fixture = Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') - uploaded_file = fixture_file_upload(fixture) + let!(:appearance) { create(:appearance, logo: uploaded_file, header_logo: uploaded_file) } + let!(:user) { create(:user, :with_avatar) } + let!(:project1) { create(:project, :with_avatar) } + let(:project2) { create(:project) } # instantiate after enabling hashed_storage - user1.update(avatar: uploaded_file) - project1.update(avatar: uploaded_file) - appearance.update(logo: uploaded_file, header_logo: uploaded_file) - uploaded_file = fixture_file_upload(fixture) - UploadService.new(project1, uploaded_file, FileUploader).execute # Markdown upload + before do + # Markdown upload before enabling hashed_storage + UploadService.new(project1, uploaded_file, FileUploader).execute stub_application_setting(hashed_storage_enabled: true) - # Hashed files - uploaded_file = fixture_file_upload(fixture) + # Markdown upload after enabling hashed_storage UploadService.new(project2, uploaded_file, FileUploader).execute end diff --git a/spec/migrations/track_untracked_uploads_spec.rb b/spec/migrations/track_untracked_uploads_spec.rb index 83eb6bbd537..a6e880279b6 100644 --- a/spec/migrations/track_untracked_uploads_spec.rb +++ b/spec/migrations/track_untracked_uploads_spec.rb @@ -4,9 +4,7 @@ require Rails.root.join('db', 'post_migrate', '20171103140253_track_untracked_up describe TrackUntrackedUploads, :migration, :sidekiq do include TrackUntrackedUploadsHelpers - class UntrackedFile < ActiveRecord::Base - self.table_name = 'untracked_files_for_uploads' - end + let(:untracked_files_for_uploads) { table(:untracked_files_for_uploads) } matcher :be_scheduled_migration do match do |migration| @@ -46,39 +44,36 @@ describe TrackUntrackedUploads, :migration, :sidekiq do component # filename ].flatten.join('/') - record = UntrackedFile.create!(path: long_path) + record = untracked_files_for_uploads.create!(path: long_path) expect(record.reload.path.size).to eq(519) end context 'with tracked and untracked uploads' do - let(:user1) { create(:user) } - let(:user2) { create(:user) } - let(:project1) { create(:project) } - let(:project2) { create(:project) } - let(:appearance) { create(:appearance) } + let!(:appearance) { create(:appearance, logo: uploaded_file, header_logo: uploaded_file) } + let!(:user1) { create(:user, :with_avatar) } + let!(:user2) { create(:user, :with_avatar) } + let!(:project1) { create(:project, :with_avatar) } + let!(:project2) { create(:project, :with_avatar) } let(:uploads) { table(:uploads) } before do - fixture = Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') - - # Tracked, by doing normal file upload - uploaded_file = fixture_file_upload(fixture) - user1.update(avatar: uploaded_file) - project1.update(avatar: uploaded_file) - upload_result = UploadService.new(project1, uploaded_file, FileUploader).execute # Markdown upload - @project1_markdown_upload_path = upload_result[:url].sub(%r{\A/uploads/}, '') - appearance.update(logo: uploaded_file) - - # Untracked, by doing normal file upload then deleting records from DB - uploaded_file = fixture_file_upload(fixture) - user2.update(avatar: uploaded_file) + UploadService.new(project1, uploaded_file, FileUploader).execute # Markdown upload + UploadService.new(project2, uploaded_file, FileUploader).execute # Markdown upload + + # Save expected Upload attributes + @appearance_logo_attributes = appearance.uploads.where("path like '%/logo/%'").first.attributes.slice('path', 'uploader', 'size', 'checksum') + @appearance_header_logo_attributes = appearance.uploads.where("path like '%/header_logo/%'").first.attributes.slice('path', 'uploader', 'size', 'checksum') + @user1_avatar_attributes = user1.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') + @user2_avatar_attributes = user2.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') + @project1_avatar_attributes = project1.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') + @project2_avatar_attributes = project2.uploads.first.attributes.slice('path', 'uploader', 'size', 'checksum') + @project1_markdown_attributes = project1.uploads.last.attributes.slice('path', 'uploader', 'size', 'checksum') + @project2_markdown_attributes = project2.uploads.last.attributes.slice('path', 'uploader', 'size', 'checksum') + + # Untrack 4 files user2.uploads.delete_all - project2.update(avatar: uploaded_file) - upload_result = UploadService.new(project2, uploaded_file, FileUploader).execute # Markdown upload - @project2_markdown_upload_path = upload_result[:url].sub(%r{\A/uploads/}, '') - project2.uploads.delete_all - appearance.update(header_logo: uploaded_file) - appearance.uploads.last.destroy + project2.uploads.delete_all # 2 files: avatar and a Markdown upload + appearance.uploads.where("path like '%header_logo%'").delete_all end it 'tracks untracked uploads' do @@ -87,23 +82,10 @@ describe TrackUntrackedUploads, :migration, :sidekiq do migrate! end.to change { uploads.count }.from(4).to(8) - expect(user2.reload.uploads.first.attributes).to include({ - "path" => "uploads/-/system/user/avatar/#{user2.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - expect(project2.reload.uploads.first.attributes).to include({ - "path" => "uploads/-/system/project/avatar/#{project2.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - expect(appearance.reload.uploads.count).to eq(2) - expect(appearance.uploads.last.attributes).to include({ - "path" => "uploads/-/system/appearance/header_logo/#{appearance.id}/rails_sample.jpg", - "uploader" => "AttachmentUploader" - }.merge(rails_sample_jpg_attrs)) - expect(project2.uploads.last.attributes).to include({ - "path" => @project2_markdown_upload_path, - "uploader" => "FileUploader" - }.merge(rails_sample_jpg_attrs)) + expect(appearance.reload.uploads.where("path like '%/header_logo/%'").first.attributes).to include(@appearance_header_logo_attributes) + expect(user2.reload.uploads.first.attributes).to include(@user2_avatar_attributes) + expect(project2.reload.uploads.first.attributes).to include(@project2_avatar_attributes) + expect(project2.uploads.last.attributes).to include(@project2_markdown_attributes) end end @@ -111,31 +93,19 @@ describe TrackUntrackedUploads, :migration, :sidekiq do Sidekiq::Testing.inline! do migrate! - expect(user1.reload.uploads.first.attributes).to include({ - "path" => "uploads/-/system/user/avatar/#{user1.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - expect(project1.reload.uploads.first.attributes).to include({ - "path" => "uploads/-/system/project/avatar/#{project1.id}/rails_sample.jpg", - "uploader" => "AvatarUploader" - }.merge(rails_sample_jpg_attrs)) - expect(appearance.reload.uploads.first.attributes).to include({ - "path" => "uploads/-/system/appearance/logo/#{appearance.id}/rails_sample.jpg", - "uploader" => "AttachmentUploader" - }.merge(rails_sample_jpg_attrs)) - expect(project1.uploads.last.attributes).to include({ - "path" => @project1_markdown_upload_path, - "uploader" => "FileUploader" - }.merge(rails_sample_jpg_attrs)) + expect(appearance.reload.uploads.where("path like '%/logo/%'").first.attributes).to include(@appearance_logo_attributes) + expect(user1.reload.uploads.first.attributes).to include(@user1_avatar_attributes) + expect(project1.reload.uploads.first.attributes).to include(@project1_avatar_attributes) + expect(project1.uploads.last.attributes).to include(@project1_markdown_attributes) end end - it 'all UntrackedFile records are marked as tracked' do + it 'all untracked_files_for_uploads records are marked as tracked' do Sidekiq::Testing.inline! do migrate! - expect(UntrackedFile.count).to eq(8) - expect(UntrackedFile.count).to eq(UntrackedFile.where(tracked: true).count) + expect(untracked_files_for_uploads.count).to eq(8) + expect(untracked_files_for_uploads.count).to eq(untracked_files_for_uploads.where(tracked: true).count) end end end diff --git a/spec/support/track_untracked_uploads_helpers.rb b/spec/support/track_untracked_uploads_helpers.rb index 749c5775bb0..5b832929602 100644 --- a/spec/support/track_untracked_uploads_helpers.rb +++ b/spec/support/track_untracked_uploads_helpers.rb @@ -1,12 +1,6 @@ module TrackUntrackedUploadsHelpers - def rails_sample_jpg_attrs - @rails_sample_jpg_attrs ||= { - "size" => File.size(rails_sample_file_path), - "checksum" => Digest::SHA256.file(rails_sample_file_path).hexdigest - } - end - - def rails_sample_file_path - Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') + def uploaded_file + fixture_path = Rails.root.join('spec', 'fixtures', 'rails_sample.jpg') + fixture_file_upload(fixture_path) end end |