Adding getters for app id, api key and index name

This commit is contained in:
Pixelastic 2017-11-13 12:57:14 +01:00
parent 6a137fa850
commit d131a62457
7 changed files with 110 additions and 232 deletions

View File

@ -1,46 +0,0 @@
module AlgoliaPlugin
def self.do_something(config)
site = Jekyll::Site.new(config)
site.process
42
end
end
describe AlgoliaPlugin do
describe '.do_something' do
let(:config) { {foo: 'bar'} }
let(:jekyll_site) { double('Jekyll::Site', process: nil) }
before { expect(Jekyll::Site).to receive(:new).with(config).and_return(jekyll_site) }
before { expect(jekyll_site).to receive(:process) }
it { AlgoliaPlugin.do_something(config) }
end
describe '.do_something' do
let(:config) { {foo: 'bar'} }
let(:jekyll_site) { double('Jekyll::Site', process: nil) }
before { allow(Jekyll::Site).to receive(:new).and_return(jekyll_site) }
before { allow(jekyll_site).to receive(:process) }
before { AlgoliaPlugin.do_something(config) }
it { expect(Jekyll::Site).to have_received(:new).with(config) }
it { expect(jekyll_site).to have_received(:process).with(config) }
end
describe '.do_something' do
let(:config) { {foo: 'bar'} }
let(:jekyll_site) { double('Jekyll::Site', process: nil) }
before { allow(Jekyll::Site).to receive(:new).and_return(jekyll_site) }
before { allow(jekyll_site).to receive(:process) }
subject { AlgoliaPlugin.do_something(config) }
context 'config is valid' do
let(:config) { false }
it { should eq 42 }
it { expect(subject).to eq 42 }
end
end
end

View File

@ -8,6 +8,7 @@ module Jekyll
require 'jekyll/algolia/utils'
require 'jekyll/algolia/user_hooks'
require 'jekyll/algolia/configurator'
require 'jekyll/algolia/logger'
require 'jekyll/algolia/file_browser'
require 'jekyll/algolia/extractor'
require 'jekyll/algolia/indexer'
@ -25,6 +26,8 @@ module Jekyll
@config = config
@site = Jekyll::Site.new(@config)
monkey_patch_site(@site)
Jekyll::Algolia::Configurator.assert_valid_credentials
# @checker = AlgoliaSearchCredentialChecker.new(@config)
self
end

View File

@ -36,6 +36,44 @@ module Jekyll
value
end
# Public: Return the application id
#
# Will first try to read the ENV variable, and fallback to the one
# configured in Jekyll config
def self.application_id
ENV['ALGOLIA_APPLICATION_ID'] || algolia('application_id')
end
# Public: Return the api key
#
# Will first try to read the ENV variable. Will otherwise try to read the
# _algolia_api_key file in the Jekyll folder
def self.api_key
# Alway taking the ENV variable first
return ENV['ALGOLIA_API_KEY'] if ENV['ALGOLIA_API_KEY']
# Reading from file on disk otherwise
source_dir = get('source')
if source_dir
api_key_file = File.join(source_dir, '_algolia_api_key')
if File.exist?(api_key_file) && File.size(api_key_file) > 0
return File.open(api_key_file).read.strip
end
end
nil
end
# Public: Return the index name
#
# Will first try to read the ENV variable, and fallback to the one
# configured in Jekyll config
def self.index_name
ENV['ALGOLIA_INDEX_NAME'] || algolia('index_name')
end
def self.assert_valid_credentials; end
# Public: Setting a default values to index only html and markdown files
#
# Markdown files can have many different extensions. We keep the one

View File

@ -0,0 +1,7 @@
module Jekyll
module Algolia
# Display helpful error messages
module Logger
end
end
end

View File

