arbetsformedlingen 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/.ruby-style-guide.yml +270 -0
  4. data/.travis.yml +0 -1
  5. data/CHANGELOG.md +12 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE.txt +1 -1
  8. data/README.md +1 -1
  9. data/Rakefile +2 -0
  10. data/arbetsformedlingen.gemspec +10 -9
  11. data/bin/console +1 -0
  12. data/lib/arbetsformedlingen/api/client.rb +48 -30
  13. data/lib/arbetsformedlingen/api/ledigtarbete_client.rb +6 -1
  14. data/lib/arbetsformedlingen/api/matchning_client.rb +16 -10
  15. data/lib/arbetsformedlingen/api/request.rb +10 -13
  16. data/lib/arbetsformedlingen/api/response.rb +71 -0
  17. data/lib/arbetsformedlingen/api/results/ad_result.rb +36 -18
  18. data/lib/arbetsformedlingen/api/results/matchning_result.rb +42 -3
  19. data/lib/arbetsformedlingen/api/results/soklista_result.rb +16 -2
  20. data/lib/arbetsformedlingen/api/soap_request.rb +11 -10
  21. data/lib/arbetsformedlingen/api/values/ad_result_values.rb +6 -1
  22. data/lib/arbetsformedlingen/api/values/create_ad_page.rb +3 -1
  23. data/lib/arbetsformedlingen/api/values/matchning_result_values.rb +9 -1
  24. data/lib/arbetsformedlingen/api/values/soklista_values.rb +17 -1
  25. data/lib/arbetsformedlingen/api/ws_occupation_client.rb +26 -1
  26. data/lib/arbetsformedlingen/codes/country_code.rb +3 -1
  27. data/lib/arbetsformedlingen/codes/drivers_license_code.rb +6 -3
  28. data/lib/arbetsformedlingen/codes/experience_required_code.rb +3 -1
  29. data/lib/arbetsformedlingen/codes/municipality_code.rb +3 -1
  30. data/lib/arbetsformedlingen/codes/occupation_code.rb +3 -1
  31. data/lib/arbetsformedlingen/codes/salary_type_code.rb +3 -1
  32. data/lib/arbetsformedlingen/key_struct.rb +5 -3
  33. data/lib/arbetsformedlingen/models/application_method.rb +3 -1
  34. data/lib/arbetsformedlingen/models/company.rb +2 -2
  35. data/lib/arbetsformedlingen/models/document.rb +4 -2
  36. data/lib/arbetsformedlingen/models/dry/predicates.rb +2 -0
  37. data/lib/arbetsformedlingen/models/dry/types.rb +5 -3
  38. data/lib/arbetsformedlingen/models/model.rb +2 -0
  39. data/lib/arbetsformedlingen/models/packet.rb +3 -1
  40. data/lib/arbetsformedlingen/models/packet_xml_builder.rb +8 -3
  41. data/lib/arbetsformedlingen/models/position.rb +5 -3
  42. data/lib/arbetsformedlingen/models/publication.rb +3 -1
  43. data/lib/arbetsformedlingen/models/qualification.rb +3 -1
  44. data/lib/arbetsformedlingen/models/salary.rb +3 -1
  45. data/lib/arbetsformedlingen/models/schedule.rb +4 -2
  46. data/lib/arbetsformedlingen/soap_builder.rb +3 -1
  47. data/lib/arbetsformedlingen/version.rb +3 -1
  48. metadata +43 -25
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  module API
3
5
  module Values
@@ -17,11 +19,13 @@ module Arbetsformedlingen
17
19
  :terms,
18
20
  :application,
19
21
  :workplace,
20
- :requirements
22
+ :requirements,
23
+ :response
21
24
  )
22
25
  class Ad
23
26
  def to_h
24
27
  hash = super.to_h
28
+ hash.delete(:response) # don't return the raw response object
25
29
  hash[:terms] = hash[:terms].to_h
26
30
  hash[:application] = hash[:application].to_h
27
31
  hash[:workplace] = hash[:workplace].to_h
@@ -63,6 +67,7 @@ module Arbetsformedlingen
63
67
  end
64
68
  end
65
69
 
70
+ Contact = KeyStruct.new(:name, :title, :phone)
66
71
  Postal = KeyStruct.new(:code, :address, :city, :country)
67
72
  Requirements = KeyStruct.new(:own_car)
68
73
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  module API
3
5
  module Values
@@ -6,7 +8,7 @@ module Arbetsformedlingen
6
8
 
7
9
  attr_reader :code, :messages, :body, :request_body
8
10
 
9
- def initialize(httparty_response, request_boby)
11
+ def initialize(httparty_response, _request_boby)
10
12
  @code = httparty_response.code
