mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 20:36:39 +08:00
refactoring the plugin interfaces to allow for better extensible
This commit is contained in:
parent
2eb55b74e4
commit
075002a6d5
|
@ -2,7 +2,7 @@
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.opener.Discourse.authenticationComplete(<%=@data.to_json.html_safe%>);
|
window.opener.Discourse.authenticationComplete(<%=@data.to_client_hash.to_json.html_safe%>);
|
||||||
window.close();
|
window.close();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -33,6 +33,8 @@ Rails.application.config.middleware.use OmniAuth::Builder do
|
||||||
:name => p.name,
|
:name => p.name,
|
||||||
:require => "omniauth-oauth2"
|
:require => "omniauth-oauth2"
|
||||||
}.merge(p.options)
|
}.merge(p.options)
|
||||||
|
else
|
||||||
|
provider p.type, *p.options
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
class AuthProvider
|
|
||||||
attr_accessor :type, :glyph, :background_color, :name, :title,
|
|
||||||
:message, :frame_width, :frame_height, :options
|
|
||||||
end
|
|
|
@ -1,4 +1,5 @@
|
||||||
require 'cache'
|
require 'cache'
|
||||||
|
require_dependency 'plugin/instance'
|
||||||
|
|
||||||
module Discourse
|
module Discourse
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ module Discourse
|
||||||
class CSRF < Exception; end
|
class CSRF < Exception; end
|
||||||
|
|
||||||
def self.activate_plugins!
|
def self.activate_plugins!
|
||||||
@plugins = Plugin.find_all("#{Rails.root}/plugins")
|
@plugins = Plugin::Instance.find_all("#{Rails.root}/plugins")
|
||||||
@plugins.each do |plugin|
|
@plugins.each do |plugin|
|
||||||
plugin.activate!
|
plugin.activate!
|
||||||
end
|
end
|
||||||
|
|
192
lib/plugin.rb
192
lib/plugin.rb
|
@ -1,192 +0,0 @@
|
||||||
require_dependency 'auth_provider'
|
|
||||||
require 'digest/sha1'
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
class Plugin
|
|
||||||
|
|
||||||
METADATA = [:name, :about, :version, :authors]
|
|
||||||
|
|
||||||
attr_accessor :path
|
|
||||||
attr_accessor *METADATA
|
|
||||||
attr_reader :auth_providers
|
|
||||||
attr_reader :assets
|
|
||||||
|
|
||||||
def self.find_all(parent_path)
|
|
||||||
plugins = []
|
|
||||||
Dir["#{parent_path}/**/plugin.rb"].each do |path|
|
|
||||||
plugin = parse(File.read(path))
|
|
||||||
plugin.path = path
|
|
||||||
plugins << plugin
|
|
||||||
end
|
|
||||||
|
|
||||||
plugins
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.parse(text)
|
|
||||||
plugin = self.new
|
|
||||||
|
|
||||||
text.each_line do |line|
|
|
||||||
break unless plugin.parse_line(line)
|
|
||||||
end
|
|
||||||
|
|
||||||
plugin
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@assets = []
|
|
||||||
end
|
|
||||||
|
|
||||||
def parse_line(line)
|
|
||||||
line = line.strip
|
|
||||||
|
|
||||||
unless line.empty?
|
|
||||||
return false unless line[0] == "#"
|
|
||||||
attribute, *description = line[1..-1].split(":")
|
|
||||||
|
|
||||||
description = description.join(":")
|
|
||||||
attribute = attribute.strip.to_sym
|
|
||||||
|
|
||||||
if METADATA.include?(attribute)
|
|
||||||
self.send("#{attribute}=", description.strip)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
# will make sure all the assets this plugin needs are registered
|
|
||||||
def generate_automatic_assets!
|
|
||||||
paths = []
|
|
||||||
automatic_assets.each do |path, contents|
|
|
||||||
unless File.exists? path
|
|
||||||
ensure_directory path
|
|
||||||
File.open(path,"w") do |f|
|
|
||||||
f.write(contents)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
paths << path
|
|
||||||
end
|
|
||||||
|
|
||||||
delete_extra_automatic_assets(paths)
|
|
||||||
|
|
||||||
paths
|
|
||||||
end
|
|
||||||
|
|
||||||
def delete_extra_automatic_assets(good_paths)
|
|
||||||
filenames = good_paths.map{|f| File.basename(f)}
|
|
||||||
# nuke old files
|
|
||||||
Dir.foreach(auto_generated_path) do |p|
|
|
||||||
next if [".", ".."].include?(p)
|
|
||||||
next if filenames.include?(p)
|
|
||||||
File.delete(auto_generated_path + "/#{p}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_directory(path)
|
|
||||||
dirname = File.dirname(path)
|
|
||||||
unless File.directory?(dirname)
|
|
||||||
FileUtils.mkdir_p(dirname)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def auto_generated_path
|
|
||||||
File.dirname(path) << "/auto_generated"
|
|
||||||
end
|
|
||||||
|
|
||||||
def register_css(style)
|
|
||||||
@styles ||= []
|
|
||||||
@styles << style
|
|
||||||
end
|
|
||||||
|
|
||||||
def register_javascript(js)
|
|
||||||
@javascripts ||= []
|
|
||||||
@javascripts << js
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def register_asset(file,opts=nil)
|
|
||||||
full_path = File.dirname(path) << "/assets/" << file
|
|
||||||
assets << full_path
|
|
||||||
if opts == :server_side
|
|
||||||
@server_side_javascripts ||= []
|
|
||||||
@server_side_javascripts << full_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def automatic_assets
|
|
||||||
css = ""
|
|
||||||
js = "(function(){"
|
|
||||||
|
|
||||||
css = @styles.join("\n") if @styles
|
|
||||||
js = @javascripts.join("\n") if @javascripts
|
|
||||||
|
|
||||||
unless auth_providers.blank?
|
|
||||||
auth_providers.each do |auth|
|
|
||||||
overrides = ""
|
|
||||||
overrides = ", titleOverride: '#{auth.title}'" if auth.title
|
|
||||||
overrides << ", messageOverride: '#{auth.message}'" if auth.message
|
|
||||||
overrides << ", frameWidth: '#{auth.frame_width}'" if auth.frame_width
|
|
||||||
overrides << ", frameHeight: '#{auth.frame_height}'" if auth.frame_height
|
|
||||||
|
|
||||||
js << "Discourse.LoginMethod.register(Discourse.LoginMethod.create({name: '#{auth.name}'#{overrides}}));\n"
|
|
||||||
|
|
||||||
if auth.glyph
|
|
||||||
css << ".btn-social.#{auth.name}:before{ content: '#{auth.glyph}'; }\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
if auth.background_color
|
|
||||||
css << ".btn-social.#{auth.name}{ background: #{auth.background_color}; }\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
js << "})();"
|
|
||||||
|
|
||||||
# TODO don't serve blank assets
|
|
||||||
[[css,"css"],[js,"js"]].map do |asset, extension|
|
|
||||||
hash = Digest::SHA1.hexdigest asset
|
|
||||||
["#{auto_generated_path}/plugin_#{hash}.#{extension}", asset]
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
# note, we need to be able to parse seperately to activation.
|
|
||||||
# this allows us to present information about a plugin in the UI
|
|
||||||
# prior to activations
|
|
||||||
def activate!
|
|
||||||
self.instance_eval File.read(path)
|
|
||||||
if auto_assets = generate_automatic_assets!
|
|
||||||
assets.concat auto_assets
|
|
||||||
end
|
|
||||||
unless assets.blank?
|
|
||||||
assets.each do |asset|
|
|
||||||
if asset =~ /\.js$/
|
|
||||||
DiscoursePluginRegistry.javascripts << asset
|
|
||||||
elsif asset =~ /\.css$|\.scss$/
|
|
||||||
DiscoursePluginRegistry.stylesheets << asset
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO possibly amend this to a rails engine
|
|
||||||
Rails.configuration.assets.paths << auto_generated_path
|
|
||||||
Rails.configuration.assets.paths << File.dirname(path) + "/assets"
|
|
||||||
end
|
|
||||||
|
|
||||||
if @server_side_javascripts
|
|
||||||
@server_side_javascripts.each do |js|
|
|
||||||
DiscoursePluginRegistry.server_side_javascripts << js
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def auth_provider(type, opts)
|
|
||||||
@auth_providers ||= []
|
|
||||||
provider = AuthProvider.new
|
|
||||||
provider.type = type
|
|
||||||
[:name, :glyph, :background_color, :title, :message, :frame_width, :frame_height].each do |sym|
|
|
||||||
provider.send "#{sym}=", opts.delete(sym)
|
|
||||||
end
|
|
||||||
provider.options = opts
|
|
||||||
@auth_providers << provider
|
|
||||||
end
|
|
||||||
end
|
|
4
lib/plugin/auth_provider.rb
Normal file
4
lib/plugin/auth_provider.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
class Plugin::AuthProvider
|
||||||
|
attr_accessor :type, :glyph, :background_color, :name, :title,
|
||||||
|
:message, :frame_width, :frame_height, :options, :callback
|
||||||
|
end
|
193
lib/plugin/instance.rb
Normal file
193
lib/plugin/instance.rb
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
require 'digest/sha1'
|
||||||
|
require 'fileutils'
|
||||||
|
require_dependency 'plugin/metadata'
|
||||||
|
require_dependency 'plugin/auth_provider'
|
||||||
|
|
||||||
|
class Plugin::Instance
|
||||||
|
|
||||||
|
attr_reader :auth_providers, :assets, :path
|
||||||
|
|
||||||
|
def self.find_all(parent_path)
|
||||||
|
[].tap { |plugins|
|
||||||
|
Dir["#{parent_path}/**/plugin.rb"].each do |path|
|
||||||
|
source = File.read(path)
|
||||||
|
metadata = Plugin::Metadata.parse(source)
|
||||||
|
plugins << self.new(metadata, path)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(metadata, path)
|
||||||
|
@metadata = metadata
|
||||||
|
@path = path
|
||||||
|
@assets = []
|
||||||
|
end
|
||||||
|
|
||||||
|
# will make sure all the assets this plugin needs are registered
|
||||||
|
def generate_automatic_assets!
|
||||||
|
paths = []
|
||||||
|
automatic_assets.each do |path, contents|
|
||||||
|
unless File.exists? path
|
||||||
|
ensure_directory path
|
||||||
|
File.open(path,"w") do |f|
|
||||||
|
f.write(contents)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
paths << path
|
||||||
|
end
|
||||||
|
|
||||||
|
delete_extra_automatic_assets(paths)
|
||||||
|
|
||||||
|
paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_extra_automatic_assets(good_paths)
|
||||||
|
filenames = good_paths.map{|f| File.basename(f)}
|
||||||
|
# nuke old files
|
||||||
|
Dir.foreach(auto_generated_path) do |p|
|
||||||
|
next if [".", ".."].include?(p)
|
||||||
|
next if filenames.include?(p)
|
||||||
|
File.delete(auto_generated_path + "/#{p}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def ensure_directory(path)
|
||||||
|
dirname = File.dirname(path)
|
||||||
|
unless File.directory?(dirname)
|
||||||
|
FileUtils.mkdir_p(dirname)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def auto_generated_path
|
||||||
|
File.dirname(path) << "/auto_generated"
|
||||||
|
end
|
||||||
|
|
||||||
|
def register_css(style)
|
||||||
|
@styles ||= []
|
||||||
|
@styles << style
|
||||||
|
end
|
||||||
|
|
||||||
|
def register_javascript(js)
|
||||||
|
@javascripts ||= []
|
||||||
|
@javascripts << js
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def register_asset(file,opts=nil)
|
||||||
|
full_path = File.dirname(path) << "/assets/" << file
|
||||||
|
assets << full_path
|
||||||
|
if opts == :server_side
|
||||||
|
@server_side_javascripts ||= []
|
||||||
|
@server_side_javascripts << full_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def automatic_assets
|
||||||
|
css = ""
|
||||||
|
js = "(function(){"
|
||||||
|
|
||||||
|
css = @styles.join("\n") if @styles
|
||||||
|
js = @javascripts.join("\n") if @javascripts
|
||||||
|
|
||||||
|
unless auth_providers.blank?
|
||||||
|
auth_providers.each do |auth|
|
||||||
|
overrides = ""
|
||||||
|
overrides = ", titleOverride: '#{auth.title}'" if auth.title
|
||||||
|
overrides << ", messageOverride: '#{auth.message}'" if auth.message
|
||||||
|
overrides << ", frameWidth: '#{auth.frame_width}'" if auth.frame_width
|
||||||
|
overrides << ", frameHeight: '#{auth.frame_height}'" if auth.frame_height
|
||||||
|
|
||||||
|
js << "Discourse.LoginMethod.register(Discourse.LoginMethod.create({name: '#{auth.name}'#{overrides}}));\n"
|
||||||
|
|
||||||
|
if auth.glyph
|
||||||
|
css << ".btn-social.#{auth.name}:before{ content: '#{auth.glyph}'; }\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
if auth.background_color
|
||||||
|
css << ".btn-social.#{auth.name}{ background: #{auth.background_color}; }\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
js << "})();"
|
||||||
|
|
||||||
|
# TODO don't serve blank assets
|
||||||
|
[[css,"css"],[js,"js"]].map do |asset, extension|
|
||||||
|
hash = Digest::SHA1.hexdigest asset
|
||||||
|
["#{auto_generated_path}/plugin_#{hash}.#{extension}", asset]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# note, we need to be able to parse seperately to activation.
|
||||||
|
# this allows us to present information about a plugin in the UI
|
||||||
|
# prior to activations
|
||||||
|
def activate!
|
||||||
|
self.instance_eval File.read(path)
|
||||||
|
if auto_assets = generate_automatic_assets!
|
||||||
|
assets.concat auto_assets
|
||||||
|
end
|
||||||
|
unless assets.blank?
|
||||||
|
assets.each do |asset|
|
||||||
|
if asset =~ /\.js$/
|
||||||
|
DiscoursePluginRegistry.javascripts << asset
|
||||||
|
elsif asset =~ /\.css$|\.scss$/
|
||||||
|
DiscoursePluginRegistry.stylesheets << asset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO possibly amend this to a rails engine
|
||||||
|
Rails.configuration.assets.paths << auto_generated_path
|
||||||
|
Rails.configuration.assets.paths << File.dirname(path) + "/assets"
|
||||||
|
end
|
||||||
|
|
||||||
|
if @server_side_javascripts
|
||||||
|
@server_side_javascripts.each do |js|
|
||||||
|
DiscoursePluginRegistry.server_side_javascripts << js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def auth_provider(type, opts)
|
||||||
|
@auth_providers ||= []
|
||||||
|
provider = Plugin::AuthProvider.new
|
||||||
|
provider.type = type
|
||||||
|
[:name, :glyph, :background_color, :title, :message, :frame_width, :frame_height, :callback].each do |sym|
|
||||||
|
provider.send "#{sym}=", opts.delete(sym)
|
||||||
|
end
|
||||||
|
provider.name ||= type.to_s
|
||||||
|
provider.options = opts[:middleware_options] || opts
|
||||||
|
# prepare for splatting
|
||||||
|
provider.options = [provider.options] if provider.options.is_a? Hash
|
||||||
|
@auth_providers << provider
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# shotgun approach to gem loading, in future we need to hack bundler
|
||||||
|
# to at least determine dependencies do not clash before loading
|
||||||
|
#
|
||||||
|
# Additionally we want to support multiple ruby versions correctly and so on
|
||||||
|
#
|
||||||
|
# This is a very rough initial implementation
|
||||||
|
def gem(name, version, opts = {})
|
||||||
|
gems_path = File.dirname(path) + "/gems/#{RUBY_VERSION}"
|
||||||
|
spec_path = gems_path + "/specifications"
|
||||||
|
spec_file = spec_path + "/#{name}-#{version}.gemspec"
|
||||||
|
unless File.exists? spec_file
|
||||||
|
command = "gem install #{name} -v #{version} -i #{gems_path} --no-rdoc --no-ri"
|
||||||
|
puts command
|
||||||
|
puts `command`
|
||||||
|
end
|
||||||
|
if File.exists? spec_file
|
||||||
|
spec = Gem::Specification.load spec_file
|
||||||
|
spec.activate
|
||||||
|
unless opts[:require] == false
|
||||||
|
require name
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts "You are specifying the gem #{name} in #{path}, however it does not exist!"
|
||||||
|
exit -1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
33
lib/plugin/metadata.rb
Normal file
33
lib/plugin/metadata.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# loaded really early
|
||||||
|
module Plugin; end
|
||||||
|
|
||||||
|
class Plugin::Metadata
|
||||||
|
FIELDS = [:name, :about, :version, :authors]
|
||||||
|
attr_accessor *FIELDS
|
||||||
|
|
||||||
|
def self.parse(text)
|
||||||
|
metadata = self.new
|
||||||
|
text.each_line do |line|
|
||||||
|
break unless metadata.parse_line(line)
|
||||||
|
end
|
||||||
|
metadata
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_line(line)
|
||||||
|
line = line.strip
|
||||||
|
|
||||||
|
unless line.empty?
|
||||||
|
return false unless line[0] == "#"
|
||||||
|
attribute, *description = line[1..-1].split(":")
|
||||||
|
|
||||||
|
description = description.join(":")
|
||||||
|
attribute = attribute.strip.to_sym
|
||||||
|
|
||||||
|
if FIELDS.include?(attribute)
|
||||||
|
self.send("#{attribute}=", description.strip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
32
spec/components/plugin/instance_spec.rb
Normal file
32
spec/components/plugin/instance_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require_dependency 'plugin/instance'
|
||||||
|
|
||||||
|
describe Plugin::Instance do
|
||||||
|
|
||||||
|
context "activate!" do
|
||||||
|
it "can activate plugins correctly" do
|
||||||
|
plugin = Plugin.new
|
||||||
|
plugin.path = "#{Rails.root}/spec/fixtures/plugins/my_plugin/plugin.rb"
|
||||||
|
junk_file = "#{plugin.auto_generated_path}/junk"
|
||||||
|
|
||||||
|
plugin.ensure_directory(junk_file)
|
||||||
|
File.open("#{plugin.auto_generated_path}/junk", "w") {|f| f.write("junk")}
|
||||||
|
plugin.activate!
|
||||||
|
|
||||||
|
plugin.auth_providers.count.should == 1
|
||||||
|
auth_provider = plugin.auth_providers[0]
|
||||||
|
auth_provider.options.should == {:identifier => 'https://zappa.com'}
|
||||||
|
auth_provider.type.should == :open_id
|
||||||
|
|
||||||
|
# calls ensure_assets! make sure they are there
|
||||||
|
plugin.assets.count.should == 2
|
||||||
|
plugin.assets.each do |a|
|
||||||
|
File.exists?(a).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
# ensure it cleans up all crap in autogenerated directory
|
||||||
|
File.exists?(junk_file).should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
41
spec/components/plugin/metadata_spec.rb
Normal file
41
spec/components/plugin/metadata_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require_dependency 'plugin/metadata'
|
||||||
|
|
||||||
|
describe Plugin::Metadata do
|
||||||
|
context "parse" do
|
||||||
|
it "correctly parses plugin info" do
|
||||||
|
metadata = Plugin::Metadata.parse <<TEXT
|
||||||
|
# name: plugin-name
|
||||||
|
# about: about: my plugin
|
||||||
|
# version: 0.1
|
||||||
|
# authors: Frank Zappa
|
||||||
|
# gem: some_gem
|
||||||
|
# gem: some_gem, "1"
|
||||||
|
|
||||||
|
some_ruby
|
||||||
|
TEXT
|
||||||
|
|
||||||
|
metadata.name.should == "plugin-name"
|
||||||
|
metadata.about.should == "about: my plugin"
|
||||||
|
metadata.version.should == "0.1"
|
||||||
|
metadata.authors.should == "Frank Zappa"
|
||||||
|
metadata.gems.should == ["some_gem", 'some_gem, "1"']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "find_all" do
|
||||||
|
it "can find plugins correctly" do
|
||||||
|
metadatas = Plugin::Metadata.find_all("#{Rails.root}/spec/fixtures/plugins")
|
||||||
|
metadatas.count.should == 1
|
||||||
|
metadata = metadata[0]
|
||||||
|
|
||||||
|
metadata.name.should == "plugin-name"
|
||||||
|
metadata.path.should == "#{Rails.root}/spec/fixtures/plugins/my_plugin/plugin.rb"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not blow up on missing directory" do
|
||||||
|
metadatas = Plugin.find_all("#{Rails.root}/frank_zappa")
|
||||||
|
metadatas.count.should == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,65 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
require_dependency 'plugin'
|
|
||||||
|
|
||||||
describe Plugin do
|
|
||||||
context "parse" do
|
|
||||||
it "correctly parses plugin info" do
|
|
||||||
plugin = Plugin.parse <<TEXT
|
|
||||||
# name: plugin-name
|
|
||||||
# about: about: my plugin
|
|
||||||
# version: 0.1
|
|
||||||
# authors: Frank Zappa
|
|
||||||
|
|
||||||
some_ruby
|
|
||||||
TEXT
|
|
||||||
|
|
||||||
plugin.name.should == "plugin-name"
|
|
||||||
plugin.about.should == "about: my plugin"
|
|
||||||
plugin.version.should == "0.1"
|
|
||||||
plugin.authors.should == "Frank Zappa"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "find_all" do
|
|
||||||
it "can find plugins correctly" do
|
|
||||||
plugins = Plugin.find_all("#{Rails.root}/spec/fixtures/plugins")
|
|
||||||
plugins.count.should == 1
|
|
||||||
plugin = plugins[0]
|
|
||||||
|
|
||||||
plugin.name.should == "plugin-name"
|
|
||||||
plugin.path.should == "#{Rails.root}/spec/fixtures/plugins/my_plugin/plugin.rb"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not blow up on missing directory" do
|
|
||||||
plugins = Plugin.find_all("#{Rails.root}/frank_zappa")
|
|
||||||
plugins.count.should == 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "activate!" do
|
|
||||||
it "can activate plugins correctly" do
|
|
||||||
plugin = Plugin.new
|
|
||||||
plugin.path = "#{Rails.root}/spec/fixtures/plugins/my_plugin/plugin.rb"
|
|
||||||
junk_file = "#{plugin.auto_generated_path}/junk"
|
|
||||||
|
|
||||||
plugin.ensure_directory(junk_file)
|
|
||||||
File.open("#{plugin.auto_generated_path}/junk", "w") {|f| f.write("junk")}
|
|
||||||
plugin.activate!
|
|
||||||
|
|
||||||
plugin.auth_providers.count.should == 1
|
|
||||||
auth_provider = plugin.auth_providers[0]
|
|
||||||
auth_provider.options.should == {:identifier => 'https://zappa.com'}
|
|
||||||
auth_provider.type.should == :open_id
|
|
||||||
|
|
||||||
# calls ensure_assets! make sure they are there
|
|
||||||
plugin.assets.count.should == 2
|
|
||||||
plugin.assets.each do |a|
|
|
||||||
File.exists?(a).should be_true
|
|
||||||
end
|
|
||||||
|
|
||||||
# ensure it cleans up all crap in autogenerated directory
|
|
||||||
File.exists?(junk_file).should be_false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user