arbetsformedlingen 0.5.0 → 0.6.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.
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