icims_client 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+ gem "xml-simple", ">= 1.1.1"
6
+ gem "rest-client", ">= 1.6.7"
7
+ gem "nokogiri", ">= 1.5.0"
8
+ gem "sanitize", ">= 2.0.3"
9
+
10
+ # Add dependencies to develop your gem here.
11
+ # Include everything needed to run rake, tests, features, etc.
12
+ group :development do
13
+ gem "shoulda", ">= 0"
14
+ gem "bundler", "~> 1.0.0"
15
+ gem "jeweler", "~> 1.6.4"
16
+ gem "rcov", ">= 0"
17
+ gem "rdoc", ">= 3.11"
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Chris Alef
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,19 @@
1
+ = icims_client
2
+
3
+ icims_client implements a dead simple client, with minimal dependencies, for calling iCIMS web services from ruby. This is not intended as a enterprise-class integration library for iCIMS.
4
+
5
+ == Contributing to icims_client
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Chris Alef. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "icims_client"
18
+ # gem.homepage = "http://github.com/calef/icims_client"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{a simple client for iCIMS web services.}
21
+ gem.description = %Q{icims_client implements a dead simple client, with minimal dependencies, for calling iCIMS web services from ruby. This is not intended as a enterprise-class integration library for iCIMS.}
22
+ gem.email = "chrisale@amazon.com"
23
+ gem.authors = ["Christopher Alef"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "icims_client #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,210 @@
1
+ require 'restclient'
2
+ require 'xmlsimple'
3
+ require 'uri'
4
+ require 'nokogiri'
5
+ require 'sanitize'
6
+
7
+ #
8
+ # Client to the iCIMS talent platform.
9
+ #
10
+ # Synopsis:
11
+ #
12
+ # client = IcimsClient.new(endpoint,username,password)
13
+ # job = client.job_from_system_id(system_id)
14
+ # assert system_id, job.get_attribute('SystemId')
15
+ # assert jcf1234_value, job.get_custom_field('jcf1234')
16
+ #
17
+ module IcimsClient
18
+
19
+ #
20
+ # A client with methods for each service call.
21
+ # Contructor takes endpoint, username, password
22
+ #
23
+ class IcimsClient
24
+
25
+ #
26
+ # given a single system_id returns a single IcimsJob
27
+ #
28
+ def job_from_system_id(system_id)
29
+ response_body = job_response_body(job_request_body(system_id))
30
+ return job_from_response_body(response_body)
31
+ end
32
+
33
+ private
34
+
35
+ #
36
+ # constructs a client from the endpoint, username, and password
37
+ #
38
+ def initialize(url, username, password)
39
+ @username = username
40
+ @password = password
41
+ @url = url
42
+ end
43
+
44
+ #
45
+ # get the IcimsJob from the provided HTTP response body
46
+ #
47
+ def job_from_response_body(response_body)
48
+ response = XmlSimple.xml_in(response_body, { 'KeyAttr' => 'name' })
49
+ raise 'XML transformation of response failed' unless response
50
+ result = response['Body'].first['GetResponse'].first['Result'].first
51
+ raise 'SOAP response was a failure' unless result['Success'].first == 'true'
52
+ return IcimsJob.new(result['JobRecord'].first)
53
+ end
54
+
55
+ #
56
+ # get the HTTP request body for a job request for the provided system_id
57
+ #
58
+ def job_request_body(system_id)
59
+
60
+ #this is icky because there isn't a great gem that implements WS-Security so we
61
+ #compose the XML by hand
62
+ return <<EOF
63
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://api.icims.com/v1">
64
+ <soapenv:Header>
65
+ <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
66
+ <wsse:UsernameToken wsu:Id="UsernameToken-5151722" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
67
+ <wsse:Username>#{@username}</wsse:Username>
68
+ <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">#{@password}</wsse:Password>
69
+ </wsse:UsernameToken>
70
+ </wsse:Security>
71
+ </soapenv:Header>
72
+ <soapenv:Body>
73
+ <v1:GetRequest>
74
+ <v1:JobReference><v1:SystemId>#{system_id}</v1:SystemId></v1:JobReference>
75
+ </v1:GetRequest>
76
+ </soapenv:Body>
77
+ </soapenv:Envelope>
78
+ EOF
79
+ end
80
+
81
+ #
82
+ #get the HTTP response body for the job response for the provided request body
83
+ #
84
+ def job_response_body(request_body)
85
+ RestClient.post @url, request_body, :content_type => 'text/xml'
86
+ end
87
+
88
+ end
89
+
90
+ #
91
+ # A job container with methods to retrieve attribute and custom field values.
92
+ #
93
+ class IcimsJob
94
+
95
+ #
96
+ # customers a job from a job_record data structure generated from the SOAP
97
+ # response as serialized by xml-simple
98
+ #
99
+ def initialize(job_record)
100
+ @job_record = job_record
101
+ end
102
+
103
+ #
104
+ # Returns the value for the provided attribute key. nil if there is no such attribute.
105
+ #
106
+ def get_attribute(key)
107
+
108
+ #I wish ruby had a safe navigation operator
109
+ begin
110
+ return IcimsAttributeValue.new(@job_record[key][0])
111
+ rescue
112
+ return nil
113
+ end
114
+ end
115
+
116
+ #
117
+ # Returns the Industry levels as an IcimsAttributeArray
118
+ #
119
+ def get_industry_levels
120
+ begin
121
+ return IcimsAttributeArray.new(@job_record['Industry'].first['Level'])
122
+ rescue
123
+ return IcimsAttributeArray.new()
124
+ end
125
+ end
126
+
127
+ #
128
+ # Returns the value for the provided custom field key. nil if there is no such attribute.
129
+ #
130
+ def get_custom_field(key)
131
+
132
+ #I wish ruby had a safe navigation operator
133
+ begin
134
+ return IcimsAttributeValue.new(@job_record['CustomField'][key]['content'])
135
+ rescue
136
+ return nil
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ #
143
+ # An attribute value as returned by IcimsJob methods
144
+ #
145
+ class IcimsAttributeValue < String
146
+
147
+ #
148
+ # Executes a custom HTML entity translation based upon organizational bias/preference
149
+ #
150
+ def custom_html_entity_translation!
151
+
152
+ #We have an ASCII bias on certain HTML entity translations, even though
153
+ #they're technically inaccurate. This is because we're commonly displaying in web pages
154
+ #and browsers (still) inconsistently implement these characters
155
+ self.gsub!(/&nbsp;/, ' ')
156
+ self.gsub!(/&rsquo;/, '\'')
157
+ self.gsub!(/&lsquo;/, '\'')
158
+ end
159
+
160
+ #
161
+ # Strips leading and trailing whitespace. Turns multiple internal whitespace
162
+ # characters to a single space.
163
+ #
164
+ def minify_whitespace!
165
+ #strip leading/tailing whitespace.
166
+ self.strip!
167
+
168
+ #eliminate multiple whitespace characters
169
+ self.gsub!(/\s{2,}/, ' ')
170
+ end
171
+
172
+ #
173
+ # Returns a sanitized IcimsAttributeValue. Idempotent.
174
+ #
175
+ def sanitize
176
+
177
+ self.custom_html_entity_translation!
178
+
179
+ #strip out all of the HTML tags, but entities are preserved
180
+ sanitized_string = Sanitize.clean(self)
181
+
182
+ # convert HTML entities to text
183
+ # We can't use this to strip HTML tags because critical whitespace is eliminated
184
+ # causing nastiness like wordsandparagraphsflowingtogether
185
+ sanitized_attr = IcimsAttributeValue.new(Nokogiri::HTML(sanitized_string).text)
186
+ sanitized_attr.minify_whitespace!
187
+ return sanitized_attr
188
+
189
+ end
190
+
191
+ end
192
+
193
+ #
194
+ # An IcimsAttributeArray as returned by IcimsJob methods
195
+ #
196
+ class IcimsAttributeArray < Array
197
+
198
+ #
199
+ # returns
200
+ #
201
+ def sanitize
202
+ sanitized_array = Array.new
203
+ self.each{|value|
204
+ sanitized_array.push(IcimsAttributeValue.new(value).sanitize)
205
+ }
206
+ return sanitized_array
207
+ end
208
+ end
209
+
210
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'icims_client'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,190 @@
1
+ require 'helper'
2
+
3
+ class TestIcimsClient < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @url = 'https://dummy.icims.com/api/v1/data'
7
+ @password = 'password'
8
+ @request_body = <<EOF
9
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://api.icims.com/v1">
10
+ <soapenv:Header>
11
+ <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
12
+ <wsse:UsernameToken wsu:Id="UsernameToken-5151722" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
13
+ <wsse:Username>username</wsse:Username>
14
+ <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
15
+ </wsse:UsernameToken>
16
+ </wsse:Security>
17
+ </soapenv:Header>
18
+ <soapenv:Body>
19
+ <v1:GetRequest>
20
+ <v1:JobReference><v1:SystemId>149522</v1:SystemId></v1:JobReference>
21
+ </v1:GetRequest>
22
+ </soapenv:Body>
23
+ </soapenv:Envelope>
24
+ EOF
25
+ @response_body = <<EOF
26
+ <?xml version="1.0"?>
27
+ <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
28
+ <SOAP-ENV:Header>
29
+ <RateLimitMax xmlns="http://api.icims.com/v1">2500000</RateLimitMax>
30
+ <RateLimitRemaining xmlns="http://api.icims.com/v1">2499998</RateLimitRemaining>
31
+ <RateLimitReset xmlns="http://api.icims.com/v1">4167</RateLimitReset>
32
+ </SOAP-ENV:Header>
33
+ <SOAP-ENV:Body>
34
+ <GetResponse xmlns="http://api.icims.com/v1">
35
+ <Result>
36
+ <Success>true</Success>
37
+ <JobRecord>
38
+ <CreatedByEmail>mercedes@foo.com</CreatedByEmail>
39
+ <CreatedByExternalId>448611</CreatedByExternalId>
40
+ <CreatedByFirstName>Mercedes</CreatedByFirstName>
41
+ <CreatedByLastName>Benz</CreatedByLastName>
42
+ <CreatedBySystemId>894140</CreatedBySystemId>
43
+ <CreatedDate>8/8/2011 10:20:04</CreatedDate>
44
+ <DisplayId>149522</DisplayId>
45
+ <Folder>Open</Folder>
46
+ <HireType>New Position</HireType>
47
+ <HmEmail>christina@foo.com</HmEmail>
48
+ <HmExternalId>344747</HmExternalId>
49
+ <HmFirstName>Christina</HmFirstName>
50
+ <HmLastName>Ricci</HmLastName>
51
+ <HmSystemId>594134</HmSystemId>
52
+ <Industry>
53
+ <Level>5620 - Category Mgmt - Health &amp; Beauty</Level>
54
+ <Level>QS_ID - Project Boardwalk</Level>
55
+ <Level>Consumables</Level>
56
+ <Level>North America Retail - Smithers</Level>
57
+ </Industry>
58
+ <JobCompanyEmail>project@dummyaddress.com</JobCompanyEmail>
59
+ <JobCompanyExternalId>B75</JobCompanyExternalId>
60
+ <JobCompanyFirstName>Foo.com</JobCompanyFirstName>
61
+ <JobCompanySystemId>93590</JobCompanySystemId>
62
+ <JobLocationCity>Jersey City</JobLocationCity>
63
+ <JobLocationCountry>US</JobLocationCountry>
64
+ <JobLocationState>NJ</JobLocationState>
65
+ <JobLocationStreet>Boardwalk 1</JobLocationStreet>
66
+ <JobLocationStreet2>330 - USA</JobLocationStreet2>
67
+ <JobNumber>DJOB</JobNumber>
68
+ <JobTitle>Site Leader, Home</JobTitle>
69
+ <JobType>F - Regular Full Time - 40 hours</JobType>
70
+ <OpenPositions>1</OpenPositions>
71
+ <Overview>&lt;p style="margin: 0px"&gt;As one of the fastest growing e-commerce companies in the country, &lt;strong&gt;Quidsi&lt;/strong&gt; is the parent company of &lt;a href="http://www.diapers.com/" target="_blank"&gt;Diapers.com&lt;/a&gt; (baby care), &lt;a href="http://www.soap.com/" target="_blank"&gt;Soap.com&lt;/a&gt; (health, beauty and household essentials), &lt;a href="http://www.beautybar.com/" target="_blank"&gt;BeautyBar.com&lt;/a&gt; (prestige beauty), &lt;a href="http://www.wag.com/" target="_blank"&gt;Wag.com&lt;/a&gt; (pet products) and &lt;a href="http://www.yoyo.com/" target="_blank"&gt;YoYo.com&lt;/a&gt; (toys). We like to work hard and play hard, always striving to improve our business, our people, our culture and the experience for our customers. If this sounds like something you would like to be a part of, the next step is yours. Send us your resume and come join a group of critical thinkers and innovators energized by the passion to explore "what if" (the meaning of Quidsi in Latin). For more information&amp;nbsp;about&amp;nbsp;our company, please go to&amp;nbsp;&lt;a href="http://www.quidsi.com/" target="_blank"&gt;www.Quidsi.com&lt;/a&gt;.&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;We&amp;rsquo;re looking for an experienced professional that has a passion for&amp;nbsp;home products&amp;nbsp;and can convert that&amp;nbsp; passion into leading the front end management, including the marketing and merchandising, of our soon to be launched &amp;lsquo;Home&amp;rsquo; site.&amp;nbsp; The right candidate will thrive in a highly entrepreneurial, fast-changing, and collaborative environment where people are driven, enthusiastic, and not afraid to take risks.&amp;nbsp; This individual will be responsible for overall site strategy, and for driving growth and profitability through new customer acquisition, customer relationship management &amp;amp; retention, assortment planning, on-site merchandising, vendor management, and inventory management.&amp;nbsp; We want you to apply if you have a commitment to action-oriented analysis, a relentless passion for results, and the belief that anything is possible.&amp;nbsp; &amp;nbsp;&lt;/p&gt;</Overview>
72
+ <OwnerEmail>patrick@foo.com</OwnerEmail>
73
+ <OwnerExternalId>451855</OwnerExternalId>
74
+ <OwnerFirstName>Patrick</OwnerFirstName>
75
+ <OwnerLastName>Saint</OwnerLastName>
76
+ <OwnerSystemId>5134398</OwnerSystemId>
77
+ <PositionCategory>
78
+ <Level>Buying/Planning</Level>
79
+ </PositionCategory>
80
+ <PositionType>Regular</PositionType>
81
+ <Qualifications>&lt;li&gt;Strong business judgment with a track record of success&lt;/li&gt;&lt;li&gt;Ability to work autonomously in a highly demanding and often ambiguous environment&lt;/li&gt;&lt;li&gt;Exceptional analytical ability&lt;/li&gt;&lt;li&gt;Track record of strong relationship management, internal and external&lt;/li&gt;&lt;li&gt;Entrepreneurial spirit&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This position is conveniently located in Jersey City, NJ, a four minute ride from the World Trade Center and just outside the Exchange Place PATH Station. Bordering the Hudson River, our offices have spectacular panoramic views of Manhattan and New Jersey. &lt;br /&gt;&lt;br /&gt;Quidsi Inc is an Equal Opportunity Employer&lt;br /&gt;&lt;br /&gt;.mrch.mkt.hm1.crp.jc.&lt;/li&gt;</Qualifications>
82
+ <RecEmail>mercedes@foo.com</RecEmail>
83
+ <RecExternalId>144861</RecExternalId>
84
+ <RecFirstName>Mercedes</RecFirstName>
85
+ <RecLastName>Benz</RecLastName>
86
+ <RecSystemId>894140</RecSystemId>
87
+ <Responsibilities>&lt;ul&gt;&lt;li&gt;MBA preferred&lt;/li&gt;&lt;li&gt;Minimum 7-8 years of relevant experience&lt;/li&gt;&lt;/ul&gt;</Responsibilities>
88
+ <StartDate>1/9/2012</StartDate>
89
+ <SystemId>149522</SystemId>
90
+ <UpdatedByEmail>tennille@foo.com</UpdatedByEmail>
91
+ <UpdatedByExternalId>649434</UpdatedByExternalId>
92
+ <UpdatedByFirstName>Tennille</UpdatedByFirstName>
93
+ <UpdatedByLastName>Captain</UpdatedByLastName>
94
+ <UpdatedBySystemId>5132308</UpdatedBySystemId>
95
+ <UpdatedDate>11/9/2011 11:25:51</UpdatedDate>
96
+ <CustomField name="jcf2001">N/A</CustomField>
97
+ <CustomField name="jcf2002">Yes</CustomField>
98
+ <CustomField name="jcf2007">40</CustomField>
99
+ <CustomField name="jcf2054">41165</CustomField>
100
+ <CustomField name="jcf2056">New vertical launch</CustomField>
101
+ <CustomField name="jcf2057">No</CustomField>
102
+ <CustomField name="jcf2058">Yes</CustomField>
103
+ <CustomField name="jcf2060">18395</CustomField>
104
+ <CustomField name="jcf2063">Site Leader, Home</CustomField>
105
+ <CustomField name="jcf2086">24917</CustomField>
106
+ <CustomField name="jcf2089">25811</CustomField>
107
+ <CustomField name="jcf2090">Yes</CustomField>
108
+ <CustomField name="jcf2133">1323085</CustomField>
109
+ <CustomField name="jcf2146">Yes</CustomField>
110
+ <CustomField name="jcf2148">Corporate</CustomField>
111
+ <CustomField name="jcf2150">No</CustomField>
112
+ <CustomField name="jcf3023">941408</CustomField>
113
+ <CustomField name="jcf3024">1343985</CustomField>
114
+ <CustomField name="jcf3035">&lt;p style="margin: 0px"&gt;As one of the fastest growing e-commerce companies in the country, &lt;strong&gt;Quidsi&lt;/strong&gt; is the parent company of &lt;a href="http://www.diapers.com/" target="_blank"&gt;Diapers.com&lt;/a&gt; (baby care), &lt;a href="http://www.soap.com/" target="_blank"&gt;Soap.com&lt;/a&gt; (health, beauty and household essentials), &lt;a href="http://www.beautybar.com/" target="_blank"&gt;BeautyBar.com&lt;/a&gt; (prestige beauty), &lt;a href="http://www.wag.com/" target="_blank"&gt;Wag.com&lt;/a&gt; (pet products) and &lt;a href="http://www.yoyo.com/" target="_blank"&gt;YoYo.com&lt;/a&gt; (toys). We like to work hard and play hard, always striving to improve our business, our people, our culture and the experience for our customers. If this sounds like something you would like to be a part of, the next step is yours. Send us your resume and come join a group of critical thinkers and innovators energized by the passion to explore "what if" (the meaning of Quidsi in Latin). For more information&amp;nbsp;about&amp;nbsp;our company, please go to&amp;nbsp;&lt;a href="http://www.quidsi.com/" target="_blank"&gt;www.Quidsi.com&lt;/a&gt;.&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;We&amp;rsquo;re looking for an experienced professional that has a passion for&amp;nbsp;home products&amp;nbsp;and can convert that&amp;nbsp; passion into leading the front end management, including the marketing and merchandising, of our soon to be launched &amp;lsquo;Home&amp;rsquo; site.&amp;nbsp; The right candidate will thrive in a highly entrepreneurial, fast-changing, and collaborative environment where people are driven, enthusiastic, and not afraid to take risks.&amp;nbsp; This individual will be responsible for overall site strategy, and for driving growth and profitability through new customer acquisition, customer relationship management &amp;amp; retention, assortment planning, on-site merchandising, vendor management, and inventory management.&amp;nbsp; We want you to apply if you have a commitment to action-oriented analysis, a relentless passion for results, and the belief that anything is possible.&amp;nbsp; &amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;STRATEGIC PLANNING&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Set strategic vision for the site and the consumer value proposition&lt;/li&gt;&lt;li&gt;Define and steward the brand&lt;/li&gt;&lt;li&gt;Responsible for the overall P&amp;amp;L, including net revenue, gross margin, and contributed profit&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;NEW CUSTOMER ACQUISITION&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Identify key acquisition strategies to aggressively but efficiently drive growth, including offer strategy&lt;/li&gt;&lt;li&gt;Make spending decisions across a range of marketing channels, partnerships, and customer segments &lt;/li&gt;&lt;li&gt;Highly metrics-driven analysis of channel performance and program results&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;CRM/RETENTION&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Harness the data to carefully understand customer lifetime value and underlying purchase behavior&lt;/li&gt;&lt;li&gt;Define strategies to maximize customer retention and lifetime value, including loyalty programs&lt;/li&gt;&lt;li&gt;Oversee CRM efforts, including email marketing and offer testing&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;ASSORTMENT PLANNING AND MERCHANDISING STRATEGY&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Articulate the assortment strategy and drive expansion&lt;/li&gt;&lt;li&gt;Develop effective pricing and merchandising strategies to maximize contributed profit&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;ONLINE MERCHANDISING&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Define strategies to optimize the on-site shopping experience, and partner with the User Experience &amp;amp; Design team to deliver on them&lt;/li&gt;&lt;li&gt;Leverage on-site opportunities to effectively drive cross-sell/up-sell&lt;/li&gt;&lt;li&gt;Determine approach to vendor marketing/advertising to capture incremental vendor funding&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;VENDOR MANAGEMENT&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Work closely with a defined set of strategic vendors to negotiate best terms, develop new incentive programs, and ensure a reliable and operationally effective flow of goods to our fulfillment centers&lt;/li&gt;&lt;li&gt;Drive profitability through accurate forecasting and close monitoring of procurement margin &lt;/li&gt;&lt;/ul&gt;&lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;strong&gt;INVENTORY &amp;amp; SUPPLY CHAIN MANAGEMENT&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Partner with supply chain to forecast sales and procure inventory required to support sales and promotions and achieve in-stock rate goals&lt;/li&gt;&lt;li&gt;Partner with supply chain team to manage inventory health, including exit strategies for unproductive inventory&lt;/li&gt;&lt;/ul&gt;</CustomField>
115
+ <CustomField name="jcf3036">&lt;ul&gt;&lt;li&gt;MBA preferred&lt;/li&gt;&lt;li&gt;Minimum 7-8 years of relevant experience&lt;/li&gt;&lt;/ul&gt;</CustomField>
116
+ <CustomField name="jcf3037">&lt;li&gt;Strong business judgment with a track record of success&lt;/li&gt;&lt;li&gt;Ability to work autonomously in a highly demanding and often ambiguous environment&lt;/li&gt;&lt;li&gt;Exceptional analytical ability&lt;/li&gt;&lt;li&gt;Track record of strong relationship management, internal and external&lt;/li&gt;&lt;li&gt;Entrepreneurial spirit&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This position is conveniently located in Jersey City, NJ, a four minute ride from the World Trade Center and just outside the Exchange Place PATH Station. Bordering the Hudson River, our offices have spectacular panoramic views of Manhattan and New Jersey. &lt;br /&gt;&lt;br /&gt;Quidsi Inc is an Equal Opportunity Employer&lt;br /&gt;&lt;br /&gt;.mrch.mkt.hm1.crp.jc.&lt;/li&gt;</CustomField>
117
+ </JobRecord>
118
+ </Result>
119
+ </GetResponse>
120
+ </SOAP-ENV:Body>
121
+ </SOAP-ENV:Envelope>
122
+ EOF
123
+ @system_id = '149522'
124
+ @username = 'username'
125
+ @client = IcimsClient::IcimsClient.new(@url,@username,@password)
126
+
127
+ #job_from_response_body is private
128
+ method = @client.method(:job_from_response_body)
129
+ @job = method.call(@response_body)
130
+ end
131
+
132
+ def test_initialize
133
+ assert_equal @username, @client.instance_variable_get(:@username)
134
+ assert_equal @password, @client.instance_variable_get(:@password)
135
+ assert_equal 'https://dummy.icims.com/api/v1/data', @client.instance_variable_get(:@url)
136
+ end
137
+
138
+ def test_request_body
139
+ method = @client.method(:job_request_body)
140
+ assert_equal @request_body, method.call(@system_id)
141
+ end
142
+
143
+ def test_job_from_response_body_get_attribute_CreatedByExternalId
144
+ assert_equal '448611', @job.get_attribute('CreatedByExternalId')
145
+ end
146
+
147
+ def test_job_from_response_body_get_attribute_CreatedDate
148
+ assert_equal '8/8/2011 10:20:04', @job.get_attribute('CreatedDate')
149
+ end
150
+
151
+ def test_job_from_response_body_get_attribute_ExternalId
152
+ assert_nil @job.get_attribute('ExternalId')
153
+ end
154
+
155
+ def test_job_from_response_body_get_attribute_Folder
156
+ assert_equal 'Open', @job.get_attribute('Folder')
157
+ end
158
+
159
+ def test_job_from_response_body_get_attribute_Overview
160
+ assert_equal '<p style="margin: 0px">As one of the fastest growing e-commerce companies in the country, <strong>Quidsi</strong> is the parent company of <a href="http://www.diapers.com/" target="_blank">Diapers.com</a> (baby care), <a href="http://www.soap.com/" target="_blank">Soap.com</a> (health, beauty and household essentials), <a href="http://www.beautybar.com/" target="_blank">BeautyBar.com</a> (prestige beauty), <a href="http://www.wag.com/" target="_blank">Wag.com</a> (pet products) and <a href="http://www.yoyo.com/" target="_blank">YoYo.com</a> (toys). We like to work hard and play hard, always striving to improve our business, our people, our culture and the experience for our customers. If this sounds like something you would like to be a part of, the next step is yours. Send us your resume and come join a group of critical thinkers and innovators energized by the passion to explore "what if" (the meaning of Quidsi in Latin). For more information&nbsp;about&nbsp;our company, please go to&nbsp;<a href="http://www.quidsi.com/" target="_blank">www.Quidsi.com</a>.</p><p style="margin: 0px">&nbsp;</p><p style="margin: 0px">We&rsquo;re looking for an experienced professional that has a passion for&nbsp;home products&nbsp;and can convert that&nbsp; passion into leading the front end management, including the marketing and merchandising, of our soon to be launched &lsquo;Home&rsquo; site.&nbsp; The right candidate will thrive in a highly entrepreneurial, fast-changing, and collaborative environment where people are driven, enthusiastic, and not afraid to take risks.&nbsp; This individual will be responsible for overall site strategy, and for driving growth and profitability through new customer acquisition, customer relationship management &amp; retention, assortment planning, on-site merchandising, vendor management, and inventory management.&nbsp; We want you to apply if you have a commitment to action-oriented analysis, a relentless passion for results, and the belief that anything is possible.&nbsp; &nbsp;</p>', @job.get_attribute('Overview')
161
+ assert_equal 'As one of the fastest growing e-commerce companies in the country, Quidsi is the parent company of Diapers.com (baby care), Soap.com (health, beauty and household essentials), BeautyBar.com (prestige beauty), Wag.com (pet products) and YoYo.com (toys). We like to work hard and play hard, always striving to improve our business, our people, our culture and the experience for our customers. If this sounds like something you would like to be a part of, the next step is yours. Send us your resume and come join a group of critical thinkers and innovators energized by the passion to explore "what if" (the meaning of Quidsi in Latin). For more information about our company, please go to www.Quidsi.com. We\'re looking for an experienced professional that has a passion for home products and can convert that passion into leading the front end management, including the marketing and merchandising, of our soon to be launched \'Home\' site. The right candidate will thrive in a highly entrepreneurial, fast-changing, and collaborative environment where people are driven, enthusiastic, and not afraid to take risks. This individual will be responsible for overall site strategy, and for driving growth and profitability through new customer acquisition, customer relationship management & retention, assortment planning, on-site merchandising, vendor management, and inventory management. We want you to apply if you have a commitment to action-oriented analysis, a relentless passion for results, and the belief that anything is possible.', @job.get_attribute('Overview').sanitize
162
+ end
163
+
164
+ def test_job_from_response_body_get_industry_levels
165
+ assert_equal ['5620 - Category Mgmt - Health & Beauty', 'QS_ID - Project Boardwalk', 'Consumables', 'North America Retail - Smithers'], @job.get_industry_levels.sanitize
166
+ end
167
+
168
+ def test_job_from_response_body_get_custom_field_jcf2001
169
+ assert_equal 'N/A', @job.get_custom_field('jcf2001')
170
+ end
171
+
172
+ def test_job_from_response_body_get_custom_field_jcf2002
173
+ assert_equal 'Yes', @job.get_custom_field('jcf2002')
174
+ end
175
+
176
+ def test_job_from_response_body_get_custom_field_jcf2007
177
+ assert_equal '40', @job.get_custom_field('jcf2007')
178
+ end
179
+
180
+ def test_job_from_response_body_get_custom_field_jcfnil
181
+ assert_nil @job.get_custom_field('jcfnil')
182
+ end
183
+
184
+ def test_sanitize
185
+ assert_equal 'This is a "sentence".', IcimsClient::IcimsAttributeValue.new('<p>This&nbsp;<b>is</b> a<br />&quot;sentence&quot;.</p>').sanitize
186
+ assert_equal 'This is a "sentence".', IcimsClient::IcimsAttributeValue.new('<p>This&nbsp;<b>is</b> a<br />&quot;sentence&quot;.</p>').sanitize.sanitize
187
+ assert_equal 'This is a trivial transform.', IcimsClient::IcimsAttributeValue.new('This is a trivial transform.').sanitize
188
+ end
189
+
190
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: icims_client
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Christopher Alef
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-12-07 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 17
27
+ segments:
28
+ - 1
29
+ - 1
30
+ - 1
31
+ version: 1.1.1
32
+ name: xml-simple
33
+ prerelease: false
34
+ type: :runtime
35
+ requirement: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 1
43
+ segments:
44
+ - 1
45
+ - 6
46
+ - 7
47
+ version: 1.6.7
48
+ name: rest-client
49
+ prerelease: false
50
+ type: :runtime
51
+ requirement: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 1
61
+ - 5
62
+ - 0
63
+ version: 1.5.0
64
+ name: nokogiri
65
+ prerelease: false
66
+ type: :runtime
67
+ requirement: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ version_requirements: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ hash: 9
75
+ segments:
76
+ - 2
77
+ - 0
78
+ - 3
79
+ version: 2.0.3
80
+ name: sanitize
81
+ prerelease: false
82
+ type: :runtime
83
+ requirement: *id004
84
+ - !ruby/object:Gem::Dependency
85
+ version_requirements: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ hash: 3
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ name: shoulda
95
+ prerelease: false
96
+ type: :development
97
+ requirement: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ version_requirements: &id006 !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ hash: 23
105
+ segments:
106
+ - 1
107
+ - 0
108
+ - 0
109
+ version: 1.0.0
110
+ name: bundler
111
+ prerelease: false
112
+ type: :development
113
+ requirement: *id006
114
+ - !ruby/object:Gem::Dependency
115
+ version_requirements: &id007 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ~>
119
+ - !ruby/object:Gem::Version
120
+ hash: 7
121
+ segments:
122
+ - 1
123
+ - 6
124
+ - 4
125
+ version: 1.6.4
126
+ name: jeweler
127
+ prerelease: false
128
+ type: :development
129
+ requirement: *id007
130
+ - !ruby/object:Gem::Dependency
131
+ version_requirements: &id008 !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ hash: 3
137
+ segments:
138
+ - 0
139
+ version: "0"
140
+ name: rcov
141
+ prerelease: false
142
+ type: :development
143
+ requirement: *id008
144
+ - !ruby/object:Gem::Dependency
145
+ version_requirements: &id009 !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 17
151
+ segments:
152
+ - 3
153
+ - 11
154
+ version: "3.11"
155
+ name: rdoc
156
+ prerelease: false
157
+ type: :development
158
+ requirement: *id009
159
+ description: icims_client implements a dead simple client, with minimal dependencies, for calling iCIMS web services from ruby. This is not intended as a enterprise-class integration library for iCIMS.
160
+ email: chrisale@amazon.com
161
+ executables: []
162
+
163
+ extensions: []
164
+
165
+ extra_rdoc_files:
166
+ - LICENSE.txt
167
+ - README.rdoc
168
+ files:
169
+ - .document
170
+ - Gemfile
171
+ - LICENSE.txt
172
+ - README.rdoc
173
+ - Rakefile
174
+ - VERSION
175
+ - lib/icims_client.rb
176
+ - test/helper.rb
177
+ - test/test_icims_client.rb
178
+ homepage:
179
+ licenses:
180
+ - MIT
181
+ post_install_message:
182
+ rdoc_options: []
183
+
184
+ require_paths:
185
+ - lib
186
+ required_ruby_version: !ruby/object:Gem::Requirement
187
+ none: false
188
+ requirements:
189
+ - - ">="
190
+ - !ruby/object:Gem::Version
191
+ hash: 3
192
+ segments:
193
+ - 0
194
+ version: "0"
195
+ required_rubygems_version: !ruby/object:Gem::Requirement
196
+ none: false
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ hash: 3
201
+ segments:
202
+ - 0
203
+ version: "0"
204
+ requirements: []
205
+
206
+ rubyforge_project:
207
+ rubygems_version: 1.8.10
208
+ signing_key:
209
+ specification_version: 3
210
+ summary: a simple client for iCIMS web services.
211
+ test_files: []
212
+