Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AliSoftware committed Sep 5, 2023
1 parent c89d346 commit 60a1530
Showing 1 changed file with 195 additions and 0 deletions.
195 changes: 195 additions & 0 deletions supply/spec/uploader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,200 @@ def find_obbs
uploader.perform_upload
end
end

context 'when sync_image_upload is set' do
let(:client) { double('client') }
let(:language) { 'pt-BR' }
let(:config) { { metadata_path: 'spec_metadata', sync_image_upload: true } }

before do
Supply.config = config
allow(Supply::Client).to receive(:make_from_config).and_return(client)
end

describe '#upload_images' do
it 'should upload and replace image if sha256 does not match remote image' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "sha256-of-#{file}") }
allow(Dir).to receive(:glob).and_return(['image.png'])
remote_images = [Supply::ImageListing.new('id123', '_unused_', 'different-remote-sha256', '_unused_')]

Supply::IMAGES_TYPES.each do |image_type|
allow(client).to receive(:fetch_images).with(image_type: image_type, language: language).and_return(remote_images)
expect(client).to receive(:upload_image).with(image_path: File.expand_path('image.png'), image_type: image_type, language: language)
end

uploader = Supply::Uploader.new
uploader.upload_images(language)
end

it 'should skip image upload if sha256 matches remote image' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "sha256-of-#{file}") }
allow(Dir).to receive(:glob).and_return(['image.png'])
remote_images = [Supply::ImageListing.new('id123', '_unused_', 'sha256-of-image.png', '_unused_')]

Supply::IMAGES_TYPES.each do |image_type|
allow(client).to receive(:fetch_images).with(image_type: image_type, language: language).and_return(remote_images)
expect(client).not_to receive(:upload_image).with(image_path: File.expand_path('image.png'), image_type: image_type, language: language)
end

uploader = Supply::Uploader.new
uploader.upload_images(language)
end
end

describe '#upload_screenshots' do
it 'should upload and replace all screenshots if no sha256 matches any remote screenshot' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "local-sha256-of-#{file}") }
local_images = %w[image1.png image2.png image3.png]
allow(Dir).to receive(:glob).and_return(local_images)
remote_images = [1, 2, 3].map do |idx|
Supply::ImageListing.new("id_#{idx}", '_unused_', "remote-sha256-#{idx}", '_unused_')
end

Supply::SCREENSHOT_TYPES.each do |screenshot_type|
allow(client).to receive(:fetch_images).with(image_type: screenshot_type, language: language).and_return(remote_images)
remote_images.each do |image|
expect(client).to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: image.id)
end
local_images.each do |path|
expect(client).to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
end

uploader = Supply::Uploader.new
uploader.upload_screenshots(language)
end

it 'should skip all screenshots if all sha256 matches the remote screenshots' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "common-sha256-of-#{file}") }
local_images = %w[image1.png image2.png image3.png]
allow(Dir).to receive(:glob).and_return(local_images)
remote_images = local_images.map do |path|
Supply::ImageListing.new("id_#{path}", '_unused_', "common-sha256-of-#{path}", '_unused_')
end

Supply::SCREENSHOT_TYPES.each do |screenshot_type|
allow(client).to receive(:fetch_images).with(image_type: screenshot_type, language: language).and_return(remote_images)
remote_images.each do |image|
expect(client).not_to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: image.id)
end
local_images.each do |path|
expect(client).not_to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
end

uploader = Supply::Uploader.new
uploader.upload_screenshots(language)
end

it 'should delete and re-upload screenshots that changed locally, as long as start of list is in order' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "sha256-of-#{file}") }
local_images = %w[image0.png image1.png new-image2.png new-image3.png]
allow(Dir).to receive(:glob).and_return(local_images)

remote_images = %w[image0.png image1.png old-image2.png old-image3.png].map.with_index do |path, idx|
Supply::ImageListing.new("id_#{idx}", '_unused_', "sha256-of-#{path}", '_unused_')
end

Supply::SCREENSHOT_TYPES.each do |screenshot_type|
allow(client).to receive(:fetch_images).with(image_type: screenshot_type, language: language).and_return(remote_images)
local_images[0..1].each_with_index do |path, idx|
expect(client).not_to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: "id_#{idx}")
expect(client).not_to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
local_images[2..3].each_with_index do |path, idx|
expect(client).to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: "id_#{idx + 2}")
expect(client).to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
end

