From 1190d0ab3dc7a3025bf55b666f34d1a0b51a8d89 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 7 Oct 2015 14:03:18 +0200 Subject: Added concern for case-insensitive WHERE queries On PostgreSQL these queries use LOWER(...) to compare columns and values. For MySQL a regular WHERE is performed as MySQL is already case-insensitive. --- spec/models/concerns/case_sensitivity_spec.rb | 176 ++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 spec/models/concerns/case_sensitivity_spec.rb (limited to 'spec') diff --git a/spec/models/concerns/case_sensitivity_spec.rb b/spec/models/concerns/case_sensitivity_spec.rb new file mode 100644 index 00000000000..8b9f50aada7 --- /dev/null +++ b/spec/models/concerns/case_sensitivity_spec.rb @@ -0,0 +1,176 @@ +require 'spec_helper' + +describe CaseSensitivity do + describe '.case_insensitive_where' do + let(:connection) { ActiveRecord::Base.connection } + let(:model) { Class.new { include CaseSensitivity } } + + describe 'using PostgreSQL' do + describe 'with a single column/value pair' do + it 'returns the criteria for a column and a value' do + criteria = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('"foo"') + + expect(model).to receive(:where). + with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). + and_return(criteria) + + expect(model.case_insensitive_where(foo: 'bar')).to eq(criteria) + end + + it 'returns the criteria for a column with a table, and a value' do + criteria = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('"foo"."bar"') + + expect(model).to receive(:where). + with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). + and_return(criteria) + + expect(model.case_insensitive_where('foo.bar': 'bar')).to eq(criteria) + end + end + + describe 'with multiple column/value pairs' do + it 'returns the criteria for a column and a value' do + initial = double(:criteria) + final = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('"foo"') + + expect(connection).to receive(:quote_table_name). + with(:bar). + and_return('"bar"') + + expect(model).to receive(:where). + with(%q{LOWER("foo") = LOWER(:value)}, value: 'bar'). + and_return(initial) + + expect(initial).to receive(:where). + with(%q{LOWER("bar") = LOWER(:value)}, value: 'baz'). + and_return(final) + + got = model.case_insensitive_where(foo: 'bar', bar: 'baz') + + expect(got).to eq(final) + end + + it 'returns the criteria for a column with a table, and a value' do + initial = double(:criteria) + final = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('"foo"."bar"') + + expect(connection).to receive(:quote_table_name). + with(:'foo.baz'). + and_return('"foo"."baz"') + + expect(model).to receive(:where). + with(%q{LOWER("foo"."bar") = LOWER(:value)}, value: 'bar'). + and_return(initial) + + expect(initial).to receive(:where). + with(%q{LOWER("foo"."baz") = LOWER(:value)}, value: 'baz'). + and_return(final) + + got = model.case_insensitive_where('foo.bar': 'bar', 'foo.baz': 'baz') + + expect(got).to eq(final) + end + end + end + + describe 'using MySQL' do + describe 'with a single column/value pair' do + it 'returns the criteria for a column and a value' do + criteria = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('`foo`') + + expect(model).to receive(:where). + with(%q{LOWER(`foo`) = LOWER(:value)}, value: 'bar'). + and_return(criteria) + + expect(model.case_insensitive_where(foo: 'bar')).to eq(criteria) + end + + it 'returns the criteria for a column with a table, and a value' do + criteria = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('`foo`.`bar`') + + expect(model).to receive(:where). + with(%q{LOWER(`foo`.`bar`) = LOWER(:value)}, value: 'bar'). + and_return(criteria) + + expect(model.case_insensitive_where('foo.bar': 'bar')).to eq(criteria) + end + end + + describe 'with multiple column/value pairs' do + it 'returns the criteria for a column and a value' do + initial = double(:criteria) + final = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:foo). + and_return('`foo`') + + expect(connection).to receive(:quote_table_name). + with(:bar). + and_return('`bar`') + + expect(model).to receive(:where). + with(%q{LOWER(`foo`) = LOWER(:value)}, value: 'bar'). + and_return(initial) + + expect(initial).to receive(:where). + with(%q{LOWER(`bar`) = LOWER(:value)}, value: 'baz'). + and_return(final) + + got = model.case_insensitive_where(foo: 'bar', bar: 'baz') + + expect(got).to eq(final) + end + + it 'returns the criteria for a column with a table, and a value' do + initial = double(:criteria) + final = double(:criteria) + + expect(connection).to receive(:quote_table_name). + with(:'foo.bar'). + and_return('`foo`.`bar`') + + expect(connection).to receive(:quote_table_name). + with(:'foo.baz'). + and_return('`foo`.`baz`') + + expect(model).to receive(:where). + with(%q{LOWER(`foo`.`bar`) = LOWER(:value)}, value: 'bar'). + and_return(initial) + + expect(initial).to receive(:where). + with(%q{LOWER(`foo`.`baz`) = LOWER(:value)}, value: 'baz'). + and_return(final) + + got = model.case_insensitive_where('foo.bar': 'bar', 'foo.baz': 'baz') + + expect(got).to eq(final) + end + end + end + end +end -- cgit v1.2.1