1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
# frozen_string_literal: true
require 'spec_helper'
RSpec.shared_examples 'Debian Distribution' do |factory, container, can_freeze|
let_it_be(:distribution_with_suite, freeze: can_freeze) { create(factory, suite: 'mysuite') }
let_it_be(:distribution_with_same_container, freeze: can_freeze) { create(factory, container: distribution_with_suite.container ) }
let_it_be(:distribution_with_same_codename, freeze: can_freeze) { create(factory, codename: distribution_with_suite.codename ) }
let_it_be(:distribution_with_same_suite, freeze: can_freeze) { create(factory, suite: distribution_with_suite.suite ) }
let_it_be(:distribution_with_codename_and_suite_flipped, freeze: can_freeze) { create(factory, codename: distribution_with_suite.suite, suite: distribution_with_suite.codename) }
let_it_be_with_refind(:distribution) { create(factory, container: distribution_with_suite.container ) }
subject { distribution }
describe 'relationships' do
it { is_expected.to belong_to(container) }
it { is_expected.to belong_to(:creator).class_name('User') }
it { is_expected.to have_one(:key).class_name("Packages::Debian::#{container.capitalize}DistributionKey").with_foreign_key(:distribution_id).inverse_of(:distribution) }
it { is_expected.to have_many(:components).class_name("Packages::Debian::#{container.capitalize}Component").inverse_of(:distribution) }
it { is_expected.to have_many(:architectures).class_name("Packages::Debian::#{container.capitalize}Architecture").inverse_of(:distribution) }
end
describe 'validations' do
describe "##{container}" do
it { is_expected.to validate_presence_of(container) }
end
describe "#creator" do
it { is_expected.not_to validate_presence_of(:creator) }
end
describe '#codename' do
it { is_expected.to validate_presence_of(:codename) }
it { is_expected.to allow_value('buster').for(:codename) }
it { is_expected.to allow_value('buster-updates').for(:codename) }
it { is_expected.to allow_value('Debian10.5').for(:codename) }
it { is_expected.not_to allow_value('jessie/updates').for(:codename) }
it { is_expected.not_to allow_value('hé').for(:codename) }
end
describe '#suite' do
it { is_expected.to allow_value(nil).for(:suite) }
it { is_expected.to allow_value('testing').for(:suite) }
it { is_expected.not_to allow_value('hé').for(:suite) }
end
describe '#unique_debian_suite_and_codename' do
using RSpec::Parameterized::TableSyntax
where(:with_existing_suite, :suite, :codename, :errors) do
false | nil | :keep | nil
false | 'testing' | :keep | nil
false | nil | :codename | ["Codename has already been taken"]
false | :codename | :keep | ["Suite has already been taken as Codename"]
false | :codename | :codename | ["Codename has already been taken", "Suite has already been taken as Codename"]
true | nil | :keep | nil
true | 'testing' | :keep | nil
true | nil | :codename | ["Codename has already been taken"]
true | :codename | :keep | ["Suite has already been taken as Codename"]
true | :codename | :codename | ["Codename has already been taken", "Suite has already been taken as Codename"]
true | nil | :suite | ["Codename has already been taken as Suite"]
true | :suite | :keep | ["Suite has already been taken"]
true | :suite | :suite | ["Suite has already been taken", "Codename has already been taken as Suite"]
end
with_them do
context factory do
let(:new_distribution) { build(factory, container: distribution.container) }
before do
distribution.update_column(:suite, 'suite-' + distribution.codename) if with_existing_suite
if suite.is_a?(Symbol)
new_distribution.suite = distribution.send suite unless suite == :keep
else
new_distribution.suite = suite
end
if codename.is_a?(Symbol)
new_distribution.codename = distribution.send codename unless codename == :keep
else
new_distribution.codename = codename
end
end
it do
if errors
expect(new_distribution).not_to be_valid
expect(new_distribution.errors.to_a).to eq(errors)
else
expect(new_distribution).to be_valid
end
end
end
end
end
describe '#origin' do
it { is_expected.to allow_value(nil).for(:origin) }
it { is_expected.to allow_value('Debian').for(:origin) }
it { is_expected.not_to allow_value('hé').for(:origin) }
end
describe '#label' do
it { is_expected.to allow_value(nil).for(:label) }
it { is_expected.to allow_value('Debian').for(:label) }
it { is_expected.not_to allow_value('hé').for(:label) }
end
describe '#version' do
it { is_expected.to allow_value(nil).for(:version) }
it { is_expected.to allow_value('10.6').for(:version) }
it { is_expected.not_to allow_value('hé').for(:version) }
end
describe '#description' do
it { is_expected.to allow_value(nil).for(:description) }
it { is_expected.to allow_value('Debian 10.6 Released 26 September 2020').for(:description) }
it { is_expected.to allow_value('Hé !').for(:description) }
end
describe '#valid_time_duration_seconds' do
it { is_expected.to allow_value(nil).for(:valid_time_duration_seconds) }
it { is_expected.to allow_value(24.hours.to_i).for(:valid_time_duration_seconds) }
it { is_expected.not_to allow_value(12.hours.to_i).for(:valid_time_duration_seconds) }
end
describe '#file' do
it { is_expected.not_to validate_presence_of(:file) }
end
describe '#file_store' do
it { is_expected.to validate_presence_of(:file_store) }
end
describe '#file_signature' do
it { is_expected.not_to validate_absence_of(:file_signature) }
end
describe '#signed_file' do
it { is_expected.not_to validate_presence_of(:signed_file) }
end
describe '#signed_file_store' do
it { is_expected.to validate_presence_of(:signed_file_store) }
end
end
describe 'scopes' do
describe '.with_container' do
subject { described_class.with_container(distribution_with_suite.container) }
it 'does not return other distributions' do
expect(subject).to match_array([distribution_with_suite, distribution, distribution_with_same_container])
end
end
describe '.with_codename' do
subject { described_class.with_codename(distribution_with_suite.codename) }
it 'does not return other distributions' do
expect(subject).to match_array([distribution_with_suite, distribution_with_same_codename])
end
end
describe '.with_suite' do
subject { described_class.with_suite(distribution_with_suite.suite) }
it 'does not return other distributions' do
expect(subject).to match_array([distribution_with_suite, distribution_with_same_suite])
end
end
describe '.with_codename_or_suite' do
describe 'passing codename' do
subject { described_class.with_codename_or_suite(distribution_with_suite.codename) }
it 'does not return other distributions' do
expect(subject.to_a).to contain_exactly(distribution_with_suite, distribution_with_same_codename, distribution_with_codename_and_suite_flipped)
end
end
describe 'passing suite' do
subject { described_class.with_codename_or_suite(distribution_with_suite.suite) }
it 'does not return other distributions' do
expect(subject.to_a).to contain_exactly(distribution_with_suite, distribution_with_same_suite, distribution_with_codename_and_suite_flipped)
end
end
end
end
if container == :project
describe 'project distribution specifics' do
describe 'relationships' do
it { is_expected.to have_many(:publications).class_name('Packages::Debian::Publication').inverse_of(:distribution).with_foreign_key(:distribution_id) }
it { is_expected.to have_many(:packages).class_name('Packages::Package').through(:publications) }
end
end
else
describe 'group distribution specifics' do
let_it_be(:public_project) { create(:project, :public, group: distribution_with_suite.container)}
let_it_be(:public_distribution_with_same_codename) { create(:debian_project_distribution, container: public_project, codename: distribution_with_suite.codename) }
let_it_be(:public_package_with_same_codename) { create(:debian_package, project: public_project, published_in: public_distribution_with_same_codename)}
let_it_be(:public_distribution_with_same_suite) { create(:debian_project_distribution, container: public_project, suite: distribution_with_suite.suite) }
let_it_be(:public_package_with_same_suite) { create(:debian_package, project: public_project, published_in: public_distribution_with_same_suite)}
let_it_be(:private_project) { create(:project, :private, group: distribution_with_suite.container)}
let_it_be(:private_distribution_with_same_codename) { create(:debian_project_distribution, container: private_project, codename: distribution_with_suite.codename) }
let_it_be(:private_package_with_same_codename) { create(:debian_package, project: private_project, published_in: private_distribution_with_same_codename)}
let_it_be(:private_distribution_with_same_suite) { create(:debian_project_distribution, container: private_project, suite: distribution_with_suite.suite) }
let_it_be(:private_package_with_same_suite) { create(:debian_package, project: private_project, published_in: private_distribution_with_same_codename)}
describe '#packages' do
subject { distribution_with_suite.packages }
it 'returns only public packages with same codename' do
expect(subject.to_a).to contain_exactly(public_package_with_same_codename)
end
end
describe '#package_files' do
subject { distribution_with_suite.package_files }
it 'returns only files from public packages with same codename' do
expect(subject.to_a).to contain_exactly(*public_package_with_same_codename.package_files)
end
context 'with pending destruction package files' do
let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: public_package_with_same_codename) }
it 'does not return them' do
expect(subject.to_a).not_to include(package_file_pending_destruction)
end
end
end
end
end
end
|