diff --git a/README.md b/README.md index 4da8730..d347a15 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,17 @@ client.offers.retrieve(offer_id: "id", candidate_id: "id", job_id: "id") client.offers.retrieve_offers(candidate_id: "id", job_id: "id") ``` +### Postings + +```ruby +client.postings.list(company_id:) +client.postings.list_departments(company_id:) +client.postings.retrieve(company_id:, posting_id:) +client.postings.create_candidate(posting_id:, {}) +client.postings.retrieve_candidate_status(posting_id:, candidate_id:) +client.postings.retrieve_configuration(posting_id:) +``` + ### Reports ```ruby diff --git a/lib/smartrecruiters.rb b/lib/smartrecruiters.rb index dbaca37..a7eba69 100644 --- a/lib/smartrecruiters.rb +++ b/lib/smartrecruiters.rb @@ -13,25 +13,28 @@ module SmartRecruiters autoload :Attachment, 'smartrecruiters/objects/attachment' autoload :CallbacksLog, 'smartrecruiters/objects/callbacks_log' autoload :Candidate, 'smartrecruiters/objects/candidate' + autoload :Department, 'smartrecruiters/objects/department' autoload :Interview, 'smartrecruiters/objects/interview' autoload :Job, 'smartrecruiters/objects/job' autoload :Offer, 'smartrecruiters/objects/offer' - autoload :User, 'smartrecruiters/objects/user' + autoload :Posting, 'smartrecruiters/objects/posting' autoload :Report, 'smartrecruiters/objects/report' autoload :ReportFile, 'smartrecruiters/objects/report_file' autoload :Review, 'smartrecruiters/objects/review' autoload :SystemRole, 'smartrecruiters/objects/system_role' + autoload :User, 'smartrecruiters/objects/user' autoload :Webhook, 'smartrecruiters/objects/webhook' autoload :AccessGroupsResource, 'smartrecruiters/resources/access_groups' autoload :CandidatesResource, 'smartrecruiters/resources/candidates' autoload :InterviewsResource, 'smartrecruiters/resources/interviews' autoload :InterviewTypesResource, 'smartrecruiters/resources/interview_types' - autoload :OffersResource, 'smartrecruiters/resources/offers' autoload :JobsResource, 'smartrecruiters/resources/jobs' - autoload :UsersResource, 'smartrecruiters/resources/users' + autoload :OffersResource, 'smartrecruiters/resources/offers' + autoload :PostingsResource, 'smartrecruiters/resources/postings' autoload :ReportsResource, 'smartrecruiters/resources/reports' autoload :ReviewsResource, 'smartrecruiters/resources/reviews' autoload :SystemRolesResource, 'smartrecruiters/resources/system_roles' + autoload :UsersResource, 'smartrecruiters/resources/users' autoload :WebhooksResource, 'smartrecruiters/resources/webhooks' end diff --git a/lib/smartrecruiters/client.rb b/lib/smartrecruiters/client.rb index 62af05b..ccb5980 100644 --- a/lib/smartrecruiters/client.rb +++ b/lib/smartrecruiters/client.rb @@ -53,6 +53,10 @@ def offers OffersResource.new(self) end + def postings + PostingsResource.new(self) + end + def reports ReportsResource.new(self) end diff --git a/lib/smartrecruiters/objects/department.rb b/lib/smartrecruiters/objects/department.rb new file mode 100644 index 0000000..3139be6 --- /dev/null +++ b/lib/smartrecruiters/objects/department.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module SmartRecruiters + class Department < Object + end +end diff --git a/lib/smartrecruiters/objects/posting.rb b/lib/smartrecruiters/objects/posting.rb new file mode 100644 index 0000000..511579c --- /dev/null +++ b/lib/smartrecruiters/objects/posting.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module SmartRecruiters + class Posting < Object + end +end diff --git a/lib/smartrecruiters/resources/postings.rb b/lib/smartrecruiters/resources/postings.rb new file mode 100644 index 0000000..1231481 --- /dev/null +++ b/lib/smartrecruiters/resources/postings.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module SmartRecruiters + class PostingsResource < Resource + COMPANY_API = 'v1/companies' + + def list(company_id:, **params) + response = get_request("#{COMPANY_API}/#{company_id}/postings", params: params) + Collection.from_response(response, type: Posting) + end + + def list_departments(company_id:, **params) + response = get_request("#{COMPANY_API}/#{company_id}/departments", params: params) + Collection.from_response(response, type: Department) + end + + def retrieve_posting(company_id:, posting_id:, **params) + Posting.new get_request("#{COMPANY_API}/#{company_id}/postings/#{posting_id}", params: params).body + end + + def create_candidate(posting_id:, **attributes) + Object.new post_request("postings/#{posting_id}/candidates", body: attributes).body + end + + def retrieve_candidate_status(posting_id:, candidate_id:) + Object.new get_request("postings/#{posting_id}/candidates/#{candidate_id}/status").body + end + + def retrieve_configuration(posting_id:) + Object.new get_request("postings/#{posting_id}/configuration").body + end + end +end diff --git a/test/fixtures/postings/create_candidate.json b/test/fixtures/postings/create_candidate.json new file mode 100644 index 0000000..e34b581 --- /dev/null +++ b/test/fixtures/postings/create_candidate.json @@ -0,0 +1,5 @@ +{ + "id": "14b68c0a-de64-4638-b6d7-189a126a0891", + "createdOn": "string", + "candidatePortalUrl": "string" +} \ No newline at end of file diff --git a/test/fixtures/postings/list.json b/test/fixtures/postings/list.json new file mode 100644 index 0000000..c90a4b8 --- /dev/null +++ b/test/fixtures/postings/list.json @@ -0,0 +1,62 @@ +{ + "totalFound": 0, + "limit": 0, + "offset": 0, + "content": [ + { + "id": "string", + "uuid": "string", + "name": "string", + "refNumber": "string", + "company": { + "identifier": "string", + "name": "string" + }, + "releasedDate": "2021-10-24T20:11:07.457Z", + "location": { + "country": "string", + "region": "string", + "city": "string", + "remote": true + }, + "industry": { + "id": "string", + "label": "string" + }, + "department": { + "id": "string", + "label": "string", + "description": "string" + }, + "function": { + "id": "string", + "label": "string" + }, + "typeOfEmployment": { + "id": "string", + "label": "string" + }, + "experienceLevel": { + "id": "associate", + "name": "string" + }, + "customField": [ + { + "fieldId": "string", + "fieldLabel": "string", + "valueId": "string", + "valueLabel": "string" + } + ], + "ref": "string", + "creator": { + "name": "string" + }, + "language": { + "code": "string", + "label": "string", + "labelNative": "string" + } + } + ] +} \ No newline at end of file diff --git a/test/fixtures/postings/list_departments.json b/test/fixtures/postings/list_departments.json new file mode 100644 index 0000000..3561c0c --- /dev/null +++ b/test/fixtures/postings/list_departments.json @@ -0,0 +1,10 @@ +{ + "totalFound": 0, + "content": [ + { + "id": "string", + "label": "Product", + "description": "Product" + } + ] +} \ No newline at end of file diff --git a/test/fixtures/postings/retrieve_candidate_status.json b/test/fixtures/postings/retrieve_candidate_status.json new file mode 100644 index 0000000..75a02af --- /dev/null +++ b/test/fixtures/postings/retrieve_candidate_status.json @@ -0,0 +1,3 @@ +{ + "status": "NEW" +} \ No newline at end of file diff --git a/test/fixtures/postings/retrieve_configuration.json b/test/fixtures/postings/retrieve_configuration.json new file mode 100644 index 0000000..622745a --- /dev/null +++ b/test/fixtures/postings/retrieve_configuration.json @@ -0,0 +1,33 @@ +{ + "questions": [ + { + "id": "string", + "label": "string", + "repeatable": true, + "fields": [ + { + "id": "string", + "label": "string", + "type": "INPUT_TEXT", + "required": true, + "complianceType": "DIVERSITY", + "values": [ + { + "id": "string", + "label": "string" + } + ] + } + ] + } + ], + "settings": { + "avatarUploadAvailable": true + }, + "privacyPolicies": [ + { + "url": "string", + "orgName": "string" + } + ] +} \ No newline at end of file diff --git a/test/fixtures/postings/retrieve_posting.json b/test/fixtures/postings/retrieve_posting.json new file mode 100644 index 0000000..5baaea3 --- /dev/null +++ b/test/fixtures/postings/retrieve_posting.json @@ -0,0 +1,81 @@ +{ + "id": "string", + "uuid": "string", + "name": "string", + "jobAdId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "applyUrl": "string", + "postingUrl": "string", + "referralUrl": "string", + "refNumber": "string", + "company": { + "identifier": "string", + "name": "string" + }, + "releasedDate": "2021-10-24T19:57:22.832Z", + "location": { + "country": "string", + "region": "string", + "city": "string", + "remote": true + }, + "industry": { + "id": "string", + "label": "string" + }, + "department": { + "id": "string", + "label": "string", + "description": "string" + }, + "function": { + "id": "string", + "label": "string" + }, + "typeOfEmployment": { + "id": "string", + "label": "string" + }, + "experienceLevel": { + "id": "associate", + "name": "string" + }, + "customField": [ + { + "fieldId": "string", + "fieldLabel": "string", + "valueId": "string", + "valueLabel": "string" + } + ], + "ref": "string", + "creator": { + "name": "string" + }, + "jobAd": { + "sections": { + "companyDescription": { + "title": "string", + "text": "string" + }, + "jobDescription": { + "title": "string", + "text": "string" + }, + "qualifications": { + "title": "string", + "text": "string" + }, + "additionalInformation": { + "title": "string", + "text": "string" + }, + "videos": { + "title": "string", + "urls": [ + "string" + ] + } + } + }, + "active": true +} \ No newline at end of file diff --git a/test/resources/postings_test.rb b/test/resources/postings_test.rb new file mode 100644 index 0000000..8cde872 --- /dev/null +++ b/test/resources/postings_test.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require 'test_helper' + +class PostingsResourceTest < Minitest::Test + COMPANY_API = 'v1/companies' + + def test_list + company_id = 'Acme' + stub = stub_request("#{COMPANY_API}/#{company_id}/postings", + response: stub_response(fixture: 'postings/list')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + postings = client.postings.list(company_id: company_id) + + assert_equal SmartRecruiters::Collection, postings.class + assert_equal SmartRecruiters::Posting, postings.content.first.class + assert_equal true, postings.content.first.location['remote'] + end + + def test_list_departments + company_id = 'Acme' + stub = stub_request("#{COMPANY_API}/#{company_id}/departments", + response: stub_response(fixture: 'postings/list_departments')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + departments = client.postings.list_departments(company_id: company_id) + + assert_equal SmartRecruiters::Collection, departments.class + assert_equal SmartRecruiters::Department, departments.content.first.class + assert_equal 'Product', departments.content.first.label + end + + def test_retrieve_posting + company_id = 'Acme' + posting_id = '0905435c-e71c-4a75-be23-3e79c68f4260' + stub = stub_request("#{COMPANY_API}/#{company_id}/postings/#{posting_id}", + response: stub_response(fixture: 'postings/retrieve_posting')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + posting = client.postings.retrieve_posting(company_id: company_id, posting_id: posting_id) + + assert_equal SmartRecruiters::Posting, posting.class + assert_equal true, posting.location['remote'] + end + + def test_create_candidate + posting_id = '0905435c-e71c-4a75-be23-3e79c68f4260' + body = { + firstName: 'First', lastName: 'string', email: 'create@example.com', phoneNumber: 'string', + location: { country: 'string', countryCode: 'string', regionCode: 'string', + region: 'string', city: 'string', lat: 0, lng: 0 }, + web: { skype: 'string', linkedin: 'string', facebook: 'string', twitter: 'string', website: 'string' }, + tags: ['string'], + education: [{ institution: 'string', degree: 'string', major: 'string', current: true, location: 'string', + startDate: 'string', endDate: 'string', description: 'string' }], + experience: [{ title: 'string', company: 'string', current: true, + startDate: 'string', endDate: 'string', location: 'string', description: 'string' }], + sourceDetails: { sourceTypeId: 'string', sourceSubTypeId: 'string', sourceId: 'string' }, + internal: true + } + stub = stub_request("postings/#{posting_id}/candidates", + method: :post, body: body, response: stub_response(fixture: 'postings/create_candidate')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + candidate = client.postings.create_candidate(posting_id: posting_id, **body) + assert_equal SmartRecruiters::Object, candidate.class + assert_equal '14b68c0a-de64-4638-b6d7-189a126a0891', candidate.id + end + + def test_retrieve_candidate_status + posting_id = '0905435c-e71c-4a75-be23-3e79c68f4260' + candidate_id = '14b68c0a-de64-4638-b6d7-189a126a0891' + + stub = stub_request("postings/#{posting_id}/candidates/#{candidate_id}/status", + response: stub_response(fixture: 'postings/retrieve_candidate_status')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + status = client.postings.retrieve_candidate_status(posting_id: posting_id, candidate_id: candidate_id) + + assert_equal SmartRecruiters::Object, status.class + assert_equal 'NEW', status.status + end + + def test_retrieve_configuration + posting_id = '0905435c-e71c-4a75-be23-3e79c68f4260' + + stub = stub_request("postings/#{posting_id}/configuration", + response: stub_response(fixture: 'postings/retrieve_configuration')) + client = SmartRecruiters::Client.new(api_key: 'fake', adapter: :test, stubs: stub) + configuration = client.postings.retrieve_configuration(posting_id: posting_id) + + assert_equal SmartRecruiters::Object, configuration.class + assert_equal true, configuration.settings.avatarUploadAvailable + end +end