Commit 7dc1dfeb authored by Alex Kalderimis's avatar Alex Kalderimis

General model and finder improvements

* Add Design.visible_in? method and specs

  This tests that a design is visible at a particular version.

* Improve Designs finder

  Finders should return none when given empty arrays

  Adds missing parameter to documentation comment on DesignsFinder
parent f4e1cf6d
......@@ -6,6 +6,7 @@ module DesignManagement
# Params:
# ids: integer[]
# filenames: string[]
# visible_at_version: ?version
def initialize(issue, current_user, params = {})
@issue = issue
......@@ -39,13 +40,15 @@ module DesignManagement
end
def by_filename(items)
return items unless params[:filenames].present?
return items if params[:filenames].nil?
return ::DesignManagement::Design.none if params[:filenames].empty?
items.with_filename(params[:filenames])
end
def by_id(items)
return items unless params[:ids].present?
return items if params[:ids].nil?
return ::DesignManagement::Design.none if params[:ids].empty?
items.id_in(params[:ids])
end
......
......@@ -78,6 +78,19 @@ module DesignManagement
most_recent_action&.deletion?
end
# A design is visible_in? a version if:
# * it was created before that version
# * the most recent action before the version was not a deletion
def visible_in?(version)
map = strong_memoize(:visible_in) do
Hash.new do |h, k|
h[k] = self.class.visible_at_version(k).where(id: id).exists?
end
end
map[version]
end
def most_recent_action
strong_memoize(:most_recent_action) { actions.ordered.last }
end
......@@ -181,7 +194,7 @@ module DesignManagement
def clear_version_cache
[versions, actions].each(&:reset)
[:new_design, :diff_refs, :head_sha, :most_recent_action].each do |key|
%i[new_design diff_refs head_sha visible_in most_recent_action].each do |key|
clear_memoization(key)
end
end
......
......@@ -54,6 +54,20 @@ describe DesignManagement::DesignsFinder do
it { is_expected.to eq([design2]) }
end
context 'when passed empty array' do
context 'for filenames' do
let(:params) { { filenames: [] } }
it { is_expected.to be_empty }
end
context "for ids" do
let(:params) { { ids: [] } }
it { is_expected.to be_empty }
end
end
describe 'returning designs that existed at a particular given version' do
let(:all_versions) { issue.design_collection.versions.ordered }
let(:first_version) { all_versions.last }
......
......@@ -179,6 +179,57 @@ describe DesignManagement::Design do
end
end
describe '#visible_in?' do
set(:issue) { create(:issue) }
# It is expensive to re-create complex histories, so we do it once, and then
# assert that we can establish visibility at any given version.
it 'tells us when a design is visible' do
expected = []
first_design = create(:design, :with_versions, issue: issue, versions_count: 1)
prior_to_creation = first_design.versions.first
expected << [prior_to_creation, :not_created_yet, false]
v = modify_designs(first_design)
expected << [v, :not_created_yet, false]
design = create(:design, :with_versions, issue: issue, versions_count: 1)
created_in = design.versions.first
expected << [created_in, :created, true]
# The future state should not affect the result for any state, so we
# ensure that most states have a long future as well as a rich past
2.times do
v = modify_designs(first_design)
expected << [v, :unaffected_visible, true]
v = modify_designs(design)
expected << [v, :modified, true]
v = modify_designs(first_design)
expected << [v, :unaffected_visible, true]
v = delete_designs(design)
expected << [v, :deleted, false]
v = modify_designs(first_design)
expected << [v, :unaffected_nv, false]
v = restore_designs(design)
expected << [v, :restored, true]
end
delete_designs(design) # ensure visibility is not corelated with current state
got = expected.map do |(v, sym, _)|
[v, sym, design.visible_in?(v)]
end
expect(got).to eq(expected)
end
end
describe '#to_ability_name' do
it { expect(described_class.new.to_ability_name).to eq('design') }
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment