496 lines
13 KiB
Ruby
496 lines
13 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# rubocop:disable Metrics/BlockLength
|
|
require 'spec_helper'
|
|
|
|
describe(Jekyll::Algolia) do
|
|
let(:configurator) { Jekyll::Algolia::Configurator }
|
|
let(:current) { Jekyll::Algolia }
|
|
let(:extractor) { Jekyll::Algolia::Extractor }
|
|
let(:logger) { Jekyll::Algolia::Logger }
|
|
let(:file_browser) { Jekyll::Algolia::FileBrowser }
|
|
let(:progress_bar) { Jekyll::Algolia::ProgressBar }
|
|
let(:hooks) { Jekyll::Algolia::Hooks }
|
|
let(:indexer) { Jekyll::Algolia::Indexer }
|
|
|
|
# Suppress Jekyll log about not having a config file
|
|
before do
|
|
allow(Jekyll.logger).to receive(:warn)
|
|
allow(logger).to receive(:log)
|
|
end
|
|
|
|
describe '.init' do
|
|
let(:config) { Jekyll.configuration }
|
|
|
|
context 'with valid Algolia credentials' do
|
|
subject { current.init(config) }
|
|
|
|
before do
|
|
allow(configurator)
|
|
.to receive(:assert_valid_credentials)
|
|
.and_return(true)
|
|
end
|
|
|
|
it 'should make the site accessible from the outside' do
|
|
expect(subject.site.config).to include(config)
|
|
end
|
|
it 'should check for deprecation warnings' do
|
|
expect(configurator).to receive(:warn_of_deprecated_options)
|
|
|
|
current.init(config)
|
|
end
|
|
it 'should register the custom link tag' do
|
|
expect(Liquid::Template)
|
|
.to receive(:register_tag)
|
|
.with('link', JekyllAlgoliaLink)
|
|
|
|
current.init(config)
|
|
end
|
|
end
|
|
|
|
context 'with invalid Algolia credentials' do
|
|
subject { -> { current.init(config) } }
|
|
before do
|
|
allow(configurator)
|
|
.to receive(:assert_valid_credentials)
|
|
.and_return(false)
|
|
end
|
|
|
|
it { is_expected.to raise_error SystemExit }
|
|
end
|
|
end
|
|
|
|
describe 'overriding Jekyll::Site#process' do
|
|
let(:configuration) { Jekyll.configuration }
|
|
let(:jekyll_site) { Jekyll::Site.new(configuration) }
|
|
let(:algolia_site) { Jekyll::Algolia::Site.new(configuration) }
|
|
let!(:initial_method) { jekyll_site.method(:process).source_location }
|
|
let!(:overridden_method) { algolia_site.method(:process).source_location }
|
|
|
|
before do
|
|
allow(algolia_site).to receive(:reset)
|
|
allow(algolia_site).to receive(:read)
|
|
allow(algolia_site).to receive(:generate)
|
|
allow(algolia_site).to receive(:keep_only_indexable_files)
|
|
allow(algolia_site).to receive(:init_rendering_progress_bar)
|
|
allow(algolia_site).to receive(:render)
|
|
allow(algolia_site).to receive(:push)
|
|
allow(algolia_site).to receive(:cleanup)
|
|
allow(algolia_site).to receive(:write)
|
|
end
|
|
|
|
it 'should change the initial .write method' do
|
|
expect(overridden_method).to_not eq initial_method
|
|
end
|
|
|
|
describe 'should call the preflight generation' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to have_received(:reset)
|
|
expect(algolia_site).to have_received(:read)
|
|
expect(algolia_site).to have_received(:generate)
|
|
end
|
|
end
|
|
|
|
describe 'should clean the list of files' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to have_received(:keep_only_indexable_files)
|
|
end
|
|
end
|
|
|
|
describe 'should set a progress bar' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to have_received(:init_rendering_progress_bar)
|
|
end
|
|
end
|
|
|
|
describe 'should convert markdown to html' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to have_received(:render)
|
|
end
|
|
end
|
|
|
|
describe 'should push records' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to have_received(:push)
|
|
end
|
|
end
|
|
|
|
describe 'should not call the original cleanup' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to_not have_received(:cleanup)
|
|
end
|
|
end
|
|
|
|
describe 'should not call the original write' do
|
|
before do
|
|
algolia_site.process
|
|
end
|
|
|
|
it do
|
|
expect(algolia_site).to_not have_received(:write)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Jekyll::Site#indexable_list' do
|
|
let(:algolia_site) { Jekyll::Algolia::Site.new(Jekyll.configuration) }
|
|
|
|
subject { algolia_site.indexable_list(items) }
|
|
|
|
describe 'remove non-indexable elements' do
|
|
let(:item1) { double('Item', name: 'foo', data: {}) }
|
|
let(:item2) { double('Item', name: 'bar', data: {}) }
|
|
let(:items) { [item1, item2] }
|
|
|
|
before do
|
|
allow(file_browser).to receive(:indexable?).and_return(true)
|
|
allow(file_browser)
|
|
.to receive(:indexable?)
|
|
.with(item2)
|
|
.and_return(false)
|
|
end
|
|
|
|
it do
|
|
expect(subject.length).to eq 1
|
|
expect(subject[0]).to eq item1
|
|
end
|
|
end
|
|
|
|
describe 'set layout to nil' do
|
|
let(:items) do
|
|
[
|
|
double('Item', name: 'foo', data: {}),
|
|
double('Item', name: 'bar', data: { 'layout' => 'post' })
|
|
]
|
|
end
|
|
|
|
before do
|
|
allow(file_browser).to receive(:indexable?).and_return(true)
|
|
end
|
|
|
|
it do
|
|
expect(subject[0].data).to include('layout' => nil)
|
|
expect(subject[1].data).to include('layout' => nil)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Jekyll::Site#keep_only_indexable_files' do
|
|
let(:site) { Jekyll::Algolia::Site.new(Jekyll.configuration) }
|
|
let(:pages) { 'pages' }
|
|
let(:collections) { { foo: collection } }
|
|
let(:collection) { double('Collection', docs: 'collection') }
|
|
let(:static_files) { 'static_pages' }
|
|
|
|
before do
|
|
allow(site)
|
|
.to receive(:indexable_list)
|
|
allow(collection).to receive(:docs=)
|
|
site.pages = pages
|
|
site.collections = collections
|
|
site.static_files = static_files
|
|
end
|
|
|
|
describe 'should clean the pages' do
|
|
before do
|
|
expect(site)
|
|
.to receive(:indexable_list)
|
|
.with(pages)
|
|
.and_return('after_pages')
|
|
site.keep_only_indexable_files
|
|
end
|
|
|
|
it do
|
|
expect(site.pages).to eq 'after_pages'
|
|
end
|
|
end
|
|
|
|
describe 'should clean the documents' do
|
|
before do
|
|
allow(site)
|
|
.to receive(:indexable_list)
|
|
.with('collection')
|
|
.and_return('after_collection')
|
|
allow(collection)
|
|
.to receive(:docs=)
|
|
.with('after_collection')
|
|
site.keep_only_indexable_files
|
|
end
|
|
|
|
it do
|
|
expect(site).to have_received(:indexable_list).with('collection')
|
|
expect(collection).to have_received(:docs=).with('after_collection')
|
|
end
|
|
end
|
|
|
|
describe 'should clean the static files' do
|
|
before do
|
|
site.keep_only_indexable_files
|
|
end
|
|
|
|
it do
|
|
expect(site.static_files).to eq []
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'Jekyll::Site#indexable_item_count' do
|
|
let(:site) { Jekyll::Algolia::Site.new(Jekyll.configuration) }
|
|
let(:collections) do
|
|
{
|
|
foo: double('CollectionFoo', docs: docs_foo),
|
|
bar: double('CollectionBar', docs: docs_bar)
|
|
}
|
|
end
|
|
|
|
subject { site.indexable_item_count }
|
|
|
|
before do
|
|
site.pages = pages
|
|
site.collections = collections
|
|
end
|
|
|
|
describe do
|
|
let(:pages) { %w[foo bar] }
|
|
let(:docs_foo) { [] }
|
|
let(:docs_bar) { [] }
|
|
it { should eq 2 }
|
|
end
|
|
describe do
|
|
let(:pages) { [] }
|
|
let(:docs_foo) { ['foo'] }
|
|
let(:docs_bar) { %w[bar baz] }
|
|
it { should eq 3 }
|
|
end
|
|
describe do
|
|
let(:pages) { [42] }
|
|
let(:docs_foo) { ['foo'] }
|
|
let(:docs_bar) { %w[bar baz] }
|
|
it { should eq 4 }
|
|
end
|
|
end
|
|
|
|
describe 'Jekyll::Site#init_rendering_progress_bar' do
|
|
let(:site) { Jekyll::Algolia::Site.new(Jekyll.configuration) }
|
|
let(:progress_bar_instance) { double('ProgressBarInstance') }
|
|
let(:item_count) { 2 }
|
|
|
|
before do
|
|
allow(site).to receive(:indexable_item_count).and_return(item_count)
|
|
allow(progress_bar).to receive(:create).and_return(progress_bar_instance)
|
|
allow(Jekyll::Hooks).to receive(:register)
|
|
site.init_rendering_progress_bar
|
|
end
|
|
|
|
it do
|
|
expect(progress_bar)
|
|
.to have_received(:create)
|
|
.with(
|
|
hash_including(total: item_count)
|
|
)
|
|
expect(Jekyll::Hooks)
|
|
.to have_received(:register)
|
|
.with(:pages, :post_render)
|
|
expect(Jekyll::Hooks)
|
|
.to have_received(:register)
|
|
.with(:documents, :post_render)
|
|
end
|
|
end
|
|
|
|
describe 'Jekyll::Site#push' do
|
|
let(:file_foo) { double('File', path: 'foo') }
|
|
let(:file_bar) { double('File', path: 'bar') }
|
|
let(:records_foo) { [{ name: 'foo1' }, { name: 'foo2' }] }
|
|
let(:records_bar) { [{ name: 'bar1' }, { name: 'bar2' }] }
|
|
let(:site) { Jekyll::Algolia::Site.new(Jekyll.configuration) }
|
|
let(:progress_bar_instance) { double('ProgressBarInstance') }
|
|
|
|
before do
|
|
allow(site)
|
|
.to receive(:each_site_file)
|
|
.and_yield(file_foo)
|
|
.and_yield(file_bar)
|
|
allow(site).to receive(:indexable_item_count)
|
|
allow(progress_bar).to receive(:create).and_return(progress_bar_instance)
|
|
allow(progress_bar_instance).to receive(:increment)
|
|
allow(extractor).to receive(:run)
|
|
allow(extractor).to receive(:run).with(file_foo).and_return(records_foo)
|
|
allow(extractor).to receive(:run).with(file_bar).and_return(records_bar)
|
|
allow(extractor).to receive(:add_unique_object_id) { |arg| arg }
|
|
allow(file_browser).to receive(:indexable?).and_return(true)
|
|
allow(file_browser).to receive(:relative_path)
|
|
allow(hooks).to receive(:apply_all) { |arg| arg }
|
|
allow(logger).to receive(:verbose)
|
|
allow(indexer).to receive(:run)
|
|
end
|
|
|
|
describe 'push records' do
|
|
before do
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(indexer)
|
|
.to have_received(:run)
|
|
.with([
|
|
{ name: 'foo1' },
|
|
{ name: 'foo2' },
|
|
{ name: 'bar1' },
|
|
{ name: 'bar2' }
|
|
])
|
|
end
|
|
end
|
|
|
|
describe 'exclude non-indexable elements' do
|
|
before do
|
|
expect(file_browser)
|
|
.to receive(:indexable?)
|
|
.with(file_bar)
|
|
.and_return(false)
|
|
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(indexer)
|
|
.to have_received(:run)
|
|
.with(records_foo)
|
|
end
|
|
end
|
|
|
|
describe 'displaying number of files processed' do
|
|
before do
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(logger).to have_received(:verbose).with(/2 files/)
|
|
end
|
|
end
|
|
|
|
describe 'display path of files in verbose mode' do
|
|
before do
|
|
allow(file_browser)
|
|
.to receive(:relative_path)
|
|
.with('foo')
|
|
.and_return('foo-path')
|
|
allow(file_browser)
|
|
.to receive(:relative_path)
|
|
.with('bar')
|
|
.and_return('bar-path')
|
|
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(logger).to have_received(:verbose).with(/foo-path/)
|
|
expect(logger).to have_received(:verbose).with(/bar-path/)
|
|
end
|
|
end
|
|
|
|
describe 'call hooks on all records' do
|
|
before do
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(hooks)
|
|
.to have_received(:apply_all)
|
|
.with([
|
|
{ name: 'foo1' },
|
|
{ name: 'foo2' },
|
|
{ name: 'bar1' },
|
|
{ name: 'bar2' }
|
|
],
|
|
site)
|
|
end
|
|
end
|
|
|
|
describe 'add a unique id to each record' do
|
|
before do
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(extractor)
|
|
.to have_received(:add_unique_object_id)
|
|
.with(name: 'foo1')
|
|
expect(extractor)
|
|
.to have_received(:add_unique_object_id)
|
|
.with(name: 'foo2')
|
|
expect(extractor)
|
|
.to have_received(:add_unique_object_id)
|
|
.with(name: 'bar1')
|
|
expect(extractor)
|
|
.to have_received(:add_unique_object_id)
|
|
.with(name: 'bar2')
|
|
end
|
|
end
|
|
|
|
describe 'increment progress bar' do
|
|
before do
|
|
allow(site)
|
|
.to receive(:indexable_item_count)
|
|
.and_return(42)
|
|
|
|
site.push
|
|
end
|
|
|
|
it do
|
|
expect(progress_bar)
|
|
.to have_received(:create)
|
|
.with(hash_including(total: 42))
|
|
expect(progress_bar_instance).to have_received(:increment).twice
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.run' do
|
|
# Prevent the whole process to stop if Algolia config is not available
|
|
before do
|
|
allow(configurator)
|
|
.to receive(:assert_valid_credentials)
|
|
.and_return(true)
|
|
end
|
|
|
|
let(:configuration) { Jekyll.configuration }
|
|
let(:algolia_site) { double('Jekyll::Algolia::Site', process: nil) }
|
|
before do
|
|
# Making sure all methods are called on the relevant objects
|
|
expect(Jekyll::Algolia::Site)
|
|
.to receive(:new)
|
|
.with(configuration)
|
|
.and_return(algolia_site)
|
|
expect(algolia_site)
|
|
.to receive(:process)
|
|
end
|
|
|
|
it { current.init(configuration).run }
|
|
end
|
|
end
|
|
# rubocop:enable Metrics/BlockLength
|