uploader = Supply::Uploader.new
uploader.upload_screenshots(language)
end

it 'should delete remote screenshots that are no longer present locally' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "common-sha256-of-#{file}") }
local_images = %w[image1.png image2.png image3.png]
allow(Dir).to receive(:glob).and_return(local_images)

same_remote_images = local_images.map do |path|
Supply::ImageListing.new("id_#{path}", '_unused_', "common-sha256-of-#{path}", '_unused_')
end
extra_remote_image = Supply::ImageListing.new("id_extra", '_unused_', "common-sha256-of-extra-image", '_unused_')
remote_images = [same_remote_images[0], extra_remote_image, same_remote_images[1], same_remote_images[2]]

Supply::SCREENSHOT_TYPES.each do |screenshot_type|
allow(client).to receive(:fetch_images).with(image_type: screenshot_type, language: language).and_return(remote_images)
same_remote_images.each do |image|
expect(client).not_to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: image.id)
end
expect(client).to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: extra_remote_image.id)
local_images.each do |path|
expect(client).not_to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
end

uploader = Supply::Uploader.new
uploader.upload_screenshots(language)
end

it 'should delete screenshots that are out of order and re-upload them in the correct order' do
allow(Digest::SHA256).to receive(:file) { |file| instance_double(Digest::SHA256, hexdigest: "sha256-of-#{file}") }
local_images = %w[image0.png image1.png image2.png image4.png image3.png image5.png image6.png] # those will be sorted after Dir.glob
allow(Dir).to receive(:glob).and_return(local_images)

# Record the mocked deletions and uploads in list of remote images to check the final state at the end
final_remote_images_ids = {}
allow(client).to receive(:clear_screenshot) do |**args|
image_type = args[:image_id].split('_')[1]
final_remote_images_ids[image_type].delete(args[:image_id])
end
allow(client).to receive(:upload_image) do |**args|
path = File.basename(args[:image_path])
image_type = args[:image_type]
final_remote_images_ids[image_type] << "new-id_#{image_type}_#{path}"
end

Supply::SCREENSHOT_TYPES.each do |screenshot_type|
remote_images = local_images.map do |path|
Supply::ImageListing.new("id_#{screenshot_type}_#{path}", '_unused_', "sha256-of-#{path}", '_unused_')
end # remote images will be in order 0124356 though
allow(client).to receive(:fetch_images).with(image_type: screenshot_type, language: language).and_return(remote_images)

final_remote_images_ids[screenshot_type] = remote_images.map(&:id)

# We should skip image0, image1, image2 from remote as they are the same as the first local images,
# But also skip image3 (which was in-between 2 and 3 in remote listing, but is still present in local images)
# While deleting image4 (because it was in-between image2 and image3 in the `remote_images`, so out of order)
# And finally deleting image5 and image6, before re-uploading image4, image5 and image6 in the right order
local_images.sort[0..3].each do |path|
expect(client).not_to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: "id_#{screenshot_type}_#{path}")
expect(client).not_to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
local_images.sort[4..6].each do |path|
expect(client).to receive(:clear_screenshot).with(image_type: screenshot_type, language: language, image_id: "id_#{screenshot_type}_#{path}")
expect(client).to receive(:upload_image).with(image_path: File.expand_path(path), image_type: screenshot_type, language: language)
end
end

uploader = Supply::Uploader.new
uploader.upload_screenshots(language)

# Check the final order of the remote images after the whole skip/delete/upload dance
Supply::SCREENSHOT_TYPES.each do |screenshot_type|
expected_final_images_ids = %W[
id_#{screenshot_type}_image0.png
id_#{screenshot_type}_image1.png
id_#{screenshot_type}_image2.png
id_#{screenshot_type}_image3.png
new-id_#{screenshot_type}_image4.png
new-id_#{screenshot_type}_image5.png
new-id_#{screenshot_type}_image6.png
]
expect(final_remote_images_ids[screenshot_type]).to eq(expected_final_images_ids)
end
end
end
end
end
end

0 comments on commit 60a1530

Please sign in to comment.