sob-has_force 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +2 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +14 -0
- data/Rakefile +50 -0
- data/lib/force/core_ext/array.rb +15 -0
- data/lib/force/core_ext/hash.rb +68 -0
- data/lib/force/has_force.rb +52 -0
- data/lib/force.rb +3 -0
- data/rails/init.rb +1 -0
- data/test/core_ext_test.rb +23 -0
- data/test/database.yml +7 -0
- data/test/has_force_test.rb +38 -0
- data/test/schema.rb +7 -0
- data/test/test_helper.rb +33 -0
- metadata +79 -0
data/CHANGELOG.rdoc
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Sean O'Brien
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= has_force
|
2
|
+
|
3
|
+
This plugin will submit an ActiveRecord model to SalesForce.com using the Web2Lead gateway.
|
4
|
+
|
5
|
+
== Example usage
|
6
|
+
|
7
|
+
class Lead < ActiveRecord::Base
|
8
|
+
has_force :oid => '123'
|
9
|
+
end
|
10
|
+
|
11
|
+
Lead.new(:first_name => "Test").to_salesforce
|
12
|
+
|
13
|
+
|
14
|
+
Copyright (c) 2009 Sean O'Brien, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the test plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the test plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'doc'
|
19
|
+
rdoc.title = 'has_force'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.options << '--webcvs=http://github.com/sob/has_force/tree/master/'
|
22
|
+
rdoc.rdoc_files.include('README.rdoc')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'Update .manifest with the latest list of project filenames'
|
27
|
+
task :manifest do
|
28
|
+
list = Dir['**/*'].sort
|
29
|
+
spec_file = Dir['*.gemspec'].first
|
30
|
+
list -= [spec_file] if spec_file
|
31
|
+
|
32
|
+
File.read('.gitignore').each_line do |glob|
|
33
|
+
glob = glob.chomp.sub(/^\//, '')
|
34
|
+
list -= Dir[glob]
|
35
|
+
list -= Dir["#{glob}/**/*"] if File.directory?(glob) && !File.symlink?(glob)
|
36
|
+
puts "excluding #{glob}"
|
37
|
+
end
|
38
|
+
|
39
|
+
if spec_file
|
40
|
+
spec = File.read spec_file
|
41
|
+
spec.gsub! /^(\s* s.(test_)?files \s* = \s* )( \[ [^\]]* \] | %w\( [^)]* \) )/mx do
|
42
|
+
assignment = $1
|
43
|
+
bunch = $2 ? list.grep(/^test\//) : list
|
44
|
+
'%s%%w(%s)' % [ assignment, bunch.join(' ') ]
|
45
|
+
end
|
46
|
+
|
47
|
+
File.open(spec_file, 'w') {|f| f << spec }
|
48
|
+
end
|
49
|
+
File.open('.manifest', 'w') {|f| f << list.join("\n") }
|
50
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
unless Array.instance_methods.include? 'stringify'
|
2
|
+
Array.class_eval do
|
3
|
+
# converts all values into strings in the current array
|
4
|
+
# [:one, 2, 3].stringify! => ['one', '2', '3']
|
5
|
+
def stringify!
|
6
|
+
collect{|v| v.to_s }
|
7
|
+
end
|
8
|
+
|
9
|
+
# return a copy of the current array with all values converted to strings
|
10
|
+
# [:one, 2, 3].stringify => ['one', '2', '3']
|
11
|
+
def stringify
|
12
|
+
dup.stringify!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
unless Hash.instance_methods.include? '-'
|
2
|
+
Hash.class_eval do
|
3
|
+
# removes one or more keys from a hash
|
4
|
+
# {:red => 1, :blue => 2, :green => 3} - [:red, :blue] => {:green => 3}
|
5
|
+
def -(v)
|
6
|
+
hsh = self.dup
|
7
|
+
(v.is_a?(Array) ? v : [v]).each{|k| hsh.delete(k) }
|
8
|
+
hsh
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
unless Hash.instance_methods.include? 'stringify_values'
|
14
|
+
Hash.class_eval do
|
15
|
+
# returns a new hash with each of the values converted to a string
|
16
|
+
# {:red => 1, :blue => 2} => {:red => '1', :blue => '2'}
|
17
|
+
def stringify_values
|
18
|
+
inject({}) do |options, (key, value)|
|
19
|
+
options[key] = value.to_s
|
20
|
+
options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# returns the hash with each of the values converted to a string
|
25
|
+
# {:red => 1, :blue => 2} => {:red => '1', :blue => '2'}
|
26
|
+
def stringify_values!
|
27
|
+
self.each do |key, value|
|
28
|
+
self[key] = value.to_s
|
29
|
+
end
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
unless Hash.instance_methods.include? 'transform_key'
|
36
|
+
Hash.class_eval do
|
37
|
+
# returns a new hash with a key renamed
|
38
|
+
# {:one => 1, :two => 2}.transform_key(:two, :three) => {:one => 1, :three => 2}
|
39
|
+
def transform_key(old_key, new_key)
|
40
|
+
self.dup.transform_key!(old_key, new_key)
|
41
|
+
end
|
42
|
+
|
43
|
+
# renames a key in a hash
|
44
|
+
# {:one => 1, :two => 2}.transform_key(:two, :three) => {:one => 1, :three => 2}
|
45
|
+
def transform_key!(old_key, new_key)
|
46
|
+
self[new_key] = self.delete(old_key)
|
47
|
+
return self
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns a new hash with renamed keys
|
51
|
+
# accepts a hash of key, value pairs to rename
|
52
|
+
# {:one => 1, :two => 2}.transform_keys(:two => :three) => {:one => 1, :three => 2}
|
53
|
+
def transform_keys(transform)
|
54
|
+
self.dup.transform_keys!(transform)
|
55
|
+
end
|
56
|
+
|
57
|
+
# returns a hash with renamed keys
|
58
|
+
# accepts a hash of key, value pairs to rename
|
59
|
+
# {:one => 1, :two => 2}.transform_keys(:two => :three) => {:one => 1, :three => 2}
|
60
|
+
def transform_keys!(transform)
|
61
|
+
raise ArgumentError, "transform_keys takes a single hash argument" unless transform.is_a?(Hash)
|
62
|
+
self.each_key do |k|
|
63
|
+
self[transform.has_key?(k) ? transform[k] : k] = self.delete(k)
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Force
|
6
|
+
def self.included(base)
|
7
|
+
base.send :extend, ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def has_force(options = {})
|
12
|
+
options = {
|
13
|
+
:skip_fields => [ :id, :created_at, :created_by, :updated_at, :updated_by, :status ],
|
14
|
+
:transform_fields => { },
|
15
|
+
:oid => ''
|
16
|
+
}.merge(options)
|
17
|
+
|
18
|
+
cattr_accessor :force_skip_fields
|
19
|
+
cattr_accessor :force_transform_fields
|
20
|
+
cattr_accessor :force_oid
|
21
|
+
|
22
|
+
self.force_skip_fields = options[:skip_fields]
|
23
|
+
self.force_transform_fields = options[:transform_fields]
|
24
|
+
self.force_oid = options[:oid]
|
25
|
+
|
26
|
+
send :include, InstanceMethods
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
def to_salesforce
|
32
|
+
url = URI.parse('https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8')
|
33
|
+
http = Net::HTTP.new(url.host, url.port)
|
34
|
+
http.use_ssl = true
|
35
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
36
|
+
request = Net::HTTP::Post.new(url.path)
|
37
|
+
attribs = (self.attributes - self.class.force_skip_fields.stringify).stringify_values!
|
38
|
+
attribs.transform_keys!(self.class.force_transform_fields)
|
39
|
+
request.set_form_data(attribs.merge({:oid => self.class.force_oid}))
|
40
|
+
begin
|
41
|
+
response = http.request(request)
|
42
|
+
case response
|
43
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
ActiveRecord::Base.send :include, Force
|
data/lib/force.rb
ADDED
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'force'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper.rb'))
|
2
|
+
|
3
|
+
class CoreExtTest < Test::Unit::TestCase
|
4
|
+
def test_array_stringify_values
|
5
|
+
assert_equal ["test", "1", "red"], [:test, 1, :red].stringify!
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_hash_minus_key
|
9
|
+
assert_equal({:one => '1'}, {:one => '1', :two => '2'} - [:two])
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_hash_stringify_values
|
13
|
+
assert_equal({:one => '1', :two => 'two'}, {:one => 1, :two => :two}.stringify_values!)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_hash_transform_key
|
17
|
+
assert_equal({:one => '1', :three => '2'}, {:one => '1', :two => '2'}.transform_key(:two, :three))
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_hash_transform_multiple_keys
|
21
|
+
assert_equal({:one => '1', :three => '2', :five => '4'}, {:one => '1', :two => '2', :four => '4'}.transform_keys({:two => :three, :four => :five}))
|
22
|
+
end
|
23
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
+
|
3
|
+
class HasForceTest < Test::Unit::TestCase
|
4
|
+
load_schema
|
5
|
+
|
6
|
+
class Lead < ActiveRecord::Base
|
7
|
+
has_force :oid => '123'
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_schema_has_loaded_correctly
|
11
|
+
assert_equal [], Lead.all
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_lead_class_sets_force_oid_variable
|
15
|
+
assert_not_nil(Lead.force_oid)
|
16
|
+
assert_equal('123', Lead.force_oid)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_lead_class_sets_force_skip_fields
|
20
|
+
assert_not_nil(Lead.force_skip_fields)
|
21
|
+
assert_equal([:id, :created_at, :created_by, :updated_at, :updated_by, :status], Lead.force_skip_fields)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_lead_class_sets_force_transform_fields
|
25
|
+
assert_not_nil(Lead.force_transform_fields)
|
26
|
+
assert_equal({}, Lead.force_transform_fields)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_a_lead_responds_to_salesforce
|
30
|
+
@lead = Lead.new
|
31
|
+
assert_respond_to(@lead, :to_salesforce)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_a_lead_submits_to_salesforce
|
35
|
+
@lead = Lead.new
|
36
|
+
assert_equal @lead.to_salesforce, true
|
37
|
+
end
|
38
|
+
end
|
data/test/schema.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
ENV['RAILS_ENV'] = 'test'
|
2
|
+
ENV['RAILS_ROOT'] ||= File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', '..'))
|
3
|
+
|
4
|
+
require 'test/unit'
|
5
|
+
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config', 'environment.rb'))
|
6
|
+
|
7
|
+
def load_schema
|
8
|
+
config = YAML::load(IO.read(File.expand_path(File.join(File.dirname(__FILE__), 'database.yml'))))
|
9
|
+
ActiveRecord::Base.logger = Logger.new(File.expand_path(File.join(File.dirname(__FILE__), 'debug.log')))
|
10
|
+
|
11
|
+
db_adapter = ENV['db']
|
12
|
+
|
13
|
+
db_adapter ||=
|
14
|
+
begin
|
15
|
+
require 'rubygems'
|
16
|
+
require 'sqlite'
|
17
|
+
'sqlite'
|
18
|
+
rescue MissingSourceFile
|
19
|
+
begin
|
20
|
+
require 'sqlite3'
|
21
|
+
'sqlite3'
|
22
|
+
rescue MissingSourceFile
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
if db_adapter.nil?
|
27
|
+
raise "No DB Adapter selected. Pass the DB= option to pick one or install sqlite or sqlite3"
|
28
|
+
end
|
29
|
+
|
30
|
+
ActiveRecord::Base.establish_connection(config[db_adapter])
|
31
|
+
load(File.expand_path(File.join(File.dirname(__FILE__), 'schema.rb')))
|
32
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rails', 'init.rb'))
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sob-has_force
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sean O'Brien
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-26 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: The has_force library will provide a simple SalesForce.com submission tool to allow you to capture leads from your ActiveRecord models without utilizing the SalesForce.com API
|
17
|
+
email: sean.ducttape.it
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- MIT-LICENSE
|
25
|
+
files:
|
26
|
+
- CHANGELOG.rdoc
|
27
|
+
- MIT-LICENSE
|
28
|
+
- README.rdoc
|
29
|
+
- Rakefile
|
30
|
+
- lib
|
31
|
+
- lib/force
|
32
|
+
- lib/force.rb
|
33
|
+
- lib/force/core_ext
|
34
|
+
- lib/force/core_ext/array.rb
|
35
|
+
- lib/force/core_ext/hash.rb
|
36
|
+
- lib/force/has_force.rb
|
37
|
+
- rails
|
38
|
+
- rails/init.rb
|
39
|
+
- test
|
40
|
+
- test/core_ext_test.rb
|
41
|
+
- test/database.yml
|
42
|
+
- test/has_force_test.rb
|
43
|
+
- test/schema.rb
|
44
|
+
- test/test_helper.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/sob/has_force
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --main
|
50
|
+
- README.rdoc
|
51
|
+
- --inline-source
|
52
|
+
- --charset=UTF-8
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.2.0
|
71
|
+
signing_key:
|
72
|
+
specification_version: 2
|
73
|
+
summary: SalesForce.com Web2Lead Submission
|
74
|
+
test_files:
|
75
|
+
- test/core_ext_test.rb
|
76
|
+
- test/database.yml
|
77
|
+
- test/has_force_test.rb
|
78
|
+
- test/schema.rb
|
79
|
+
- test/test_helper.rb
|