@ -1,21 +1,22 @@
# frozen_string_literal: true
require 'rails_helper'
require 'rails_helper'
RSpec . describe Tag , type : :model do
RSpec . describe Tag do
describe 'validations' do
describe 'validations' do
it 'invalid with #' do
it 'invalid with #' do
expect ( Tag . new ( name : '#hello_world' ) ) . to_ not be_valid
expect ( described_class . new ( name : '#hello_world' ) ) . not_to be_valid
end
end
it 'invalid with .' do
it 'invalid with .' do
expect ( Tag . new ( name : '.abcdef123' ) ) . to_ not be_valid
expect ( described_class . new ( name : '.abcdef123' ) ) . not_to be_valid
end
end
it 'invalid with spaces' do
it 'invalid with spaces' do
expect ( Tag . new ( name : 'hello world' ) ) . to_ not be_valid
expect ( described_class . new ( name : 'hello world' ) ) . not_to be_valid
end
end
it 'valid with a e s t h e t i c ' do
it 'valid with a e s t h e t i c ' do
expect ( Tag . new ( name : 'a e s t h e t i c ' ) ) . to be_valid
expect ( described_class . new ( name : 'a e s t h e t i c ' ) ) . to be_valid
end
end
end
end
@ -62,6 +63,10 @@ RSpec.describe Tag, type: :model do
expect ( subject . match ( 'hello #one·two·three' ) . to_s ) . to eq ' #one·two·three'
expect ( subject . match ( 'hello #one·two·three' ) . to_s ) . to eq ' #one·two·three'
end
end
it 'matches ・unicode in ぼっち・ざ・ろっく correctly' do
expect ( subject . match ( 'testing #ぼっち・ざ・ろっく' ) . to_s ) . to eq ' #ぼっち・ざ・ろっく'
end
it 'matches ZWNJ' do
it 'matches ZWNJ' do
expect ( subject . match ( 'just add #نرمافزار and' ) . to_s ) . to eq ' #نرمافزار'
expect ( subject . match ( 'just add #نرمافزار and' ) . to_s ) . to eq ' #نرمافزار'
end
end
@ -89,44 +94,46 @@ RSpec.describe Tag, type: :model do
describe '.find_normalized' do
describe '.find_normalized' do
it 'returns tag for a multibyte case-insensitive name' do
it 'returns tag for a multibyte case-insensitive name' do
upcase_string = 'abcABCa b c A B C やゆよ'
upcase_string = 'abcABCa b c A B C やゆよ'
downcase_string = 'abcabca b c a b c やゆよ' ;
downcase_string = 'abcabca b c a b c やゆよ'
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
expect ( Tag . find_normalized ( upcase_string ) ) . to eq tag
expect ( described_class . find_normalized ( upcase_string ) ) . to eq tag
end
end
end
end
describe '.matches_name' do
describe '.matches_name' do
it 'returns tags for multibyte case-insensitive names' do
it 'returns tags for multibyte case-insensitive names' do
upcase_string = 'abcABCa b c A B C やゆよ'
upcase_string = 'abcABCa b c A B C やゆよ'
downcase_string = 'abcabca b c a b c やゆよ' ;
downcase_string = 'abcabca b c a b c やゆよ'
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
expect ( Tag . matches_name ( upcase_string ) ) . to eq [ tag ]
expect ( described_class . matches_name ( upcase_string ) ) . to eq [ tag ]
end
end
it 'uses the LIKE operator' do
it 'uses the LIKE operator' do
expect ( Tag . matches_name ( '100%abc' ) . to_sql ) . to eq %q[ SELECT "tags".* FROM "tags" WHERE LOWER("tags"."name") LIKE LOWER('100abc%') ]
result = %q[ SELECT "tags".* FROM "tags" WHERE LOWER("tags"."name") LIKE LOWER('100abc%') ]
expect ( described_class . matches_name ( '100%abc' ) . to_sql ) . to eq result
end
end
end
end
describe '.matching_name' do
describe '.matching_name' do
it 'returns tags for multibyte case-insensitive names' do
it 'returns tags for multibyte case-insensitive names' do
upcase_string = 'abcABCa b c A B C やゆよ'
upcase_string = 'abcABCa b c A B C やゆよ'
downcase_string = 'abcabca b c a b c やゆよ' ;
downcase_string = 'abcabca b c a b c やゆよ'
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
tag = Fabricate ( :tag , name : HashtagNormalizer . new . normalize ( downcase_string ) )
expect ( Tag . matching_name ( upcase_string ) ) . to eq [ tag ]
expect ( described_class . matching_name ( upcase_string ) ) . to eq [ tag ]
end
end
end
end
describe '.find_or_create_by_names' do
describe '.find_or_create_by_names' do
let ( :upcase_string ) { 'abcABCa b c A B C やゆよ' }
let ( :downcase_string ) { 'abcabca b c a b c やゆよ' }
it 'runs a passed block once per tag regardless of duplicates' do
it 'runs a passed block once per tag regardless of duplicates' do
upcase_string = 'abcABCa b c A B C やゆよ'
downcase_string = 'abcabca b c a b c やゆよ' ;
count = 0
count = 0
Tag . find_or_create_by_names ( [ upcase_string , downcase_string ] ) do | tag|
described_class . find_or_create_by_names ( [ upcase_string , downcase_string ] ) do | _ tag|
count += 1
count += 1
end
end
@ -136,28 +143,28 @@ RSpec.describe Tag, type: :model do
describe '.search_for' do
describe '.search_for' do
it 'finds tag records with matching names' do
it 'finds tag records with matching names' do
tag = Fabricate ( :tag , name : " match " )
tag = Fabricate ( :tag , name : 'match' )
_miss_tag = Fabricate ( :tag , name : " miss " )
_miss_tag = Fabricate ( :tag , name : 'miss' )
results = Tag . search_for ( " match " )
results = described_class . search_for ( 'match' )
expect ( results ) . to eq [ tag ]
expect ( results ) . to eq [ tag ]
end
end
it 'finds tag records in case insensitive' do
it 'finds tag records in case insensitive' do
tag = Fabricate ( :tag , name : " MATCH " )
tag = Fabricate ( :tag , name : 'MATCH' )
_miss_tag = Fabricate ( :tag , name : " miss " )
_miss_tag = Fabricate ( :tag , name : 'miss' )
results = Tag . search_for ( " match " )
results = described_class . search_for ( 'match' )
expect ( results ) . to eq [ tag ]
expect ( results ) . to eq [ tag ]
end
end
it 'finds the exact matching tag as the first item' do
it 'finds the exact matching tag as the first item' do
similar_tag = Fabricate ( :tag , name : " matchlater " , reviewed_at : Time . now . utc )
similar_tag = Fabricate ( :tag , name : 'matchlater' , reviewed_at : Time . now . utc )
tag = Fabricate ( :tag , name : " match " , reviewed_at : Time . now . utc )
tag = Fabricate ( :tag , name : 'match' , reviewed_at : Time . now . utc )
results = Tag . search_for ( " match " )
results = described_class . search_for ( 'match' )
expect ( results ) . to eq [ tag , similar_tag ]
expect ( results ) . to eq [ tag , similar_tag ]
end
end