/* eslint no-param-reassign: "off" */ import $ from 'jquery'; import GfmAutoComplete from '~/gfm_auto_complete'; import 'vendor/jquery.caret'; import 'vendor/jquery.atwho'; describe('GfmAutoComplete', function() { const gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({ fetchData: () => {}, }); describe('DefaultOptions.sorter', function() { describe('assets loading', function() { beforeEach(function() { spyOn(GfmAutoComplete, 'isLoading').and.returnValue(true); this.atwhoInstance = { setting: {} }; this.items = []; this.sorterValue = gfmAutoCompleteCallbacks.sorter.call(this.atwhoInstance, '', this.items); }); it('should disable highlightFirst', function() { expect(this.atwhoInstance.setting.highlightFirst).toBe(false); }); it('should return the passed unfiltered items', function() { expect(this.sorterValue).toEqual(this.items); }); }); describe('assets finished loading', function() { beforeEach(function() { spyOn(GfmAutoComplete, 'isLoading').and.returnValue(false); spyOn($.fn.atwho.default.callbacks, 'sorter'); }); it('should enable highlightFirst if alwaysHighlightFirst is set', function() { const atwhoInstance = { setting: { alwaysHighlightFirst: true } }; gfmAutoCompleteCallbacks.sorter.call(atwhoInstance); expect(atwhoInstance.setting.highlightFirst).toBe(true); }); it('should enable highlightFirst if a query is present', function() { const atwhoInstance = { setting: {} }; gfmAutoCompleteCallbacks.sorter.call(atwhoInstance, 'query'); expect(atwhoInstance.setting.highlightFirst).toBe(true); }); it('should call the default atwho sorter', function() { const atwhoInstance = { setting: {} }; const query = 'query'; const items = []; const searchKey = 'searchKey'; gfmAutoCompleteCallbacks.sorter.call(atwhoInstance, query, items, searchKey); expect($.fn.atwho.default.callbacks.sorter).toHaveBeenCalledWith(query, items, searchKey); }); }); }); describe('DefaultOptions.beforeInsert', () => { const beforeInsert = (context, value) => gfmAutoCompleteCallbacks.beforeInsert.call(context, value); const atwhoInstance = { setting: { skipSpecialCharacterTest: false } }; it('should not quote if value only contains alphanumeric charecters', () => { expect(beforeInsert(atwhoInstance, '@user1')).toBe('@user1'); expect(beforeInsert(atwhoInstance, '~label1')).toBe('~label1'); }); it('should quote if value contains any non-alphanumeric characters', () => { expect(beforeInsert(atwhoInstance, '~label-20')).toBe('~"label\\-20"'); expect(beforeInsert(atwhoInstance, '~label 20')).toBe('~"label 20"'); }); it('should quote integer labels', () => { expect(beforeInsert(atwhoInstance, '~1234')).toBe('~"1234"'); }); it('should escape Markdown emphasis characters, except in the first character', () => { expect(beforeInsert(atwhoInstance, '@_group')).toEqual('@\\_group'); expect(beforeInsert(atwhoInstance, '~_bug')).toEqual('~\\_bug'); expect(beforeInsert(atwhoInstance, '~a `bug`')).toEqual('~"a \\`bug\\`"'); expect(beforeInsert(atwhoInstance, '~a ~bug')).toEqual('~"a \\~bug"'); expect(beforeInsert(atwhoInstance, '~a **bug')).toEqual('~"a \\*\\*bug"'); }); }); describe('DefaultOptions.matcher', function() { const defaultMatcher = (context, flag, subtext) => gfmAutoCompleteCallbacks.matcher.call(context, flag, subtext); const flagsUseDefaultMatcher = ['@', '#', '!', '~', '%', '$']; const otherFlags = ['/', ':']; const flags = flagsUseDefaultMatcher.concat(otherFlags); const flagsHash = flags.reduce((hash, el) => { hash[el] = null; return hash; }, {}); const atwhoInstance = { setting: {}, app: { controllers: flagsHash } }; const minLen = 1; const maxLen = 20; const argumentSize = [minLen, maxLen / 2, maxLen]; const allowedSymbols = [ '', 'a', 'n', 'z', 'A', 'Z', 'N', '0', '5', '9', 'А', 'а', 'Я', 'я', '.', "'", '+', '-', '_', ]; const jointAllowedSymbols = allowedSymbols.join(''); describe('should match regular symbols', () => { flagsUseDefaultMatcher.forEach(flag => { allowedSymbols.forEach(symbol => { argumentSize.forEach(size => { const query = new Array(size + 1).join(symbol); const subtext = flag + query; it(`matches argument "${flag}" with query "${subtext}"`, () => { expect(defaultMatcher(atwhoInstance, flag, subtext)).toBe(query); }); }); }); it(`matches combination of allowed symbols for flag "${flag}"`, () => { const subtext = flag + jointAllowedSymbols; expect(defaultMatcher(atwhoInstance, flag, subtext)).toBe(jointAllowedSymbols); }); }); }); describe('should not match special sequences', () => { const shouldNotBeFollowedBy = flags.concat(['\x00', '\x10', '\x3f', '\n', ' ']); const shouldNotBePrependedBy = ['`']; flagsUseDefaultMatcher.forEach(atSign => { shouldNotBeFollowedBy.forEach(followedSymbol => { const seq = atSign + followedSymbol; it(`should not match ${JSON.stringify(seq)}`, () => { expect(defaultMatcher(atwhoInstance, atSign, seq)).toBe(null); }); }); shouldNotBePrependedBy.forEach(prependedSymbol => { const seq = prependedSymbol + atSign; it(`should not match "${seq}"`, () => { expect(defaultMatcher(atwhoInstance, atSign, seq)).toBe(null); }); }); }); }); }); describe('isLoading', function() { it('should be true with loading data object item', function() { expect(GfmAutoComplete.isLoading({ name: 'loading' })).toBe(true); }); it('should be true with loading data array', function() { expect(GfmAutoComplete.isLoading(['loading'])).toBe(true); }); it('should be true with loading data object array', function() { expect(GfmAutoComplete.isLoading([{ name: 'loading' }])).toBe(true); }); it('should be false with actual array data', function() { expect( GfmAutoComplete.isLoading([{ title: 'Foo' }, { title: 'Bar' }, { title: 'Qux' }]), ).toBe(false); }); it('should be false with actual data item', function() { expect(GfmAutoComplete.isLoading({ title: 'Foo' })).toBe(false); }); }); });