11
13
  @body = httparty_response.body
12
14
  @request_body = request_body
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  module API
3
5
  module Values
@@ -10,7 +12,8 @@ module Arbetsformedlingen
10
12
  :total_places_total,
11
13
  :total_pages,
12
14
  :data,
13
- :raw_data
15
+ :raw_data,
16
+ :response
14
17
  )
15
18
  class MatchningPage
16
19
  include Enumerable
@@ -21,9 +24,14 @@ module Arbetsformedlingen
21
24
 
22
25
  def to_h
23
26
  hash = super.to_h
27
+ hash.delete(:response) # don't return the raw response object
24
28
  hash[:data].map!(&:to_h)
25
29
  hash
26
30
  end
31
+
32
+ def success?
33
+ success
34
+ end
27
35
  end
28
36
 
29
37
  MatchningAd = KeyStruct.new(
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  module API
3
5
  module Values
@@ -6,7 +8,8 @@ module Arbetsformedlingen
6
8
  :total_ads,
7
9
  :total_vacancies,
8
10
  :data,
9
- :raw_data
11
+ :raw_data,
12
+ :response
10
13
  )
11
14
  class SoklistaPage
12
15
  include Enumerable
@@ -17,9 +20,22 @@ module Arbetsformedlingen
17
20
 
18
21
  def to_h
19
22
  hash = super.to_h
23
+ hash.delete(:response) # don't return the raw response object
20
24
  hash[:data].map!(&:to_h)
21
25
  hash
22
26
  end
27
+
28
+ def method_missing(method_name, *arguments, &block)
29
+ if response.respond_to?(method_name)
30
+ response.public_send(method_name, *arguments, &block)
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def respond_to_missing?(method_name, include_private = false)
37
+ response.respond_to?(method_name) || super
38
+ end
23
39
  end
24
40
 
25
41
  SoklistaResult = KeyStruct.new(
@@ -1,17 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'arbetsformedlingen/soap_builder'
2
4
  require 'arbetsformedlingen/api/soap_request'
3
5
 
4
6
  module Arbetsformedlingen
5
7
  module API
8
+ # WsOccupation API client
6
9
  class WSOccupationClient
7
10
  attr_reader :request
8
11
 
12
+ # Service URL
9
13
  SERVICE_URL = 'https://api.arbetsformedlingen.se/af/v0/Occupation/wsoccupation.asmx'.freeze
10
14
 
15
+ # Initialize client
11
16
  def initialize
12
- @request = request || SOAPRequest.new(SERVICE_URL)
17
+ @request = SOAPRequest.new(SERVICE_URL)
13
18
  end
14
19
 
20
+ # Returns occupation response with specified id
21
+ # @return [Response] the response
22
+ # @see Response
23
+ # @see Response#xml
15
24
  def occupation(id)
16
25
  soap_body = SOAPBuilder.wrap do |body|
17
26
  body.GetOccupationById(xmlns: 'urn:ams.se:wsoccupation') do |node|
@@ -22,6 +31,10 @@ module Arbetsformedlingen
22
31
  request.post(soap_body.to_xml)
23
32
  end
24
33
 
34
+ # Returns occupations response with specified name
35
+ # @return [Response] the response
36
+ # @see Response
37
+ # @see Response#xml
25
38
  def find_occupations(name)
26
39
  soap_body = SOAPBuilder.wrap do |body|
27
40
  body.FindOccupation(xmlns: 'urn:ams.se:wsoccupation') do |node|
@@ -32,6 +45,10 @@ module Arbetsformedlingen
32
45
  request.post(soap_body.to_xml)
33
46
  end
34
47
 
48
+ # Returns occupations response
49
+ # @return [Response] the response
50
+ # @see Response
51
+ # @see Response#xml
35
52
  def occupations
36
53
  soap_body = SOAPBuilder.wrap do |body|
37
54
  body.GetAllOccupations(xmlns: 'urn:ams.se:wsoccupation')
@@ -40,6 +57,10 @@ module Arbetsformedlingen
40
57
  request.post(soap_body.to_xml)
41
58
  end
42
59
 
60
+ # Returns occupations short response with specified id
61
+ # @return [Response] the response
62
+ # @see Response
63
+ # @see Response#xml
43
64
  def occupations_short
44
65
  soap_body = SOAPBuilder.wrap do |body|
45
66
  body.GetAllOccupationsShort(xmlns: 'urn:ams.se:wsoccupation')
@@ -48,6 +69,10 @@ module Arbetsformedlingen
48
69
  request.post(soap_body.to_xml)
49
70
  end
50
71
 
72
+ # Returns occupations detailed response with specified id
73
+ # @return [Response] the response
74
+ # @see Response
75
+ # @see Response#xml
51
76
  def occupations_detailed
52
77
  soap_body = SOAPBuilder.wrap do |body|
53
78
  body.GetAllOccupationsDetailed(xmlns: 'urn:ams.se:wsoccupation')
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'csv'
2
4
  require 'set'
3
5
 
4
6
  module Arbetsformedlingen
5
7
  class CountryCode
6
8
  CODES = CSV.read(
7
- File.expand_path('../../../../data/country-codes.csv', __FILE__)
9
+ File.expand_path('../../../data/country-codes.csv', __dir__)
8
10
  ).to_h.freeze
9
11
 
10
12
  COUNTRY_CODES = Set.new(CODES.values).freeze
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module Arbetsformedlingen
4
6
  module DriversLicenseCode
5
7
  CODES = Set.new([
6
- 'AM', 'A1', 'A2', 'A', 'B', 'Utökad B', 'BE', 'C1', 'C1E', 'C', 'CE', 'D1', 'D1E', 'D', 'DE'
7
- ]).freeze
8
+ 'AM', 'A1', 'A2', 'A', 'B', 'Utökad B', 'BE',
9
+ 'C1', 'C1E', 'C', 'CE', 'D1', 'D1E', 'D', 'DE'
10
+ ]).freeze
8
11
 