@ -1,180 +0,0 @@
require 'algoliasearch'
require 'nokogiri'
require 'json'
require 'algolia_html_extractor'
# Given an HTML file as input, will return an array of records to index
class AlgoliaSearchRecordExtractor
attr_reader :file
def initialize(file)
@file = file
@config = file.site.config
default_config = {
'nodes_to_index' => 'p'
}
@config = default_config.merge(file.site.config['algolia'])
end
# Hook to modify a record after extracting
def custom_hook_each(item, _node)
item
end
# Hook to modify all records after extracting
def custom_hook_all(items)
items
end
##
# Return the type of the Jekyll element
# It can be either page, post or document
def type
classname = @file.class.name
subclass = classname.split('::')[1]
type = subclass.downcase
# Post are actually a specific type of Documents
if type == 'document'
collection_name = @file.collection.label
return 'post' if collection_name == 'posts'
end
type
end
##
# Return the url of the page
def url
@file.url
end
##
# Return the title of the page
def title
@file.data['title']
end
##
# Returns the slug of the document
def slug
# We can guess the slug from the filename for all documents
basename = File.basename(@file.path)
extname = File.extname(basename)
slug = File.basename(basename, extname)
# Jekyll v3 posts have it in data
return @file.data['slug'] if @file.data.key?('slug')
# Jekyll v2 posts have a specific slug method
return @file.slug if @file.respond_to?(:slug)
slug
end
##
# Get an array of tags of the document
def tags
tags = []
has_tags_data = @file.data.key?('tags')
# All tags are in data['tags']
tags = @file.data['tags'] if has_tags_data
# Some extension extends the tags with custom classes, so we make sure we
# cast them as strings
tags.map(&:to_s)
end
##
# Get the post date timestamp
def date
return nil unless @file.respond_to?(:date)
@file.date.to_time.to_i
end
##
# Get the collection name of a document
def collection
return nil unless @file.respond_to?(:collection)
collection_name = @file.collection.label
# In Jekyll v3, posts are actually a collection
return nil if collection_name == 'posts'
collection_name
end
##
# Get a hash of all front-matter data
def front_matter
raw_data = @file.data
# We clean some keys that will be handled by specific methods
attributes_to_remove = %w(title tags slug url date type)
attributes_to_remove.each do |attribute|
raw_data.delete(attribute)
end
# Convert to symbols
data = {}
raw_data.each do |key, value|
data[key.to_sym] = value
end
data
end
##
# Get the list of all node data
def hierarchy_nodes
extractor_options = {
css_selector: @config['nodes_to_index']
}
AlgoliaHTMLExtractor.new(
@file.content,
options: extractor_options
).extract
end
# Extract all records from the page and return the list
def extract
# Getting all hierarchical nodes from the HTML input
raw_items = hierarchy_nodes
# Shared attributes relative to the page that all records will have
shared_attributes = {
type: type,
url: url,
title: title,
slug: slug,
date: date,
collection: collection,
tags: tags
}
# Remove empty attributes
shared_attributes = shared_attributes.delete_if do |_, value|
value.nil?
end
# Enriching with page metadata
items = []
raw_items.each do |raw_item|
nokogiri_node = raw_item[:node]
raw_item.delete(:node)
item = shared_attributes.merge(raw_item)
item[:objectID] = item[:uuid]
item.delete(:uuid)
item = custom_hook_each(item, nokogiri_node)
next if item.nil?
items << item
end
custom_hook_all(items)
end
end

View File

@ -1,8 +1,8 @@
# rubocop:disable Metrics/BlockLength
require 'spec_helper'
describe(Jekyll::Algolia::Configurator) do
let(:current) { Jekyll::Algolia::Configurator }
let(:config) { {} }
before do
allow(Jekyll::Algolia).to receive(:config).and_return(config)
end
@ -46,7 +46,6 @@ describe(Jekyll::Algolia::Configurator) do
end
context 'with no algolia config defined' do
let(:config) { {} }
let(:input) { 'foo' }
it { should eq nil }
@ -58,8 +57,6 @@ describe(Jekyll::Algolia::Configurator) do
end
describe '.default_extensions_to_index' do
let(:config) { {} }
subject { current.default_extensions_to_index }
before do
@ -75,8 +72,6 @@ describe(Jekyll::Algolia::Configurator) do
end
describe '.default_files_to_exclude' do
let(:config) { {} }
subject { current.default_files_to_exclude }
before do
@ -89,4 +84,65 @@ describe(Jekyll::Algolia::Configurator) do
it { should include('index.foo') }
it { should include('index.bar') }
end
describe '.index_name' do
subject { current.index_name }
describe 'should return nil if none configured' do
it { should eq nil }
end
describe 'should return the value in _config.yml if set' do
let(:config) { { 'algolia' => { 'index_name' => 'foo' } } }
it { should eq 'foo' }
end
describe 'should return the value in ENV is set' do
before { stub_const('ENV', 'ALGOLIA_INDEX_NAME' => 'bar') }
it { should eq 'bar' }
end
describe 'should prefer the value in ENV rather than config if set' do
let(:config) { { 'algolia' => { 'index_name' => 'foo' } } }
before { stub_const('ENV', 'ALGOLIA_INDEX_NAME' => 'bar') }
it { should eq 'bar' }
end
end
describe '.application_id' do
subject { current.application_id }
describe 'should return nil if none configured' do
it { should eq nil }
end
describe 'should return the value in _config.yml if set' do
let(:config) { { 'algolia' => { 'application_id' => 'foo' } } }
it { should eq 'foo' }
end
describe 'should return the value in ENV is set' do
let(:config) { {} }
before { stub_const('ENV', 'ALGOLIA_APPLICATION_ID' => 'bar') }
it { should eq 'bar' }
end
describe 'should prefer the value in ENV rather than config if set' do
let(:config) { { 'algolia' => { 'application_id' => 'foo' } } }
before { stub_const('ENV', 'ALGOLIA_APPLICATION_ID' => 'bar') }
it { should eq 'bar' }
end
end
describe '.api_key' do
subject { current.api_key }
describe 'should return nil if none configured' do
it { should eq nil }
end
describe 'should return the value in ENV is set' do
before { stub_const('ENV', 'ALGOLIA_API_KEY' => 'bar') }
it { should eq 'bar' }
end
describe 'should return the value in _algolia_api_key file' do
let(:config) { { 'source' => './spec/site' } }
it { should eq 'APIKEY_FROM_FILE' }
end
describe 'should prefer the value in ENV rather than in the file' do
end
end
end