|
214 | 214 | end |
215 | 215 | end |
216 | 216 |
|
217 | | - context 'with read/write roles' do |
218 | | - # Skip for older Rails versions that don't support connected_to with roles |
219 | | - next unless ActiveRecord::Base.respond_to?(:connected_to) && ActiveRecord.version >= Gem::Version.new('7.1') |
| 217 | + if ActiveRecord::Base.respond_to?(:connected_to) && ActiveRecord.version >= Gem::Version.new('7.1') |
| 218 | + context 'with read/write roles' do |
| 219 | + # Skip for older Rails versions that don't support connected_to with roles |
220 | 220 |
|
221 | | - # Skip for SQLite as it doesn't handle role-based connections well with :memory: databases |
222 | | - next if config["adapter"] == "sqlite3" |
223 | 221 |
|
224 | | - let(:abstract_class) do |
225 | | - # Create a named abstract class (Rails requires names for connects_to) |
226 | | - klass = Class.new(ActiveRecord::Base) do |
227 | | - self.abstract_class = true |
228 | | - end |
229 | | - stub_const('TestApplicationRecord', klass) |
| 222 | + # Skip for SQLite as it doesn't handle role-based connections well with :memory: databases |
| 223 | + next if config["adapter"] == "sqlite3" |
230 | 224 |
|
231 | | - # Now configure connects_to with the same database for both roles |
232 | | - # In production, these would be different (primary/replica) |
233 | | - klass.connects_to database: { |
234 | | - writing: config, |
235 | | - reading: config |
236 | | - } |
| 225 | + let(:abstract_class) do |
| 226 | + # Create a named abstract class (Rails requires names for connects_to) |
| 227 | + klass = Class.new(ActiveRecord::Base) do |
| 228 | + self.abstract_class = true |
| 229 | + end |
| 230 | + stub_const('TestApplicationRecord', klass) |
237 | 231 |
|
238 | | - klass |
239 | | - end |
| 232 | + # Now configure connects_to with the same database for both roles |
| 233 | + # In production, these would be different (primary/replica) |
| 234 | + klass.connects_to database: { |
| 235 | + writing: config, |
| 236 | + reading: config |
| 237 | + } |
240 | 238 |
|
241 | | - after do |
242 | | - # Disconnect role-based connections to avoid interfering with database cleanup |
243 | | - clear_all_connections! |
244 | | - end |
| 239 | + klass |
| 240 | + end |
245 | 241 |
|
246 | | - let(:feature_class) do |
247 | | - klass = Class.new(abstract_class) do |
248 | | - self.table_name = 'flipper_features' |
249 | | - validates :key, presence: true |
| 242 | + after do |
| 243 | + # Disconnect role-based connections to avoid interfering with database cleanup |
| 244 | + clear_all_connections! |
250 | 245 | end |
251 | | - stub_const('TestFeature', klass) |
252 | | - klass |
253 | | - end |
254 | 246 |
|
255 | | - let(:gate_class) do |
256 | | - klass = Class.new(abstract_class) do |
257 | | - self.table_name = 'flipper_gates' |
| 247 | + let(:feature_class) do |
| 248 | + klass = Class.new(abstract_class) do |
| 249 | + self.table_name = 'flipper_features' |
| 250 | + validates :key, presence: true |
| 251 | + end |
| 252 | + stub_const('TestFeature', klass) |
| 253 | + klass |
258 | 254 | end |
259 | | - stub_const('TestGate', klass) |
260 | | - klass |
261 | | - end |
262 | 255 |
|
263 | | - let(:adapter_with_roles) do |
264 | | - described_class.new( |
265 | | - feature_class: feature_class, |
266 | | - gate_class: gate_class |
267 | | - ) |
268 | | - end |
| 256 | + let(:gate_class) do |
| 257 | + klass = Class.new(abstract_class) do |
| 258 | + self.table_name = 'flipper_gates' |
| 259 | + end |
| 260 | + stub_const('TestGate', klass) |
| 261 | + klass |
| 262 | + end |
269 | 263 |
|
270 | | - it 'can perform write operations when forced to reading role' do |
271 | | - abstract_class.connected_to(role: :reading) do |
272 | | - flipper = Flipper.new(adapter_with_roles) |
273 | | - |
274 | | - feature = flipper[:test_feature] |
275 | | - expect { feature.enable }.not_to raise_error |
276 | | - expect(feature.enabled?).to be(true) |
277 | | - expect { feature.disable }.not_to raise_error |
278 | | - expect(feature.enabled?).to be(false) |
279 | | - |
280 | | - feature = flipper[:actor_test] |
281 | | - actor = Struct.new(:flipper_id).new(123) |
282 | | - expect { feature.enable_actor(actor) }.not_to raise_error |
283 | | - expect(feature.enabled?(actor)).to be(true) |
284 | | - expect { feature.disable_actor(actor) }.not_to raise_error |
285 | | - expect(feature.enabled?(actor)).to be(false) |
286 | | - |
287 | | - feature = flipper[:gate_test] |
288 | | - expect { feature.enable_percentage_of_time(50) }.not_to raise_error |
289 | | - expect { feature.disable_percentage_of_time }.not_to raise_error |
290 | | - feature.enable |
291 | | - expect { feature.remove }.not_to raise_error |
292 | | - |
293 | | - feature = flipper[:expression_test] |
294 | | - expression = Flipper.property(:plan).eq("premium") |
295 | | - expect { feature.enable_expression(expression) }.not_to raise_error |
296 | | - expect(feature.expression).to eq(expression) |
297 | | - expect { feature.disable_expression }.not_to raise_error |
298 | | - expect(feature.expression).to be_nil |
| 264 | + let(:adapter_with_roles) do |
| 265 | + described_class.new( |
| 266 | + feature_class: feature_class, |
| 267 | + gate_class: gate_class |
| 268 | + ) |
299 | 269 | end |
300 | | - end |
301 | 270 |
|
302 | | - it 'does not hold onto connections during write operations' do |
303 | | - clear_active_connections! |
| 271 | + it 'can perform write operations when forced to reading role' do |
| 272 | + abstract_class.connected_to(role: :reading) do |
| 273 | + flipper = Flipper.new(adapter_with_roles) |
| 274 | + |
| 275 | + feature = flipper[:test_feature] |
| 276 | + expect { feature.enable }.not_to raise_error |
| 277 | + expect(feature.enabled?).to be(true) |
| 278 | + expect { feature.disable }.not_to raise_error |
| 279 | + expect(feature.enabled?).to be(false) |
| 280 | + |
| 281 | + feature = flipper[:actor_test] |
| 282 | + actor = Struct.new(:flipper_id).new(123) |
| 283 | + expect { feature.enable_actor(actor) }.not_to raise_error |
| 284 | + expect(feature.enabled?(actor)).to be(true) |
| 285 | + expect { feature.disable_actor(actor) }.not_to raise_error |
| 286 | + expect(feature.enabled?(actor)).to be(false) |
| 287 | + |
| 288 | + feature = flipper[:gate_test] |
| 289 | + expect { feature.enable_percentage_of_time(50) }.not_to raise_error |
| 290 | + expect { feature.disable_percentage_of_time }.not_to raise_error |
| 291 | + feature.enable |
| 292 | + expect { feature.remove }.not_to raise_error |
| 293 | + |
| 294 | + feature = flipper[:expression_test] |
| 295 | + expression = Flipper.property(:plan).eq("premium") |
| 296 | + expect { feature.enable_expression(expression) }.not_to raise_error |
| 297 | + expect(feature.expression).to eq(expression) |
| 298 | + expect { feature.disable_expression }.not_to raise_error |
| 299 | + expect(feature.expression).to be_nil |
| 300 | + end |
| 301 | + end |
304 | 302 |
|
305 | | - abstract_class.connected_to(role: :reading) do |
306 | | - flipper = Flipper.new(adapter_with_roles) |
307 | | - feature = flipper[:connection_test] |
| 303 | + it 'does not hold onto connections during write operations' do |
| 304 | + clear_active_connections! |
308 | 305 |
|
309 | | - feature.enable |
310 | | - expect(active_connections?).to be(false) |
| 306 | + abstract_class.connected_to(role: :reading) do |
| 307 | + flipper = Flipper.new(adapter_with_roles) |
| 308 | + feature = flipper[:connection_test] |
| 309 | + |
| 310 | + feature.enable |
| 311 | + expect(active_connections?).to be(false) |
| 312 | + end |
311 | 313 | end |
312 | 314 | end |
313 | 315 | end |
|
0 commit comments