9
12
  def self.codes
10
13
  CODES.to_a
@@ -30,4 +33,4 @@ module Arbetsformedlingen
30
33
  map(&:upcase)
31
34
  end
32
35
  end
33
- end
36
+ end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module Arbetsformedlingen
4
6
  class ExperienceRequiredCode
5
7
  CODES_MAP = {
6
8
  'true' => '1',
7
- 'false' => '4'
9
+ 'false' => '4',
8
10
  }.freeze
9
11
  CODES_MAP_INVERTED = CODES_MAP.invert.freeze
10
12
 
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'csv'
2
4
 
3
5
  module Arbetsformedlingen
4
6
  class MunicipalityCode
5
7
  CODE_MAP = CSV.read(
6
- File.expand_path('../../../../data/municipality-codes.csv', __FILE__)
8
+ File.expand_path('../../../data/municipality-codes.csv', __dir__)
7
9
  ).to_h.freeze
8
10
  CODES_MAP_INVERTED = CODE_MAP.invert.freeze
9
11
 
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'csv'
2
4
 
3
5
  module Arbetsformedlingen
4
6
  class OccupationCode
5
7
  CODE_MAP = CSV.read(
6
- File.expand_path('../../../../data/occupation-codes.csv', __FILE__)
8
+ File.expand_path('../../../data/occupation-codes.csv', __dir__)
7
9
  ).to_h.invert.freeze
8
10
  CODES_MAP_INVERTED = CODE_MAP.invert.freeze
9
11
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module Arbetsformedlingen
@@ -5,7 +7,7 @@ module Arbetsformedlingen
5
7
  CODE_MAP = {
6
8
  'fixed' => '1',
7
9
  'fixed_and_commission' => '2',
8
- 'commission' => '3'
10
+ 'commission' => '3',
9
11
  }.freeze
10
12
 
11
13
  CODES = Set.new(CODE_MAP.values).freeze
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  class KeyStruct < Struct
3
5
  def initialize(**keyword_args)
4
6
  keyword_args.each do |key, value|
5
- if members.include?(key)
6
- self[key] = value
7
- else
7
+ unless members.include?(key)
8
8
  raise ArgumentError, "Unknown key struct member: #{key}"
9
9
  end
10
+
11
+ self[key] = value
10
12
  end
11
13
  end
12
14
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  ApplicationMethodSchema = Dry::Validation.Params do
3
5
  configure do
4
6
  config.type_specs = true
5
- config.messages_file = File.expand_path('../../../../config/locales/errors.yml', __FILE__)
7
+ config.messages_file = File.expand_path('../../../config/locales/errors.yml', __dir__)
6
8
 
7
9
  predicates(Predicates)
8
10
  end
@@ -4,7 +4,7 @@ module Arbetsformedlingen
4
4
  CompanySchema = Dry::Validation.Params do
5
5
  configure do
6
6
  config.type_specs = true
7
- config.messages_file = File.expand_path('../../../../config/locales/errors.yml', __FILE__)
7
+ config.messages_file = File.expand_path('../../../config/locales/errors.yml', __dir__)
8
8
 
9
9
  predicates(Predicates)
10
10
  end
