metaforce 0.4.1 → 0.5.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/README.md +17 -5
- data/lib/metaforce.rb +1 -0
- data/lib/metaforce/core_extensions.rb +1 -0
- data/lib/metaforce/core_extensions/string.rb +24 -0
- data/lib/metaforce/metadata.rb +2 -0
- data/lib/metaforce/metadata/client.rb +27 -19
- data/lib/metaforce/metadata/crud.rb +103 -0
- data/lib/metaforce/metadata/file.rb +74 -0
- data/lib/metaforce/metadata/transaction.rb +12 -0
- data/lib/metaforce/services/client.rb +2 -0
- data/lib/metaforce/version.rb +1 -1
- data/spec/fixtures/requests/create/in_progress.xml +12 -0
- data/spec/fixtures/requests/delete/in_progress.xml +12 -0
- data/spec/fixtures/requests/update/in_progress.xml +12 -0
- data/spec/lib/core_extensions/string_spec.rb +23 -0
- data/spec/lib/metadata/{metadata_spec.rb → client_spec.rb} +22 -3
- data/spec/lib/metadata/crud_spec.rb +66 -0
- data/spec/lib/metadata/file_spec.rb +17 -0
- data/spec/lib/services/{services_spec.rb → client_spec.rb} +0 -0
- metadata +38 -22
data/README.md
CHANGED
@@ -17,11 +17,11 @@ client = Metaforce::Metadata::Client.new :username => 'username',
|
|
17
17
|
:security_token => 'security token')
|
18
18
|
|
19
19
|
# Describe the metadata on the organization
|
20
|
-
client.
|
21
|
-
# =>
|
20
|
+
client.metadata_objects
|
21
|
+
# => [{ :child_xml_names => "CustomLabel", :directory_name => "labels" ... }]
|
22
22
|
|
23
23
|
# List all custom objects
|
24
|
-
client.list(:
|
24
|
+
client.list(:custom_object)
|
25
25
|
# => [{ :created_by_id => "005U0000000EGpcIAG", :created_by_name => "Eric Holmes", ... }]
|
26
26
|
|
27
27
|
# Deploy metadata to the organization
|
@@ -34,6 +34,15 @@ deployment.result
|
|
34
34
|
|
35
35
|
# Retrieve the metadata components specified in package.xml and unzip to the "retrieved" directory
|
36
36
|
client.retrieve(File.expand_path('path/to/package.xml')).to('retrieved')
|
37
|
+
|
38
|
+
# Create a Visualforce page
|
39
|
+
client.create_apex_page(:full_name => 'TestPage', :label => 'TestPage')
|
40
|
+
|
41
|
+
# Update a Visualforce page
|
42
|
+
client.update_apex_page('OldName', :full_name => 'NewName')
|
43
|
+
|
44
|
+
# Delete a Visualforce page
|
45
|
+
client.delete_apex_page('TestPage')
|
37
46
|
```
|
38
47
|
|
39
48
|
## Roadmap
|
@@ -42,7 +51,6 @@ need to be done.
|
|
42
51
|
|
43
52
|
* Implement command line utility that can watch the directory and deploy when a
|
44
53
|
file changes.
|
45
|
-
* Implement CRUD based calls <http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_crud_based_calls_intro.htm>.
|
46
54
|
* Implement some helper methods for diffing metadata.
|
47
55
|
* Ability to deploy directly from a git repository.
|
48
56
|
* And some other stuff that I haven't quite thought of yet...
|
@@ -53,6 +61,10 @@ feature on a new branch, then send me a pull request with a detailed
|
|
53
61
|
description. Please provide applicable rspec specs.
|
54
62
|
|
55
63
|
## Version History
|
64
|
+
**0.5.0** (March 23, 2012)
|
65
|
+
|
66
|
+
* Implemented CRUD calls.
|
67
|
+
|
56
68
|
**0.4.1** (March 8, 2012)
|
57
69
|
|
58
70
|
* Bug fixes
|
@@ -82,7 +94,7 @@ description. Please provide applicable rspec specs.
|
|
82
94
|
|
83
95
|
**0.3.1** (February 3, 2012)
|
84
96
|
|
85
|
-
* Dynamically defined helper methods for .list (e.g. `client.
|
97
|
+
* Dynamically defined helper methods for .list (e.g. `client.list_apex_class`, `client.list_custom_object`).
|
86
98
|
* The `Metaforce::Metadata::Client.describe` method now caches the results to minimize latency. `describe!`
|
87
99
|
can be used to force a refresh.
|
88
100
|
|
data/lib/metaforce.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require 'metaforce/core_extensions/string'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Metaforce
|
2
|
+
module CoreExtensions
|
3
|
+
module String
|
4
|
+
|
5
|
+
def lower_camelcase
|
6
|
+
str = dup
|
7
|
+
str.gsub!(/_[a-z]/) { |a| a.upcase }
|
8
|
+
str.gsub!('_', '')
|
9
|
+
str
|
10
|
+
end unless method_defined?(:lower_camelcase)
|
11
|
+
|
12
|
+
def underscore
|
13
|
+
self.gsub(/::/, '/').
|
14
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
15
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
16
|
+
tr("-", "_").
|
17
|
+
downcase
|
18
|
+
end unless method_defined?(:underscore)
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
String.send :include, Metaforce::CoreExtensions::String
|
data/lib/metaforce/metadata.rb
CHANGED
@@ -43,6 +43,11 @@ module Metaforce
|
|
43
43
|
# client.list([{ :type => "CustomObject" }, { :type => "ApexComponent" }])
|
44
44
|
# #=> ["ContractContactRole", "Solution", "Invoice_Statements__c", ... ]
|
45
45
|
def list(queries=[])
|
46
|
+
if queries.is_a?(Symbol)
|
47
|
+
queries = { :type => queries.to_s.camelcase }
|
48
|
+
elsif queries.is_a?(String)
|
49
|
+
queries = { :type => queries }
|
50
|
+
end
|
46
51
|
queries = [ queries ] unless queries.is_a?(Array)
|
47
52
|
response = @client.request(:list_metadata) do |soap|
|
48
53
|
soap.header = @header
|
@@ -54,28 +59,11 @@ module Metaforce
|
|
54
59
|
response.body[:list_metadata_response][:result]
|
55
60
|
end
|
56
61
|
|
57
|
-
# Defines some helper methods for listing metadata types
|
58
|
-
#
|
59
|
-
# == Examples
|
60
|
-
#
|
61
|
-
# # List the names of all apex classes
|
62
|
-
# client.list_apex_classes.collect { |t| t[:full_name] }
|
63
|
-
# #=> ["al__SObjectPaginatorListenerForTesting", "al__IndexOutOfBoundsException", ... ]
|
64
|
-
#
|
65
|
-
# # List the names of all custom objects
|
66
|
-
# client.list_custom_objects.collect { |t| t[:full_name] }
|
67
|
-
# #=> ["Asset", "estore__Ida_Menu_Item__c", "SfoMatchHistoryItem", ... ]
|
68
|
-
Metaforce::Metadata::Types.all.each do |type, value|
|
69
|
-
define_method("list_#{value[:plural]}".to_sym) do
|
70
|
-
list :type => value[:name]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
62
|
# Describe the organization's metadata and cache the response
|
75
63
|
#
|
76
64
|
# == Examples
|
77
65
|
#
|
78
|
-
# # List the names of all
|
66
|
+
# # List the names of all metadata types
|
79
67
|
# client.describe[:metadata_objects].collect { |t| t[:xml_name] }
|
80
68
|
# #=> ["CustomLabels", "StaticResource", "Scontrol", "ApexComponent", ... ]
|
81
69
|
def describe(version=nil)
|
@@ -91,6 +79,18 @@ module Metaforce
|
|
91
79
|
@describe = response.body[:describe_metadata_response][:result]
|
92
80
|
end
|
93
81
|
|
82
|
+
# Lists all metadata objects on the org. Same as
|
83
|
+
# +client.describe[:metadata_objects]
|
84
|
+
#
|
85
|
+
# == Examples
|
86
|
+
#
|
87
|
+
# # List the names of all metadata types
|
88
|
+
# client.metadata_objects.collect { |t| t[:xml_name] }
|
89
|
+
# #=> ["CustomLabels", "StaticResource", "Scontrol", "ApexComponent", ... ]
|
90
|
+
def metadata_objects(version=nil)
|
91
|
+
describe(version)[:metadata_objects]
|
92
|
+
end
|
93
|
+
|
94
94
|
# Checks the status of an async result. If type is +:retrieve+ or +:deploy+,
|
95
95
|
# it returns the RetrieveResult or DeployResult, respectively
|
96
96
|
#
|
@@ -204,7 +204,15 @@ module Metaforce
|
|
204
204
|
end
|
205
205
|
|
206
206
|
private
|
207
|
-
|
207
|
+
|
208
|
+
def method_missing(name, *args, &block)
|
209
|
+
if name =~ /^list_(.*)$/ && metadata_objects.any? { |m| m[:xml_name] == $1.camelcase }
|
210
|
+
list("#{$1}".to_sym)
|
211
|
+
else
|
212
|
+
super
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
208
216
|
# Creates the deploy file, reads in the contents and returns the base64
|
209
217
|
# encoded data
|
210
218
|
def create_deploy_file(dir)
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module Metaforce
|
4
|
+
module Metadata
|
5
|
+
module CRUD
|
6
|
+
|
7
|
+
# Create metadata
|
8
|
+
#
|
9
|
+
# == Examples
|
10
|
+
#
|
11
|
+
# client.create(:apex_page, :full_name => 'TestPage')
|
12
|
+
def create(type, metadata={})
|
13
|
+
metadata = prepare_metadata(type, metadata)
|
14
|
+
type = type.to_s.camelcase
|
15
|
+
response = @client.request(:create) do |soap|
|
16
|
+
soap.header = @header
|
17
|
+
soap.body = {
|
18
|
+
:metadata => metadata,
|
19
|
+
:attributes! => { "ins0:metadata" => { "xsi:type" => "wsdl:#{type}" } }
|
20
|
+
}
|
21
|
+
end
|
22
|
+
Transaction.new self, response.body[:create_response][:result][:id]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Update metadata
|
26
|
+
#
|
27
|
+
# == Examples
|
28
|
+
#
|
29
|
+
# client.update(:apex_page, 'OldPage', :full_name => 'NewPage')
|
30
|
+
def update(type, current_name, metadata={})
|
31
|
+
metadata = prepare_metadata(type, metadata)
|
32
|
+
type = type.to_s.camelcase
|
33
|
+
response = @client.request(:update) do |soap|
|
34
|
+
soap.header = @header
|
35
|
+
soap.body = {
|
36
|
+
:metadata => {
|
37
|
+
:current_name => current_name,
|
38
|
+
:metadata => metadata,
|
39
|
+
:attributes! => { :metadata => { "xsi:type" => "wsdl:#{type}" } }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
Transaction.new self, response.body[:update_response][:result][:id]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Delete metadata
|
47
|
+
#
|
48
|
+
# == Examples
|
49
|
+
#
|
50
|
+
# client.delete(:apex_page, :full_name => 'TestPage')
|
51
|
+
def delete(type, full_name)
|
52
|
+
full_name = [full_name] unless full_name.is_a?(Array)
|
53
|
+
metadata = []
|
54
|
+
full_name.each do |f|
|
55
|
+
metadata << { :full_name => f }
|
56
|
+
end
|
57
|
+
type = type.to_s.camelcase
|
58
|
+
response = @client.request(:delete) do |soap|
|
59
|
+
soap.header = @header
|
60
|
+
soap.body = {
|
61
|
+
:metadata => metadata,
|
62
|
+
:attributes! => { "ins0:metadata" => { "xsi:type" => "wsdl:#{type}" } }
|
63
|
+
}
|
64
|
+
end
|
65
|
+
Transaction.new self, response.body[:delete_response][:result][:id]
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def prepare_metadata(type, metadata)
|
71
|
+
metadata = [metadata] unless metadata.is_a?(Array)
|
72
|
+
metadata.each_with_index do |m, i|
|
73
|
+
template = Metaforce::Metadata::MetadataFile.template(type)
|
74
|
+
m = template.merge(m) if template
|
75
|
+
metadata[i] = m
|
76
|
+
end
|
77
|
+
metadata = encode_content(metadata)
|
78
|
+
end
|
79
|
+
|
80
|
+
def encode_content(metadata)
|
81
|
+
metadata.each do |m|
|
82
|
+
m[:content] = Base64.encode64(m[:content]) if m.has_key?(:content)
|
83
|
+
end
|
84
|
+
metadata
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_missing(name, *args, &block)
|
88
|
+
if name =~ /^create_(.*)$/
|
89
|
+
create($1.to_sym, *args)
|
90
|
+
elsif name =~ /^update_(.*)$/
|
91
|
+
update($1.to_sym, *args)
|
92
|
+
elsif name =~ /^delete_(.*)$/
|
93
|
+
delete($1.to_sym, *args)
|
94
|
+
else
|
95
|
+
super
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
Metaforce::Metadata::Client.send :include, Metaforce::Metadata::CRUD
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Metaforce
|
4
|
+
module Metadata
|
5
|
+
class MetadataFile < Hash
|
6
|
+
|
7
|
+
# Initialize the underlying hash
|
8
|
+
def initialize(hash, type)
|
9
|
+
super(hash)
|
10
|
+
@type = type
|
11
|
+
replace(hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
def type
|
15
|
+
@type
|
16
|
+
end
|
17
|
+
|
18
|
+
# Builds a new MetadataFile object based on the template
|
19
|
+
#
|
20
|
+
# == Examples
|
21
|
+
#
|
22
|
+
# Metaforce::Metadata::MetadataFile.template(:apex_class)
|
23
|
+
# #=> {:api_version=>"23.0", :status=>"Active"}
|
24
|
+
def self.template(type)
|
25
|
+
Metaforce::Metadata::MetadataFile.new(TEMPLATES[type], type)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the xml representation of the underlying hash structure
|
29
|
+
#
|
30
|
+
# == Examples
|
31
|
+
#
|
32
|
+
# f = Metaforce::Metadata::MetadataFile.template(:apex_class)
|
33
|
+
# f.to_xml
|
34
|
+
# #=> "<?xml version=\"1.0\"?>\n<ApexClass xmlns=\"http://soap.sforce.com/2006/04/metadata\">\n <apiVersion>23.0</apiVersion>\n <status>Active</status>\n</ApexClass>\n"
|
35
|
+
def to_xml
|
36
|
+
xml_builder = Nokogiri::XML::Builder.new do |xml|
|
37
|
+
xml.send(type.to_s.camelcase, "xmlns" => "http://soap.sforce.com/2006/04/metadata") do
|
38
|
+
self.each do |key, value|
|
39
|
+
xml.send(key.to_s.lower_camelcase, value)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
xml_builder.to_xml
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Metadata file templates
|
49
|
+
TEMPLATES = {
|
50
|
+
:apex_class => {
|
51
|
+
:api_version => Metaforce.configuration.api_version,
|
52
|
+
:status => "Active"
|
53
|
+
},
|
54
|
+
:apex_component => {
|
55
|
+
:api_version => Metaforce.configuration.api_version,
|
56
|
+
:description => '',
|
57
|
+
:label => '',
|
58
|
+
:content => "<apex:component>\n</apex:component>"
|
59
|
+
},
|
60
|
+
:apex_page => {
|
61
|
+
:api_version => Metaforce.configuration.api_version,
|
62
|
+
:description => '',
|
63
|
+
:label => '',
|
64
|
+
:content => "<apex:page>\n</apex:page>"
|
65
|
+
},
|
66
|
+
:apex_trigger => {
|
67
|
+
:api_version => Metaforce.configuration.api_version,
|
68
|
+
:status => "Active"
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -84,5 +84,17 @@ module Metaforce
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
BLACK_LIST = [:@client]
|
88
|
+
|
89
|
+
def to_s
|
90
|
+
public_vars = self.instance_variables.reject { |var|
|
91
|
+
BLACK_LIST.include? var
|
92
|
+
}.map { |var|
|
93
|
+
"#{var}=\"#{instance_variable_get(var)}\""
|
94
|
+
}.join(" ")
|
95
|
+
|
96
|
+
"<##{self.class}:#{self.object_id.to_s(8)} #{public_vars}>"
|
97
|
+
end
|
98
|
+
|
87
99
|
end
|
88
100
|
end
|
@@ -27,8 +27,10 @@ module Metaforce
|
|
27
27
|
password = "#{password}#{security_token}" unless security_token.nil?
|
28
28
|
client = Savon::Client.new File.expand_path("../../../../wsdl/#{Metaforce.configuration.api_version}/partner.xml", __FILE__) do |wsdl|
|
29
29
|
wsdl.endpoint = wsdl.endpoint.to_s.sub(/login/, 'test') if Metaforce.configuration.test
|
30
|
+
Metaforce.log("Logging in via #{wsdl.endpoint.to_s}")
|
30
31
|
end
|
31
32
|
client.http.auth.ssl.verify_mode = :none
|
33
|
+
|
32
34
|
response = client.request(:login) do
|
33
35
|
soap.body = {
|
34
36
|
:username => username,
|
data/lib/metaforce/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata">
|
3
|
+
<soapenv:Body>
|
4
|
+
<createResponse>
|
5
|
+
<result>
|
6
|
+
<done>false</done>
|
7
|
+
<id>04sU0000000WNWoIAO</id>
|
8
|
+
<state>InProgress</state>
|
9
|
+
</result>
|
10
|
+
</createResponse>
|
11
|
+
</soapenv:Body>
|
12
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata">
|
3
|
+
<soapenv:Body>
|
4
|
+
<deleteResponse>
|
5
|
+
<result>
|
6
|
+
<done>false</done>
|
7
|
+
<id>04sU0000000WNWoIAO</id>
|
8
|
+
<state>InProgress</state>
|
9
|
+
</result>
|
10
|
+
</deleteResponse>
|
11
|
+
</soapenv:Body>
|
12
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata">
|
3
|
+
<soapenv:Body>
|
4
|
+
<updateResponse>
|
5
|
+
<result>
|
6
|
+
<done>false</done>
|
7
|
+
<id>04sU0000000WNWoIAO</id>
|
8
|
+
<state>InProgress</state>
|
9
|
+
</result>
|
10
|
+
</updateResponse>
|
11
|
+
</soapenv:Body>
|
12
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe String do
|
4
|
+
|
5
|
+
describe ".lower_camelcase" do
|
6
|
+
it "camelCases underscored_words" do
|
7
|
+
"hello_world".lower_camelcase.should eq("helloWorld")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".camelcase" do
|
12
|
+
it "CamelCases underscored_words" do
|
13
|
+
"hello_world".camelcase.should eq("HelloWorld")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".underscore" do
|
18
|
+
it "underscores CamelCased words" do
|
19
|
+
"HelloWorld".underscore.should eq("hello_world")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -23,12 +23,24 @@ describe Metaforce::Metadata::Client do
|
|
23
23
|
client.list(:type => "ApexClass").should be_an(Array)
|
24
24
|
end
|
25
25
|
|
26
|
+
it "accepts a symbol" do
|
27
|
+
savon.expects(:list_metadata).with(:queries => [ :type => "ApexClass"]).returns(:no_result)
|
28
|
+
client.list(:apex_class).should be_an(Array)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "accepts a string" do
|
32
|
+
savon.expects(:list_metadata).with(:queries => [ :type => "ApexClass"]).returns(:no_result)
|
33
|
+
client.list("ApexClass").should be_an(Array)
|
34
|
+
end
|
35
|
+
|
26
36
|
end
|
27
37
|
|
28
38
|
it "should respond to dynamically defined list methods" do
|
29
|
-
|
30
|
-
|
31
|
-
|
39
|
+
savon.expects(:describe_metadata).returns(:success)
|
40
|
+
savon.expects(:list_metadata).with(:queries => [ :type => "ApexClass"]).returns(:no_result)
|
41
|
+
client.list_apex_class.should be_an(Array)
|
42
|
+
|
43
|
+
expect { client.list_undefined_type }.to raise_error(NoMethodError)
|
32
44
|
end
|
33
45
|
|
34
46
|
describe ".describe" do
|
@@ -48,6 +60,13 @@ describe Metaforce::Metadata::Client do
|
|
48
60
|
end
|
49
61
|
end
|
50
62
|
|
63
|
+
describe ".metadata_objects" do
|
64
|
+
it "returns the :metadata_objects key from the describe call" do
|
65
|
+
savon.expects(:describe_metadata).returns(:success)
|
66
|
+
client.metadata_objects.should be_a(Array)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
51
70
|
describe ".describe!" do
|
52
71
|
context "when given valid information" do
|
53
72
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Metaforce::Metadata::Client do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
savon.expects(:login).with(:username => 'valid', :password => 'password').returns(:success)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:client) do
|
10
|
+
Metaforce::Metadata::Client.new(:username => 'valid', :password => 'password')
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".create" do
|
14
|
+
it "returns a transaction" do
|
15
|
+
savon.expects(:create).with(:metadata => [{:api_version => '23.0', :description => '', :label => 'test', :content => '', :full_name => 'component'}], :attributes! => {'ins0:metadata' => {'xsi:type' => 'wsdl:ApexComponent'}}).returns(:in_progress)
|
16
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
17
|
+
response = client.create(:apex_component, :full_name => 'component', :label => 'test', :content => '')
|
18
|
+
response.should be_a(Metaforce::Transaction)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "base64 encodes any content" do
|
22
|
+
savon.expects(:create).with(:metadata => [{:api_version => '23.0', :description => '', :full_name => 'component', :label => 'test', :content => "dGVzdA==\n"}], :attributes! => {'ins0:metadata' => {'xsi:type' => 'wsdl:ApexComponent'}}).returns(:in_progress)
|
23
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
24
|
+
response = client.create(:apex_component, :full_name => 'component', :label => 'test', :content => 'test')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "responds to method missing" do
|
28
|
+
savon.expects(:create).with(:metadata => [{:api_version => '23.0', :description => '', :label => 'test', :content => '', :full_name => 'component'}], :attributes! => {'ins0:metadata' => {'xsi:type' => 'wsdl:ApexComponent'}}).returns(:in_progress)
|
29
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
30
|
+
response = client.create_apex_component(:full_name => 'component', :label => 'test', :content => '')
|
31
|
+
response.should be_a(Metaforce::Transaction)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".delete" do
|
36
|
+
it "returns a transaction" do
|
37
|
+
savon.expects(:delete).with(:metadata => [{:full_name => 'component'}], :attributes! => {'ins0:metadata' => {'xsi:type' => 'wsdl:ApexComponent'}}).returns(:in_progress)
|
38
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
39
|
+
response = client.delete(:apex_component, 'component')
|
40
|
+
response.should be_a(Metaforce::Transaction)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "responds to method missing" do
|
44
|
+
savon.expects(:delete).with(:metadata => [{:full_name => 'component'}], :attributes! => {'ins0:metadata' => {'xsi:type' => 'wsdl:ApexComponent'}}).returns(:in_progress)
|
45
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
46
|
+
response = client.delete_apex_component('component')
|
47
|
+
response.should be_a(Metaforce::Transaction)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ".update" do
|
52
|
+
it "returns a transaction" do
|
53
|
+
savon.expects(:update).with(:metadata => {:current_name => 'old_component', :metadata => [{:api_version => '23.0', :description => '', :label => 'test', :content => '', :full_name => 'component'}], :attributes! => {:metadata => {'xsi:type' => 'wsdl:ApexComponent'}}}).returns(:in_progress)
|
54
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
55
|
+
response = client.update(:apex_component, 'old_component', :full_name => 'component', :label => 'test', :content => '')
|
56
|
+
response.should be_a(Metaforce::Transaction)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "responds to method missing" do
|
60
|
+
savon.expects(:update).with(:metadata => {:current_name => 'old_component', :metadata => [{:api_version => '23.0', :description => '', :label => 'test', :content => '', :full_name => 'component'}], :attributes! => {:metadata => {'xsi:type' => 'wsdl:ApexComponent'}}}).returns(:in_progress)
|
61
|
+
savon.expects(:check_status).with(:ids => ['04sU0000000WNWoIAO']).returns(:done);
|
62
|
+
response = client.update_apex_component('old_component', :full_name => 'component', :label => 'test', :content => '')
|
63
|
+
response.should be_a(Metaforce::Transaction)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Metaforce::Metadata::MetadataFile do
|
4
|
+
describe "#template" do
|
5
|
+
it "returns a hash" do
|
6
|
+
file = Metaforce::Metadata::MetadataFile.template(:apex_page)
|
7
|
+
file.should be_a(Hash)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".to_xml" do
|
12
|
+
it "returns a string representation of the hash" do
|
13
|
+
file = Metaforce::Metadata::MetadataFile.template(:apex_page)
|
14
|
+
file.to_xml.should be_a(String)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metaforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &70320535767740 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 1.5.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70320535767740
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: savon
|
27
|
-
requirement: &
|
27
|
+
requirement: &70320535767240 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 0.9.7
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70320535767240
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rubyzip
|
38
|
-
requirement: &
|
38
|
+
requirement: &70320535744500 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.9.5
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70320535744500
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: term-ansicolor
|
49
|
-
requirement: &
|
49
|
+
requirement: &70320535744120 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70320535744120
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
requirement: &
|
60
|
+
requirement: &70320535743580 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70320535743580
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &70320535743020 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70320535743020
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: mocha
|
82
|
-
requirement: &
|
82
|
+
requirement: &70320535742560 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70320535742560
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: savon_spec
|
93
|
-
requirement: &
|
93
|
+
requirement: &70320535742000 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: 0.1.6
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70320535742000
|
102
102
|
description: A Ruby gem for interacting with the Salesforce Metadata API
|
103
103
|
email:
|
104
104
|
- eric@ejholmes.net
|
@@ -114,10 +114,14 @@ files:
|
|
114
114
|
- Rakefile
|
115
115
|
- lib/metaforce.rb
|
116
116
|
- lib/metaforce/config.rb
|
117
|
+
- lib/metaforce/core_extensions.rb
|
118
|
+
- lib/metaforce/core_extensions/string.rb
|
117
119
|
- lib/metaforce/error.rb
|
118
120
|
- lib/metaforce/manifest.rb
|
119
121
|
- lib/metaforce/metadata.rb
|
120
122
|
- lib/metaforce/metadata/client.rb
|
123
|
+
- lib/metaforce/metadata/crud.rb
|
124
|
+
- lib/metaforce/metadata/file.rb
|
121
125
|
- lib/metaforce/metadata/transaction.rb
|
122
126
|
- lib/metaforce/rake.rb
|
123
127
|
- lib/metaforce/rake/deploy.rb
|
@@ -137,6 +141,8 @@ files:
|
|
137
141
|
- spec/fixtures/requests/check_retrieve_status/success.xml
|
138
142
|
- spec/fixtures/requests/check_status/done.xml
|
139
143
|
- spec/fixtures/requests/check_status/not_done.xml
|
144
|
+
- spec/fixtures/requests/create/in_progress.xml
|
145
|
+
- spec/fixtures/requests/delete/in_progress.xml
|
140
146
|
- spec/fixtures/requests/deploy/in_progress.xml
|
141
147
|
- spec/fixtures/requests/describe_metadata/success.xml
|
142
148
|
- spec/fixtures/requests/list_metadata/no_result.xml
|
@@ -144,16 +150,20 @@ files:
|
|
144
150
|
- spec/fixtures/requests/login/failure.xml
|
145
151
|
- spec/fixtures/requests/login/success.xml
|
146
152
|
- spec/fixtures/requests/retrieve/in_progress.xml
|
153
|
+
- spec/fixtures/requests/update/in_progress.xml
|
147
154
|
- spec/fixtures/sample/Rakefile
|
148
155
|
- spec/fixtures/sample/metaforce.yml
|
149
156
|
- spec/fixtures/sample/src/classes/TestClass.cls
|
150
157
|
- spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
|
151
158
|
- spec/fixtures/sample/src/package.xml
|
152
159
|
- spec/lib/config_spec.rb
|
160
|
+
- spec/lib/core_extensions/string_spec.rb
|
153
161
|
- spec/lib/manifest_spec.rb
|
154
|
-
- spec/lib/metadata/
|
162
|
+
- spec/lib/metadata/client_spec.rb
|
163
|
+
- spec/lib/metadata/crud_spec.rb
|
164
|
+
- spec/lib/metadata/file_spec.rb
|
155
165
|
- spec/lib/metadata/transaction_spec.rb
|
156
|
-
- spec/lib/services/
|
166
|
+
- spec/lib/services/client_spec.rb
|
157
167
|
- spec/spec_helper.rb
|
158
168
|
- wsdl/23.0/metadata.xml
|
159
169
|
- wsdl/23.0/partner.xml
|
@@ -188,6 +198,8 @@ test_files:
|
|
188
198
|
- spec/fixtures/requests/check_retrieve_status/success.xml
|
189
199
|
- spec/fixtures/requests/check_status/done.xml
|
190
200
|
- spec/fixtures/requests/check_status/not_done.xml
|
201
|
+
- spec/fixtures/requests/create/in_progress.xml
|
202
|
+
- spec/fixtures/requests/delete/in_progress.xml
|
191
203
|
- spec/fixtures/requests/deploy/in_progress.xml
|
192
204
|
- spec/fixtures/requests/describe_metadata/success.xml
|
193
205
|
- spec/fixtures/requests/list_metadata/no_result.xml
|
@@ -195,15 +207,19 @@ test_files:
|
|
195
207
|
- spec/fixtures/requests/login/failure.xml
|
196
208
|
- spec/fixtures/requests/login/success.xml
|
197
209
|
- spec/fixtures/requests/retrieve/in_progress.xml
|
210
|
+
- spec/fixtures/requests/update/in_progress.xml
|
198
211
|
- spec/fixtures/sample/Rakefile
|
199
212
|
- spec/fixtures/sample/metaforce.yml
|
200
213
|
- spec/fixtures/sample/src/classes/TestClass.cls
|
201
214
|
- spec/fixtures/sample/src/classes/TestClass.cls-meta.xml
|
202
215
|
- spec/fixtures/sample/src/package.xml
|
203
216
|
- spec/lib/config_spec.rb
|
217
|
+
- spec/lib/core_extensions/string_spec.rb
|
204
218
|
- spec/lib/manifest_spec.rb
|
205
|
-
- spec/lib/metadata/
|
219
|
+
- spec/lib/metadata/client_spec.rb
|
220
|
+
- spec/lib/metadata/crud_spec.rb
|
221
|
+
- spec/lib/metadata/file_spec.rb
|
206
222
|
- spec/lib/metadata/transaction_spec.rb
|
207
|
-
- spec/lib/services/
|
223
|
+
- spec/lib/services/client_spec.rb
|
208
224
|
- spec/spec_helper.rb
|
209
225
|
has_rdoc:
|