stackone_migration 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 18a239a9855fad756660ec28639ef4f97c6e06a2b716b6f29ecf5066d9dec14e
4
+ data.tar.gz: 337ad0348278d4ac3da0a92cf193ccb9bd0f5529a5e75d4437367e578d97928f
5
+ SHA512:
6
+ metadata.gz: 1e366986d794a7d04a20b9fe3c48d05cb27b10400a850aad1b0d2571881da72c9028a54f8d0369902c5b8d9cce42f461e5041533f5485e33337261246fd1203f
7
+ data.tar.gz: e50856a872ddf66eae142f57bf4ecb6e45a72fc4de9d634c933c2fb3f2b40f68eb04e53e1024824170ecc29b240bff0469b6eb14fc9e30cb8fa4ae3b1d4203c0
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ group :development, :test do
8
+ gem 'pry-byebug'
9
+ gem 'rake', '~> 13.0.1'
10
+ gem 'rubocop', '~> 1.48.0'
11
+ end
12
+
13
+ gem 'merge_hris_client', '~> 3.0'
14
+ gem 'stackone_hris_client', '~> 1.1'
data/Gemfile.lock ADDED
@@ -0,0 +1,80 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ stackone_migration (1.0.0)
5
+ merge_hris_client (~> 3.0)
6
+ stackone_hris_client (~> 1.1)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ast (2.4.2)
12
+ byebug (11.1.3)
13
+ coderay (1.1.3)
14
+ diff-lcs (1.5.0)
15
+ ethon (0.16.0)
16
+ ffi (>= 1.15.0)
17
+ ffi (1.15.5)
18
+ json (2.6.3)
19
+ merge_hris_client (3.0.0)
20
+ typhoeus (~> 1.0, >= 1.0.1)
21
+ method_source (1.0.0)
22
+ parallel (1.22.1)
23
+ parser (3.2.1.1)
24
+ ast (~> 2.4.1)
25
+ pry (0.14.2)
26
+ coderay (~> 1.1)
27
+ method_source (~> 1.0)
28
+ pry-byebug (3.10.1)
29
+ byebug (~> 11.0)
30
+ pry (>= 0.13, < 0.15)
31
+ rainbow (3.1.1)
32
+ rake (13.0.6)
33
+ regexp_parser (2.7.0)
34
+ rexml (3.2.5)
35
+ rspec (3.12.0)
36
+ rspec-core (~> 3.12.0)
37
+ rspec-expectations (~> 3.12.0)
38
+ rspec-mocks (~> 3.12.0)
39
+ rspec-core (3.12.1)
40
+ rspec-support (~> 3.12.0)
41
+ rspec-expectations (3.12.2)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.12.0)
44
+ rspec-mocks (3.12.4)
45
+ diff-lcs (>= 1.2.0, < 2.0)
46
+ rspec-support (~> 3.12.0)
47
+ rspec-support (3.12.0)
48
+ rubocop (1.48.1)
49
+ json (~> 2.3)
50
+ parallel (~> 1.10)
51
+ parser (>= 3.2.0.0)
52
+ rainbow (>= 2.2.2, < 4.0)
53
+ regexp_parser (>= 1.8, < 3.0)
54
+ rexml (>= 3.2.5, < 4.0)
55
+ rubocop-ast (>= 1.26.0, < 2.0)
56
+ ruby-progressbar (~> 1.7)
57
+ unicode-display_width (>= 2.4.0, < 3.0)
58
+ rubocop-ast (1.27.0)
59
+ parser (>= 3.2.1.0)
60
+ ruby-progressbar (1.13.0)
61
+ stackone_hris_client (1.1.0)
62
+ typhoeus (~> 1.0, >= 1.0.1)
63
+ typhoeus (1.4.0)
64
+ ethon (>= 0.9.0)
65
+ unicode-display_width (2.4.2)
66
+
67
+ PLATFORMS
68
+ arm64-darwin-22
69
+
70
+ DEPENDENCIES
71
+ merge_hris_client (~> 3.0)
72
+ pry-byebug
73
+ rake (~> 13.0.1)
74
+ rspec (~> 3.6, >= 3.6.0)
75
+ rubocop (~> 1.48.0)
76
+ stackone_hris_client (~> 1.1)
77
+ stackone_migration!
78
+
79
+ BUNDLED WITH
80
+ 2.4.7
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 StackOne
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # stackone-migration-ruby
2
+
3
+ StackOneMigration - the Ruby gem for migration to the StackOne Unified API
4
+
5
+ ## Installation
6
+
7
+ ```shell
8
+ gem install stackone_migration
9
+ ```
10
+
11
+ or add this line to your Gemfile:
12
+
13
+ ```ruby
14
+ gem 'stackone_migration'
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ Load the migration gem:
20
+
21
+ ```ruby
22
+ require 'stackone_migration'
23
+ ```
24
+
25
+ Configure StackOne API key:
26
+
27
+ ```ruby
28
+ StackOneHrisClient.configure do |config|
29
+ config.api_key_token = 'YOUR API KEY'
30
+ end
31
+ ```
32
+
33
+ ## License
34
+
35
+ Copyright (c) 2023 [StackOne](https://stackone.com). Licensed under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ begin
6
+ require 'rspec/core/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ task default: :spec
10
+ rescue LoadError
11
+ # no rspec available
12
+ end
@@ -0,0 +1,19 @@
1
+ require 'cgi'
2
+
3
+ module MergeHRISClient
4
+ class AccountTokenApi
5
+ alias_method :original_account_token_retrieve, :account_token_retrieve
6
+
7
+ def account_token_retrieve(public_token, opts = {})
8
+ return original_account_token_retrieve(public_token, opts) unless StackOneMigration::AccountHelper.stackone_account?(public_token)
9
+
10
+ account_data = StackOneHrisClient::AccountsApi.new.accounts_get(public_token)
11
+
12
+ integration_data = MergeHRISClient::AccountIntegration.new(slug: account_data.provider)
13
+ MergeHRISClient::AccountToken.new(account_token: public_token, integration: integration_data)
14
+
15
+ rescue StackOneHrisClient::ApiError
16
+ raise MergeHRISClient::ApiError
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module MergeHRISClient
6
+ class EmployeesApi
7
+ alias_method :original_employees_list, :employees_list
8
+
9
+ def employees_list(x_account_id, opts = {})
10
+ return original_employees_list(x_account_id, opts) unless StackOneMigration::AccountHelper.stackone_account?(x_account_id)
11
+
12
+ if opts.key?(:remote_id)
13
+ stripped_opts = opts.reject { |k, _| k == :remote_id }
14
+ response = StackOneHrisClient::EmployeesApi.new.employees_get(opts[:remote_id], x_account_id,
15
+ stripped_opts)
16
+
17
+ StackOneMigration::EmployeesMapper.map_single_employee_to_list_model(response&.data)
18
+ else
19
+ response = StackOneHrisClient::EmployeesApi.new.employees_list(x_account_id, opts)
20
+
21
+ StackOneMigration::EmployeesMapper.map_to_paginated_employee_list_model(response)
22
+ end
23
+ rescue StackOneHrisClient::ApiError
24
+ raise MergeHRISClient::ApiError
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ require 'cgi'
2
+
3
+ module MergeHRISClient
4
+ class LinkTokenApi
5
+ alias_method :original_link_token_create, :link_token_create
6
+
7
+ def link_token_create(end_user_details_request, opts = {})
8
+ return original_link_token_create(end_user_details_request, opts) if opts.key?(:use_merge) && opts[:use_merge]
9
+
10
+ connect_session_create_request = StackOneHrisClient::ConnectSessionCreate.new(
11
+ :origin_owner_id => end_user_details_request.end_user_origin_id,
12
+ :origin_owner_name => end_user_details_request.end_user_email_address,
13
+ :provider => end_user_details_request.integration,
14
+ :categories => end_user_details_request.categories,
15
+ )
16
+
17
+ created_session = StackOneHrisClient::ConnectSessionsApi.new.connect_sessions_create(connect_session_create_request)
18
+ MergeHRISClient::LinkToken.new(:link_token => created_session.token, :integration_name => end_user_details_request.integration)
19
+
20
+ rescue StackOneHrisClient::ApiError
21
+ raise MergeHRISClient::ApiError
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ module StackOneMigration
2
+ class AccountHelper
3
+ def self.stackone_account?(account_id)
4
+ account_id =~ /\A\d+\Z/
5
+ end
6
+
7
+ def self.merge_account?(account_id)
8
+ !stackone_account?(account_id)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module StackOneMigration
2
+ class EmployeesMapper
3
+ def self.map_to_employee_model(employee)
4
+ return nil if employee.nil?
5
+
6
+ MergeHRISClient::Employee.new(
7
+ :id => employee.id,
8
+ :remote_id => employee.id,
9
+ :first_name => employee.first_name,
10
+ :last_name => employee.last_name,
11
+ :display_full_name => employee.display_name,
12
+ :avatar => employee.avatar_url,
13
+ :personal_email => employee.personal_email,
14
+ :work_email => employee.work_email,
15
+ :mobile_phone_number => employee.personal_phone_number,
16
+ :gender => employee.gender,
17
+ :date_of_birth => employee.birth_date,
18
+ :start_date => employee.start_date,
19
+ :manager => employee.manager_id,
20
+ )
21
+ end
22
+
23
+ def self.map_single_employee_to_list_model(employee)
24
+ mapped_employee = map_to_employee_model(employee)
25
+
26
+ mapped_results = mapped_employee.nil? ? [] : [mapped_employee]
27
+
28
+ MergeHRISClient::PaginatedEmployeeList.new(
29
+ :_next => nil,
30
+ :results => mapped_results,
31
+ :previous => nil
32
+ )
33
+ end
34
+
35
+ def self.map_to_paginated_employee_list_model(paginated_employees)
36
+ if paginated_employees&.data.nil?
37
+ mapped_results = []
38
+ else
39
+ mapped_results = paginated_employees.data.map do |employee|
40
+ map_to_employee_model(employee)
41
+ end
42
+ end
43
+
44
+ next_page = paginated_employees.next_page unless paginated_employees.nil?
45
+
46
+ MergeHRISClient::PaginatedEmployeeList.new(
47
+ :_next => next_page,
48
+ :results => mapped_results,
49
+ :previous => nil
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StackOneMigration
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stackone_hris_client'
4
+ require 'merge_hris_client'
5
+
6
+ # Common files
7
+ require 'stackone_migration/version'
8
+
9
+ # APIs
10
+ require 'stackone_migration/api/employees_api'
11
+ require 'stackone_migration/api/account_token_api'
12
+ require 'stackone_migration/api/link_token_api'
13
+
14
+ # Mappers
15
+ require 'stackone_migration/mappers/employees_mapper'
16
+
17
+ # Helpers
18
+ require 'stackone_migration/helpers/account_helper'
19
+
20
+ module StackOneMigration
21
+ class << self
22
+ def configure
23
+ if block_given?
24
+ yield(Configuration.default)
25
+ else
26
+ Configuration.default
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe MergeHRISClient::AccountTokenApi do
6
+ subject { MergeHRISClient::AccountTokenApi.new }
7
+
8
+ context '.account_token_retrieve' do
9
+ context 'when the public token is an account id from StackOne' do
10
+ it 'returns a merge account token object' do
11
+ account_data = StackOneHrisClient::Account.new(:id => '12345', :provider => 'stackone_hris_provider')
12
+ stackone_account_api_double = double('StackOneHrisClient::AccountsApi', :accounts_get => account_data)
13
+ allow(StackOneHrisClient::AccountsApi).to receive(:new).and_return(stackone_account_api_double)
14
+
15
+ result = subject.account_token_retrieve('12345')
16
+
17
+ expect(result).to be_a(MergeHRISClient::AccountToken)
18
+ end
19
+
20
+ it 'returns an account token object with the right attributes' do
21
+ account_data = StackOneHrisClient::Account.new(:id => '12345', :provider => 'stackone_hris_provider')
22
+ stackone_account_api_double = double('StackOneHrisClient::AccountsApi', :accounts_get => account_data)
23
+ allow(StackOneHrisClient::AccountsApi).to receive(:new).and_return(stackone_account_api_double)
24
+
25
+ result = subject.account_token_retrieve('12345')
26
+
27
+ expect(result).to have_attributes(:account_token => '12345', :integration => MergeHRISClient::AccountIntegration.new(:slug => 'stackone_hris_provider'))
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'when the public token is from Merge' do
33
+ it 'calls the method from the Merge api to retrieve the account token' do
34
+ merge_account_token_api_double = double('MergeHRISClient::AccountTokenApi')
35
+ allow(MergeHRISClient::AccountTokenApi).to receive(:new).and_return(merge_account_token_api_double)
36
+ options = { :custom => 'option_value' }
37
+
38
+ expect(merge_account_token_api_double).to receive(:account_token_retrieve).with('123abc', options)
39
+
40
+ subject.account_token_retrieve('123abc', options)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe MergeHRISClient::EmployeesApi do
6
+ subject { MergeHRISClient::EmployeesApi.new }
7
+
8
+ context '.employees_list' do
9
+ context 'when the account id is from StackOne' do
10
+ it 'calls the method from the StackOne client to list employees' do
11
+ paginated_employees_double = double('StackOneHrisClient::PaginatedEmployeeList', :data => nil, :next_page => nil)
12
+ stackone_employees_api_double = double('StackOneHrisClient::EmployeesApi', :employees_list => paginated_employees_double)
13
+ allow(StackOneHrisClient::EmployeesApi).to receive(:new).and_return(stackone_employees_api_double)
14
+ options = { :expand => 'employments,home_location' }
15
+
16
+ expect(stackone_employees_api_double).to receive(:employees_list).with('123', options)
17
+
18
+ subject.employees_list('123', options)
19
+ end
20
+
21
+ context 'and the remote id param is in the options' do
22
+ it 'calls the method from the StackOne client to get an employee with remote id parameter' do
23
+ paginated_employees_double = double('StackOneHrisClient::PaginatedEmployeeList', :data => nil)
24
+ stackone_employees_api_double = double('StackOneHrisClient::EmployeesApi', :employees_get => paginated_employees_double)
25
+ allow(StackOneHrisClient::EmployeesApi).to receive(:new).and_return(stackone_employees_api_double)
26
+ options = { :expand => 'employments,home_location', :remote_id => '456' }
27
+
28
+ expect(stackone_employees_api_double).to receive(:employees_get).with('456', '123', { :expand => 'employments,home_location' })
29
+
30
+ subject.employees_list('123', options)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ context 'when the account id is from Merge' do
37
+ it 'calls the method from the Merge client to list employees' do
38
+ merge_employees_api_double = double('MergeHRISClient::EmployeesApi')
39
+ allow(MergeHRISClient::EmployeesApi).to receive(:new).and_return(merge_employees_api_double)
40
+ options = { :custom => 'option_value' }
41
+
42
+ expect(merge_employees_api_double).to receive(:employees_list).with('123abc', options)
43
+
44
+ subject.employees_list('123abc', options)
45
+ end
46
+
47
+ context 'and the remote id param is in the options' do
48
+ it 'calls the method from the Merge client to get an employee with remote id parameter' do
49
+ merge_employees_api_double = double('MergeHRISClient::EmployeesApi')
50
+ allow(MergeHRISClient::EmployeesApi).to receive(:new).and_return(merge_employees_api_double)
51
+ options = { :expand => 'employments,home_location', :remote_id => '456' }
52
+
53
+ expect(merge_employees_api_double).to receive(:employees_list).with('123abc', { :expand => 'employments,home_location', :remote_id => '456' })
54
+
55
+ subject.employees_list('123abc', options)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe MergeHRISClient::LinkTokenApi do
6
+ subject { MergeHRISClient::LinkTokenApi.new }
7
+
8
+ context '.link_token_create' do
9
+ context 'when the the key to use merge is not present in the options' do
10
+ it 'returns a merge link token object' do
11
+ session_data = StackOneHrisClient::ConnectSessionToken.new(:token => 'test_token')
12
+ connect_sessions_api_double = double('StackOneHrisClient::ConnectSessionsApi', :connect_sessions_create => session_data)
13
+ allow(StackOneHrisClient::ConnectSessionsApi).to receive(:new).and_return(connect_sessions_api_double)
14
+
15
+ end_user_details_request = MergeHRISClient::EndUserDetailsRequest.new(
16
+ :end_user_email_address => 'tos@potig.er',
17
+ :end_user_origin_id => 'user_origin_id',
18
+ :categories => ['hris'],
19
+ :integration => 'stackone_hris_provider',
20
+ )
21
+
22
+ result = subject.link_token_create(end_user_details_request)
23
+
24
+ expect(result).to be_a(MergeHRISClient::LinkToken)
25
+ end
26
+
27
+ it 'returns an object with the right attributes' do
28
+ session_data = StackOneHrisClient::ConnectSessionToken.new(:token => 'test_token')
29
+ connect_sessions_api_double = double('StackOneHrisClient::ConnectSessionsApi', :connect_sessions_create => session_data)
30
+ allow(StackOneHrisClient::ConnectSessionsApi).to receive(:new).and_return(connect_sessions_api_double)
31
+
32
+ end_user_details_request = MergeHRISClient::EndUserDetailsRequest.new(
33
+ :end_user_email_address => 'tos@potig.er',
34
+ :end_user_origin_id => 'user_origin_id',
35
+ :categories => ['hris'],
36
+ :integration => 'stackone_hris_provider',
37
+ )
38
+
39
+ result = subject.link_token_create(end_user_details_request)
40
+
41
+ expect(result).to have_attributes(:link_token => 'test_token', :integration_name => 'stackone_hris_provider', :magic_link_url => nil)
42
+ end
43
+
44
+ it 'calls the connect sessions api with the right parameters' do
45
+ session_data = StackOneHrisClient::ConnectSessionToken.new(:token => 'test_token')
46
+ connect_sessions_api_double = double('StackOneHrisClient::ConnectSessionsApi', :connect_sessions_create => session_data)
47
+ allow(StackOneHrisClient::ConnectSessionsApi).to receive(:new).and_return(connect_sessions_api_double)
48
+
49
+ end_user_details_request = MergeHRISClient::EndUserDetailsRequest.new(
50
+ :end_user_email_address => 'tos@potig.er',
51
+ :end_user_origin_id => 'user_origin_id',
52
+ :categories => ['hris'],
53
+ :integration => 'stackone_hris_provider',
54
+ )
55
+
56
+ expected_request = StackOneHrisClient::ConnectSessionCreate.new(
57
+ :origin_owner_id => 'user_origin_id',
58
+ :origin_owner_name => 'tos@potig.er',
59
+ :provider => 'stackone_hris_provider',
60
+ :categories => ['hris'],
61
+ )
62
+
63
+ expect(connect_sessions_api_double).to receive(:connect_sessions_create).with(expected_request)
64
+
65
+ result = subject.link_token_create(end_user_details_request)
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'when the the key to use merge is present in the options' do
71
+ it 'calls the method from the Merge api to create the link token' do
72
+ end_user_details_request = MergeHRISClient::EndUserDetailsRequest.new
73
+ merge_link_token_api_double = double('MergeHRISClient::LinkTokenApi')
74
+ allow(MergeHRISClient::LinkTokenApi).to receive(:new).and_return(merge_link_token_api_double)
75
+ options = { :custom => 'option_value', :use_merge => true }
76
+
77
+ expect(merge_link_token_api_double).to receive(:link_token_create).with(end_user_details_request, options)
78
+
79
+ subject.link_token_create(end_user_details_request, options)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe StackOneMigration::AccountHelper do
6
+ context '.stackone_account?' do
7
+ context 'when the account identifier is composed only by numbers' do
8
+ it 'returns true' do
9
+ result = described_class.stackone_account?('12345')
10
+
11
+ expect(result).to be_truthy
12
+ end
13
+ end
14
+
15
+ context 'when the account identifier is not composed only by numbers' do
16
+ it 'returns false' do
17
+ result = described_class.stackone_account?('12345abc')
18
+
19
+ expect(result).to be_falsey
20
+ end
21
+ end
22
+ end
23
+
24
+ context '.merge_account?' do
25
+ context 'when the account identifier is not composed only by numbers' do
26
+ it 'returns true' do
27
+ result = described_class.merge_account?('12345abc')
28
+
29
+ expect(result).to be_truthy
30
+ end
31
+ end
32
+
33
+ context 'when the account identifier is composed only by numbers' do
34
+ it 'returns false' do
35
+ result = described_class.merge_account?('12345')
36
+
37
+ expect(result).to be_falsey
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe StackOneMigration::EmployeesMapper do
6
+ let(:sample_employee) {
7
+ StackOneHrisClient::Employee.new(
8
+ :id => '123',
9
+ :first_name => 'Jean',
10
+ :last_name => 'Harrington',
11
+ :display_name => 'Jean Harrington',
12
+ :name => 'Jean Marie Harrington',
13
+ :avatar_url => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
14
+ :personal_email => 'ija@egje.wf',
15
+ :work_email => 'kota@efpiphi.kw',
16
+ :personal_phone_number => '(715) 658-9486',
17
+ :gender => 'female',
18
+ :birth_date => '1990-01-01',
19
+ :start_date => '2018-01-01',
20
+ :manager_id => '417b5e62-e011-5e69-a906-0aefade9ded1',
21
+ :work_phone_number => '(456) 787-3508',
22
+ :title => 'Manager',
23
+ :department => 'Human Resources',
24
+ )
25
+ }
26
+ let(:other_sample_employee) {
27
+ StackOneHrisClient::Employee.new(
28
+ :id => '456',
29
+ :first_name => 'Allie',
30
+ :last_name => 'Shaw',
31
+ :display_name => 'Allie Shaw',
32
+ :name => 'Allie Jennifer Shaw',
33
+ :avatar_url => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
34
+ :personal_email => 'ija@egje.wf',
35
+ :work_email => 'kota@efpiphi.kw',
36
+ :personal_phone_number => '(715) 658-9486',
37
+ :gender => 'female',
38
+ :birth_date => '1990-01-01',
39
+ :start_date => '2018-01-01',
40
+ :manager_id => '417b5e62-e011-5e69-a906-0aefade9ded1',
41
+ :work_phone_number => '(456) 787-3508',
42
+ :title => 'Manager',
43
+ :department => 'Human Resources',
44
+ )
45
+ }
46
+
47
+ context '.map_to_employee_model' do
48
+ it 'maps the employee to the target employee class' do
49
+ target_model = described_class.map_to_employee_model(sample_employee)
50
+
51
+ expect(target_model).to be_a(MergeHRISClient::Employee)
52
+ end
53
+
54
+ it 'maps the employee attributes with the right structure to the target class' do
55
+ target_model = described_class.map_to_employee_model(sample_employee)
56
+
57
+ expect(target_model).to have_attributes(
58
+ :id => '123',
59
+ :remote_id => '123',
60
+ :first_name => 'Jean',
61
+ :last_name => 'Harrington',
62
+ :display_full_name => 'Jean Harrington',
63
+ :avatar => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
64
+ :personal_email => 'ija@egje.wf',
65
+ :work_email => 'kota@efpiphi.kw',
66
+ :mobile_phone_number => '(715) 658-9486',
67
+ :gender => 'female',
68
+ :date_of_birth => '1990-01-01',
69
+ :start_date => '2018-01-01',
70
+ :manager => '417b5e62-e011-5e69-a906-0aefade9ded1',
71
+ )
72
+ end
73
+
74
+ context 'when the employee record to map is nil' do
75
+ it 'returns nil' do
76
+ target_model = described_class.map_to_employee_model(nil)
77
+
78
+ expect(target_model).to be_nil
79
+ end
80
+ end
81
+ end
82
+
83
+ context '.map_single_employee_to_list_model' do
84
+ it 'maps a single employee to a paginated employee list class' do
85
+ target_model = described_class.map_single_employee_to_list_model(sample_employee)
86
+
87
+ expect(target_model).to be_a(MergeHRISClient::PaginatedEmployeeList)
88
+ end
89
+
90
+ it 'maps a single employee to a paginated employee with the right attributes' do
91
+ target_model = described_class.map_single_employee_to_list_model(sample_employee)
92
+
93
+ expect(target_model).to have_attributes(
94
+ :_next => nil,
95
+ :results => [
96
+ MergeHRISClient::Employee.new(
97
+ :id => '123',
98
+ :remote_id => '123',
99
+ :first_name => 'Jean',
100
+ :last_name => 'Harrington',
101
+ :display_full_name => 'Jean Harrington',
102
+ :avatar => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
103
+ :personal_email => 'ija@egje.wf',
104
+ :work_email => 'kota@efpiphi.kw',
105
+ :mobile_phone_number => '(715) 658-9486',
106
+ :gender => 'female',
107
+ :date_of_birth => '1990-01-01',
108
+ :start_date => '2018-01-01',
109
+ :manager => '417b5e62-e011-5e69-a906-0aefade9ded1',
110
+ )
111
+ ],
112
+ :previous => nil)
113
+ end
114
+
115
+ context 'when the single employee record to map is nil' do
116
+ it 'returns the paginated employee list with empty results' do
117
+ target_model = described_class.map_single_employee_to_list_model(nil)
118
+
119
+ expect(target_model).to have_attributes(
120
+ :_next => nil,
121
+ :results => [],
122
+ :previous => nil)
123
+ end
124
+ end
125
+ end
126
+
127
+ context '.map_to_paginated_employee_list_model' do
128
+ it 'maps the employees to a paginated employee list classl' do
129
+ other_sample_employee = sample_employee.clone
130
+
131
+ stackone_paginated_employees = StackOneHrisClient::EmployeesPaginated.new(
132
+ :next_page => 'next_page_token',
133
+ :data => [sample_employee, other_sample_employee],
134
+ )
135
+
136
+ target_model = described_class.map_to_paginated_employee_list_model(stackone_paginated_employees)
137
+
138
+ expect(target_model).to be_a(MergeHRISClient::PaginatedEmployeeList)
139
+ end
140
+
141
+
142
+ it 'maps the employee list attributes with the right structure to the target class' do
143
+ stackone_paginated_employees = StackOneHrisClient::EmployeesPaginated.new(
144
+ :next_page => 'next_page_token',
145
+ :data => [sample_employee, other_sample_employee],
146
+ )
147
+
148
+ target_model = described_class.map_to_paginated_employee_list_model(stackone_paginated_employees)
149
+
150
+ expect(target_model).to have_attributes(
151
+ :_next => 'next_page_token',
152
+ :results => [
153
+ MergeHRISClient::Employee.new(
154
+ :id => '123',
155
+ :remote_id => '123',
156
+ :first_name => 'Jean',
157
+ :last_name => 'Harrington',
158
+ :display_full_name => 'Jean Harrington',
159
+ :avatar => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
160
+ :personal_email => 'ija@egje.wf',
161
+ :work_email => 'kota@efpiphi.kw',
162
+ :mobile_phone_number => '(715) 658-9486',
163
+ :gender => 'female',
164
+ :date_of_birth => '1990-01-01',
165
+ :start_date => '2018-01-01',
166
+ :manager => '417b5e62-e011-5e69-a906-0aefade9ded1',
167
+ ),
168
+ MergeHRISClient::Employee.new(
169
+ :id => '456',
170
+ :remote_id => '456',
171
+ :first_name => 'Allie',
172
+ :last_name => 'Shaw',
173
+ :display_full_name => 'Allie Shaw',
174
+ :avatar => 'https://www.gravatar.com/avatar/0c1c0c1c0c1c0c1c0c1c0c1c0c1c0c1c?d=mm&s=200',
175
+ :personal_email => 'ija@egje.wf',
176
+ :work_email => 'kota@efpiphi.kw',
177
+ :mobile_phone_number => '(715) 658-9486',
178
+ :gender => 'female',
179
+ :date_of_birth => '1990-01-01',
180
+ :start_date => '2018-01-01',
181
+ :manager => '417b5e62-e011-5e69-a906-0aefade9ded1',
182
+ )
183
+ ],
184
+ :previous => nil
185
+ )
186
+ end
187
+
188
+ context 'when the employee list to map is nil' do
189
+ it 'returns the paginated employee list with empty results' do
190
+ target_model = described_class.map_to_paginated_employee_list_model(nil)
191
+
192
+ expect(target_model).to have_attributes(
193
+ :_next => nil,
194
+ :results => [],
195
+ :previous => nil)
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ # load the gem
4
+ require 'stackone_migration'
5
+
6
+ # The following was generated by the `rspec --init` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
9
+ # this file to always be loaded, without a need to explicitly require it in any
10
+ # files.
11
+ #
12
+ # Given that it is always loaded, you are encouraged to keep this file as
13
+ # light-weight as possible. Requiring heavyweight dependencies from this file
14
+ # will add to the boot time of your test suite on EVERY test run, even for an
15
+ # individual file that may not need all of that loaded. Instead, consider making
16
+ # a separate helper file that requires the additional dependencies and performs
17
+ # the additional setup, and require it from the spec files that actually need
18
+ # it.
19
+ #
20
+ # The `.rspec` file also contains a few flags that are not defaults but that
21
+ # users commonly want.
22
+ #
23
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
24
+ RSpec.configure do |config|
25
+ # rspec-expectations config goes here. You can use an alternate
26
+ # assertion/expectation library such as wrong or the stdlib/minitest
27
+ # assertions if you prefer.
28
+ config.expect_with :rspec do |expectations|
29
+ # This option will default to `true` in RSpec 4. It makes the `description`
30
+ # and `failure_message` of custom matchers include text for helper methods
31
+ # defined using `chain`, e.g.:
32
+ # be_bigger_than(2).and_smaller_than(4).description
33
+ # # => "be bigger than 2 and smaller than 4"
34
+ # ...rather than:
35
+ # # => "be bigger than 2"
36
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
37
+ end
38
+
39
+ # rspec-mocks config goes here. You can use an alternate test double
40
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
41
+ config.mock_with :rspec do |mocks|
42
+ # Prevents you from mocking or stubbing a method that does not exist on
43
+ # a real object. This is generally recommended, and will default to
44
+ # `true` in RSpec 4.
45
+ mocks.verify_partial_doubles = true
46
+ end
47
+
48
+ # The settings below are suggested to provide a good initial experience
49
+ # with RSpec, but feel free to customize to your heart's content.
50
+ # # These two settings work together to allow you to limit a spec run
51
+ # # to individual examples or groups you care about by tagging them with
52
+ # # `:focus` metadata. When nothing is tagged with `:focus`, all examples
53
+ # # get run.
54
+ # config.filter_run :focus
55
+ # config.run_all_when_everything_filtered = true
56
+ #
57
+ # # Allows RSpec to persist some state between runs in order to support
58
+ # # the `--only-failures` and `--next-failure` CLI options. We recommend
59
+ # # you configure your source control system to ignore this file.
60
+ # config.example_status_persistence_file_path = "spec/examples.txt"
61
+ #
62
+ # # Limits the available syntax to the non-monkey patched syntax that is
63
+ # # recommended. For more details, see:
64
+ # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
65
+ # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
66
+ # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
67
+ # config.disable_monkey_patching!
68
+ #
69
+ # # This setting enables warnings. It's recommended, but in some cases may
70
+ # # be too noisy due to issues in dependencies.
71
+ # config.warnings = true
72
+ #
73
+ # # Many RSpec users commonly either run the entire suite or an individual
74
+ # # file, and it's useful to allow more verbose output when running an
75
+ # # individual spec file.
76
+ # if config.files_to_run.one?
77
+ # # Use the documentation formatter for detailed output,
78
+ # # unless a formatter has already been configured
79
+ # # (e.g. via a command-line flag).
80
+ # config.default_formatter = 'doc'
81
+ # end
82
+ #
83
+ # # Print the 10 slowest examples and example groups at the
84
+ # # end of the spec run, to help surface which specs are running
85
+ # # particularly slow.
86
+ # config.profile_examples = 10
87
+ #
88
+ # # Run specs in random order to surface order dependencies. If you find an
89
+ # # order dependency and want to debug it, you can fix the order by providing
90
+ # # the seed, which is printed after each run.
91
+ # # --seed 1234
92
+ # config.order = :random
93
+ #
94
+ # # Seed global randomization in this process using the `--seed` CLI option.
95
+ # # Setting this allows you to use `--seed` to deterministically reproduce
96
+ # # test failures related to randomization by passing the same `--seed` value
97
+ # # as the one that triggered the failure.
98
+ # Kernel.srand config.seed
99
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
+ require 'stackone_migration/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'stackone_migration'
8
+ s.version = StackOneMigration::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ['StackOne']
11
+ s.email = ['developer-support@stackone.comm']
12
+ s.homepage = 'https://stackone.com'
13
+ s.summary = 'StackOne migration client gem'
14
+ s.description = 'StackOne Unified API client for systems migration'
15
+ s.license = 'MIT'
16
+ s.required_ruby_version = '>= 2.7'
17
+
18
+ s.add_runtime_dependency 'merge_hris_client', '~> 3.0'
19
+ s.add_runtime_dependency 'stackone_hris_client', '~> 1.1'
20
+
21
+ s.add_development_dependency 'rspec', '~> 3.6', '>= 3.6.0'
22
+
23
+ s.files = `find *`.split("\n").uniq.sort.reject(&:empty?)
24
+ s.test_files = `find spec/*`.split("\n")
25
+ s.executables = []
26
+ s.require_paths = ['lib']
27
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stackone_migration
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - StackOne
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-03-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: merge_hris_client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: stackone_hris_client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.6'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 3.6.0
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.6'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 3.6.0
61
+ description: StackOne Unified API client for systems migration
62
+ email:
63
+ - developer-support@stackone.comm
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - Gemfile
69
+ - Gemfile.lock
70
+ - LICENSE
71
+ - README.md
72
+ - Rakefile
73
+ - lib/stackone_migration.rb
74
+ - lib/stackone_migration/api/account_token_api.rb
75
+ - lib/stackone_migration/api/employees_api.rb
76
+ - lib/stackone_migration/api/link_token_api.rb
77
+ - lib/stackone_migration/helpers/account_helper.rb
78
+ - lib/stackone_migration/mappers/employees_mapper.rb
79
+ - lib/stackone_migration/version.rb
80
+ - spec/api/account_token_api_spec.rb
81
+ - spec/api/employees_api_spec.rb
82
+ - spec/api/link_token_api_spec.rb
83
+ - spec/helpers/account_helper_spec.rb
84
+ - spec/mappers/employees_mapper_spec.rb
85
+ - spec/spec_helper.rb
86
+ - stackone_migration.gemspec
87
+ homepage: https://stackone.com
88
+ licenses:
89
+ - MIT
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '2.7'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubygems_version: 3.1.6
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: StackOne migration client gem
110
+ test_files:
111
+ - spec/api/employees_api_spec.rb
112
+ - spec/api/account_token_api_spec.rb
113
+ - spec/api/link_token_api_spec.rb
114
+ - spec/helpers/account_helper_spec.rb
115
+ - spec/mappers/employees_mapper_spec.rb
116
+ - spec/spec_helper.rb