commit a7f78b1919e885a0bdc8a3b0109264bb24c93b35
Author: Ohad Levy <ohadlevy@gmail.com>
Date:   Sun Sep 4 10:13:41 2011 +0300

    fixes #1148 - CRUD on lookup values via the API

diff --git a/app/controllers/lookup_keys_controller.rb b/app/controllers/lookup_keys_controller.rb
index 3a9abc22a..000a952cb 100644
--- a/app/controllers/lookup_keys_controller.rb
+++ b/app/controllers/lookup_keys_controller.rb
@@ -20,11 +20,14 @@ class LookupKeysController < ApplicationController
   end
 
   def show
-    return not_found if ((name = params[:host_id]).blank? or (host = Host.find_by_name(name)).blank?)
-    @value = @lookup_key.value_for(host)
+    if (name = params[:host_id]).blank? or (host = Host.find_by_name(name)).blank?
+      value = @lookup_key
+    else
+      value = { :value => @lookup_key.value_for(host) }
+    end
 
     respond_to do |format|
-      format.json { render :json => { :value => @value } }
+      format.json { render :json => value }
     end
   end
 
@@ -50,7 +53,12 @@ class LookupKeysController < ApplicationController
   private
   def find_by_key
     if params[:id]
-      not_found and return unless @lookup_key = LookupKey.find_by_key(params[:id])
+      if params[:id].to_i == 0
+        @lookup_key = LookupKey.find_by_key(params[:id])
+      else
+        @lookup_key = LookupKey.find(params[:id])
+      end
+      not_found and return if @lookup_key.blank?
     end
   end
 end
diff --git a/app/controllers/lookup_values_controller.rb b/app/controllers/lookup_values_controller.rb
new file mode 100644
index 000000000..1931e4383
--- /dev/null
+++ b/app/controllers/lookup_values_controller.rb
@@ -0,0 +1,59 @@
+class LookupValuesController < ApplicationController
+  include Foreman::Controller::AutoCompleteSearch
+  before_filter :reject_non_json_requests
+  before_filter :find_by_id, :except => [:index, :create]
+  before_filter :setup_search_options, :only => :index
+  filter_parameter_logging :value # might contain sensative information
+
+  def index
+    begin
+      values = LookupValue.search_for(params[:search], :order => params[:order])
+    rescue => e
+      error e.to_s
+      values = LookupValue.search_for ""
+    end
+
+    respond_to do |format|
+      format.html do
+        @lookup_values = values.paginate(:page => params[:page])
+      end
+      format.json { render :json => values}
+    end
+  end
+
+  def create
+    @lookup_value = LookupValue.new(params[:lookup_value])
+    if @lookup_value.save
+      process_success({:success_redirect => lookup_key_lookup_values_url(params[:lookup_key_id])})
+    else
+      process_error
+    end
+  end
+
+  def update
+    if @lookup_value.update_attributes(params[:lookup_value])
+      process_success({:success_redirect => lookup_key_lookup_values_url(params[:lookup_key_id])})
+    else
+      process_error
+    end
+  end
+
+  def destroy
+    if @lookup_value.destroy
+      process_success({:success_redirect => lookup_key_lookup_values_url(params[:lookup_key_id])})
+    else
+      process_error
+    end
+  end
+
+  private
+
+  def reject_non_json_requests
+    render_403 unless request_json?
+  end
+
+  def find_by_id
+    @lookup_value = LookupValue.find(params[:id])
+  end
+
+end
diff --git a/app/models/lookup_key.rb b/app/models/lookup_key.rb
index 1dcd15c05..83b9f1c37 100644
--- a/app/models/lookup_key.rb
+++ b/app/models/lookup_key.rb
@@ -117,4 +117,8 @@ class LookupKey < ActiveRecord::Base
     errors.add(:default_value, "not in list") and return false unless validator_rule.split(KEY_DELM).map(&:strip).include?(default_value)
   end
 
+  def as_json(options={})
+    super({:only => [:key, :description, :default_value, :id]}.merge(options))
+  end
+
 end
diff --git a/app/models/lookup_value.rb b/app/models/lookup_value.rb
index 77634a66f..a4f50da86 100644
--- a/app/models/lookup_value.rb
+++ b/app/models/lookup_value.rb
@@ -1,7 +1,8 @@
 class LookupValue < ActiveRecord::Base
+  include Authorization
   belongs_to :lookup_key
   validates_uniqueness_of :match, :scope => :lookup_key_id
-  validates_presence_of :match, :value
+  validates_presence_of :match, :value, :lookup_key_id
   delegate :key, :to => :lookup_key
   validate :validate_range, :validate_list, :validate_regexp, :validate_match
   before_validation :sanitize_match
@@ -10,6 +11,14 @@ class LookupValue < ActiveRecord::Base
 
   default_scope :order => 'LOWER(lookup_values.value)'
 
+  scoped_search :on => :value, :complete_value => true, :default_order => true
+  scoped_search :on => :match, :complete_value => true
+  scoped_search :in => :lookup_key, :on => :key, :rename => :lookup_key, :complete_value => true
+
+  def name
+    value
+  end
+
   private
 
   # TODO: ensures that the match contain only allowed path elements
@@ -35,4 +44,9 @@ class LookupValue < ActiveRecord::Base
     return true unless (lookup_key.validator_type == 'list')
     errors.add(:value, "not in list") and return false unless lookup_key.validator_rule.split(LookupKey::KEY_DELM).map(&:strip).include?(value)
   end
+
+  def as_json(options={})
+    super({:only => [:value, :match, :lookup_key_id, :id]}.merge(options))
+  end
+
 end
diff --git a/app/models/puppetclass.rb b/app/models/puppetclass.rb
index 5e5dd3dc5..980193580 100644
--- a/app/models/puppetclass.rb
+++ b/app/models/puppetclass.rb
@@ -170,7 +170,7 @@ class Puppetclass < ActiveRecord::Base
   end
 
   def as_json(options={})
-    super({:only => [:name, :id]}.merge(options))
+    super({:only => [:name, :id], :methods => [:lookup_keys]}.merge(options))
   end
 
   def self.search_by_host(key, operator, value)
diff --git a/config/routes.rb b/config/routes.rb
index b1f7d9e46..1e1f5c1ec 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -33,7 +33,9 @@ ActionController::Routing::Routes.draw do |map|
   map.resources :media, :collection => {:auto_complete_search => :get}
   map.resources :models, :collection => {:auto_complete_search => :get}
   map.resources :architectures, :collection => {:auto_complete_search => :get}
-  map.resources :lookup_keys, :except => [:show, :new, :create], :requirements => {:id => /[^\/]+/}
+  map.resources :lookup_keys, :except => [:new, :create], :requirements => {:id => /[^\/]+/} do |keys|
+    keys.resources :lookup_values, :only => [:index, :create, :update, :destroy]
+  end
   map.resources :puppetclasses, :member => { :assign => :post }, :collection => {:import_environments => :get, :auto_complete_search => :get} do |pc|
     pc.resources :hosts, :requirements => {:id => /[^\/]+/}
     pc.resources :lookup_keys, :except => [:show, :new, :create], :requirements => {:id => /[^\/]+/}
diff --git a/test/functional/lookup_values_controller_test.rb b/test/functional/lookup_values_controller_test.rb
new file mode 100644
index 000000000..6e73b9149
--- /dev/null
+++ b/test/functional/lookup_values_controller_test.rb
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class LookupValuesControllerTest < ActionController::TestCase
+  # Replace this with your real tests.
+  test "the truth" do
+    assert true
+  end
+end
