60 行
2.0 KiB
Ruby
60 行
2.0 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe PostBulkCreator do
|
|
it 'limits workers to two and keeps failures in their request slots' do
|
|
actor = instance_double(User, id: 123)
|
|
allow(User).to receive(:find).with(123) {
|
|
instance_double(User, id: 123)
|
|
}
|
|
mutex = Mutex.new
|
|
active = 0
|
|
maximum_active = 0
|
|
|
|
allow(PostCreatePreflight).to receive(:new) do |attributes:, **|
|
|
preflight = instance_double(PostCreatePreflight)
|
|
allow(preflight).to receive(:run) do
|
|
mutex.synchronize do
|
|
active += 1
|
|
maximum_active = [maximum_active, active].max
|
|
end
|
|
sleep 0.02
|
|
mutex.synchronize { active -= 1 }
|
|
attributes.symbolize_keys.merge(
|
|
existing_post_id: nil,
|
|
field_warnings: { },
|
|
base_warnings: [])
|
|
end
|
|
preflight
|
|
end
|
|
allow(PostCreator).to receive(:new) do |attributes:, **|
|
|
creator = instance_double(PostCreator)
|
|
if attributes[:title] == 'broken'
|
|
allow(creator).to receive(:create!).and_raise(StandardError, 'broken')
|
|
else
|
|
post = instance_double(Post, id: attributes[:title].delete_prefix('post ').to_i)
|
|
allow(creator).to receive(:create!).and_return(post)
|
|
end
|
|
creator
|
|
end
|
|
posts = [
|
|
{ 'title' => 'post 1', 'url' => 'https://example.com/1' },
|
|
{ 'title' => 'broken', 'url' => 'https://example.com/2' },
|
|
{ 'title' => 'post 3', 'url' => 'https://example.com/3' },
|
|
{ 'title' => 'post 4', 'url' => 'https://example.com/4' }]
|
|
|
|
results = described_class.new(
|
|
actor:,
|
|
posts:,
|
|
thumbnails: { }).run.fetch(:results)
|
|
|
|
expect(maximum_active).to eq(2)
|
|
expect(results.length).to eq(posts.length)
|
|
expect(results.map { _1[:status] }).to eq(
|
|
['created', 'failed', 'created', 'created'])
|
|
expect(results[0].dig(:post, :id)).to eq(1)
|
|
expect(results[1]).to include(status: 'failed', recoverable: false)
|
|
expect(results[2].dig(:post, :id)).to eq(3)
|
|
expect(results[3].dig(:post, :id)).to eq(4)
|
|
end
|
|
end
|