@@ -34,7 +34,7 @@ module Arbetsformedlingen
34
34
  hash[:address][:full_address] = [
35
35
  address.fetch(:street),
36
36
  address.fetch(:zip),
37
- address.fetch(:city)
37
+ address.fetch(:city),
38
38
  ].join(', ')
39
39
  hash[:cin_arbetsformedlingen] = cin_arbetsformedlingen(hash.fetch(:cin))
40
40
  hash
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'securerandom'
2
4
 
3
5
  module Arbetsformedlingen
4
6
  DocumentSchema = Dry::Validation.Params do
5
7
  configure do
6
8
  config.type_specs = true
7
- config.messages_file = File.expand_path('../../../../config/locales/errors.yml', __FILE__)
9
+ config.messages_file = File.expand_path('../../../config/locales/errors.yml', __dir__)
8
10
 
9
11
  predicates(Predicates)
10
12
  end
@@ -19,7 +21,7 @@ module Arbetsformedlingen
19
21
  def initialize(hash)
20
22
  data = {
21
23
  id: SecureRandom.uuid,
22
- timestamp: Time.now.utc.iso8601
24
+ timestamp: Time.now.utc.iso8601,
23
25
  }.merge!(hash)
24
26
 
25
27
  super(DocumentSchema.call(data))
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
 
3
5
  module Arbetsformedlingen
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  module Types
3
5
  include Dry::Types.module
@@ -5,14 +7,14 @@ module Arbetsformedlingen
5
7
  StrippedString = Types::Strict::String.constructor { |value| value.to_s.strip }
6
8
  UUIDString = Types::Strict::String.constrained(size: 36)
7
9
  Currency = Types::Strict::String.constructor do |string|
8
- string.strip.upcase if string
10
+ string&.strip&.upcase
9
11
  end
10
12
  # Company Identification Number
11
13
  CIN = Types::Strict::String.constructor do |string|
12
- string.delete(' ').delete('-') if string
14
+ string&.delete(' ')&.delete('-')
13
15
  end
14
16
  Zip = Types::Strict::String.constructor do |string|
15
- string.delete(' ') if string
17
+ string&.delete(' ')
16
18
  end
17
19
  Municipality = Types::Strict::String.constructor do |string|
18
20
  MunicipalityCode.to_code(string)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Arbetsformedlingen
2
4
  class Model
3
5
  def self.from_schema(schema)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'builder'
2
4
  require 'arbetsformedlingen/models/packet_xml_builder'
3
5
 
@@ -5,7 +7,7 @@ module Arbetsformedlingen
5
7
  PacketSchema = Dry::Validation.Params do
6
8
  configure do
7
9
  config.type_specs = true
8
- config.messages_file = File.expand_path('../../../../config/locales/errors.yml', __FILE__)
10
+ config.messages_file = File.expand_path('../../../config/locales/errors.yml', __dir__)
9
11
 
10
12
  predicates(Predicates)
11
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'builder'
2
4
 
3
5
  module Arbetsformedlingen
@@ -47,7 +49,7 @@ module Arbetsformedlingen
47
49
  end
48
50
 
49
51
  def append_job_position(payload, packet_data)
50
- payload.JobPositionPosting(status: "#{'in' unless packet_data.fetch(:active)}active") do |pos|
52
+ payload.JobPositionPosting(status: "#{'in' unless packet_data.fetch(:active)}active") do |pos| # rubocop:disable Metrics/LineLength
51
53
  cin = packet_data[:position][:company].fetch(:cin_arbetsformedlingen)
52
54
  job_pos_id = "#{cin}-#{packet_data.fetch(:job_id)}"
53
55
  pos.JobPositionPostingId(job_pos_id)
@@ -65,7 +67,10 @@ module Arbetsformedlingen
65
67
  if description = company.fetch(:description, nil)
66
68
  jpp.HiringOrgDescription(description)
67
69
  end
68
- jpp.OccupationGroup(code: packet_data.fetch(:occupation), codename: 'OccupationNameID')
70
+ jpp.OccupationGroup(
71
+ code: packet_data.fetch(:occupation),
72
+ codename: 'OccupationNameID'
73
+ )
69
74
  end
70
75
  end
71
76
  end
@@ -87,7 +92,7 @@ module Arbetsformedlingen
87
92
 
88
93
  payload.HiringOrg do |org|
89
94
  org.HiringOrgName(company.fetch(:name))
90
- org.HiringOrgId(company.fetch(:cin_arbetsformedlingen), idOwner: company.fetch(:cin))
95
+ org.HiringOrgId(company.fetch(:cin_arbetsformedlingen), idOwner: company.fetch(:cin)) # rubocop:disable Metrics/LineLength
91
96
  append_company_contact(org, company)
92
97
  end
93
98
  end