From a77a77dd915b66864a7b870355c1ae6d96ae13b5 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 21 Jun 2024 15:12:51 +0200 Subject: [PATCH 01/79] Create migration to add ptime id to person model --- db/migrate/20240621131028_add_p_time_id_to_people.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240621131028_add_p_time_id_to_people.rb diff --git a/db/migrate/20240621131028_add_p_time_id_to_people.rb b/db/migrate/20240621131028_add_p_time_id_to_people.rb new file mode 100644 index 000000000..302a4768f --- /dev/null +++ b/db/migrate/20240621131028_add_p_time_id_to_people.rb @@ -0,0 +1,5 @@ +class AddPTimeIdToPeople < ActiveRecord::Migration[7.0] + def change + add_column :people, :ptime_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 14cf33abf..d4e7f888b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_03_085509) do +ActiveRecord::Schema[7.0].define(version: 2024_06_21_131028) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -148,6 +148,7 @@ t.string "email" t.integer "department_id" t.string "shortname" + t.integer "ptime_id" t.index ["company_id"], name: "index_people_on_company_id" end From 665bf0bbb1ad2aaa03b95b6f5d6873e18f10dbf9 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 21 Jun 2024 15:54:21 +0200 Subject: [PATCH 02/79] Start writing mapper script --- app/ptime_mapper.rb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 app/ptime_mapper.rb diff --git a/app/ptime_mapper.rb b/app/ptime_mapper.rb new file mode 100644 index 000000000..b8c2592b8 --- /dev/null +++ b/app/ptime_mapper.rb @@ -0,0 +1,24 @@ +require 'uri' +require 'net/http' +require 'active_record' +require_relative '../config/environment' + +def fetch_ptime_data + url = URI('/api/v1/employees') + + https = Net::HTTP.new(url.host, url.port) + https.use_ssl = true + + request = Net::HTTP::Get.new(url) + request['Authorization'] = 'Basic ' + + response = https.request(request) + @ptime_people = response.read_body +end + +def load_skills_data + @skills_people = Person.all +end + +load_skills_data +puts @skills_people.pluck(:name) From 2f1660f4f70701fcfafc154d9637a8dd9188588c Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 24 Jun 2024 14:18:27 +0200 Subject: [PATCH 03/79] Implement basic PTime client class and install webmock gem --- .gitignore | 2 ++ Gemfile | 1 + Gemfile.lock | 10 ++++++++++ app/domain/ptime/client.rb | 36 ++++++++++++++++++++++++++++++++++++ app/ptime_mapper.rb | 24 ------------------------ docker-compose.yml | 4 +++- 6 files changed, 52 insertions(+), 25 deletions(-) create mode 100644 app/domain/ptime/client.rb delete mode 100644 app/ptime_mapper.rb diff --git a/.gitignore b/.gitignore index dbebe2096..df6ff684e 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,5 @@ config/docker/development/home/rails/.bash_history /app/assets/builds/* !/app/assets/builds/.keep + +.sec diff --git a/Gemfile b/Gemfile index 8b71dcd7a..ca6809334 100644 --- a/Gemfile +++ b/Gemfile @@ -77,6 +77,7 @@ group :test do gem 'capybara' gem 'selenium-webdriver', '>= 4.11.8' gem 'simplecov' + gem 'webmock' # Use fixed version of webdrivers to avoid compatibility issues with chrome and chromedriver end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Gemfile.lock b/Gemfile.lock index 6c6c6c9c6..53b350008 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,6 +82,7 @@ GEM ast (2.4.2) base64 (0.2.0) bcrypt (3.1.20) + bigdecimal (3.1.8) bindata (2.5.0) bleib (0.0.8) bootsnap (1.18.3) @@ -118,6 +119,9 @@ GEM deep_merge (~> 1.2, >= 1.2.1) countries (6.0.0) unaccent (~> 0.3) + crack (1.0.0) + bigdecimal + rexml crass (1.0.6) cssbundling-rails (1.4.0) railties (>= 6.0.0) @@ -166,6 +170,7 @@ GEM rainbow rubocop (>= 1.0) sysexits (~> 1.1) + hashdiff (1.1.0) hashie (5.0.0) http-accept (1.7.0) http-cookie (1.0.5) @@ -444,6 +449,10 @@ GEM version_gem (1.1.4) warden (1.2.9) rack (>= 2.0.9) + webmock (3.23.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) websocket (1.2.10) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -517,6 +526,7 @@ DEPENDENCIES stimulus-rails turbo-rails tzinfo-data + webmock BUNDLED WITH 2.4.10 diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb new file mode 100644 index 000000000..2a82a4e37 --- /dev/null +++ b/app/domain/ptime/client.rb @@ -0,0 +1,36 @@ +require 'rest_client' +require 'base64' +require_relative '../../../config/environment' + +module Ptime + class Client + BASE_URL = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/".freeze + + def get(endpoint, params = {}) + request(:get, BASE_URL + endpoint, params) + end + + private + + def request(method, path, params = nil) + response = RestClient.send(method, path, headers.merge(params)) + JSON.parse(response.body) + rescue RestClient::BadRequest => e + msg = response_error_message(e) + e.message = msg if msg.present? + raise e + end + + def headers + { + authorization: "Basic #{basic_token}", + content_type: :json, + accept: :json + } + end + + def basic_token + Base64.encode64("#{ENV.fetch('PTIME_API_USERNAME')}:#{ENV.fetch('PTIME_API_PASSWORD')}") + end + end +end diff --git a/app/ptime_mapper.rb b/app/ptime_mapper.rb deleted file mode 100644 index b8c2592b8..000000000 --- a/app/ptime_mapper.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'uri' -require 'net/http' -require 'active_record' -require_relative '../config/environment' - -def fetch_ptime_data - url = URI('/api/v1/employees') - - https = Net::HTTP.new(url.host, url.port) - https.use_ssl = true - - request = Net::HTTP::Get.new(url) - request['Authorization'] = 'Basic ' - - response = https.request(request) - @ptime_people = response.read_body -end - -def load_skills_data - @skills_people = Person.all -end - -load_skills_data -puts @skills_people.pluck(:name) diff --git a/docker-compose.yml b/docker-compose.yml index cedb92fef..8568cb03a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,7 +7,9 @@ services: stdin_open: true environment: - RAILS_DB_HOST=postgres - env_file: .env + env_file: + - .env + - .sec build: context: ./config/docker/development dockerfile: Rails.dockerfile From 0555ec7214236f459364fc0d922059f21e3e0623 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 24 Jun 2024 14:27:30 +0200 Subject: [PATCH 04/79] Create new migration to fix naming of ptime_emplyoee_id attribute --- db/migrate/20240621131028_add_p_time_id_to_people.rb | 5 ----- db/migrate/20240624122411_add_ptime_employee_id_to_people.rb | 5 +++++ db/schema.rb | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 db/migrate/20240621131028_add_p_time_id_to_people.rb create mode 100644 db/migrate/20240624122411_add_ptime_employee_id_to_people.rb diff --git a/db/migrate/20240621131028_add_p_time_id_to_people.rb b/db/migrate/20240621131028_add_p_time_id_to_people.rb deleted file mode 100644 index 302a4768f..000000000 --- a/db/migrate/20240621131028_add_p_time_id_to_people.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddPTimeIdToPeople < ActiveRecord::Migration[7.0] - def change - add_column :people, :ptime_id, :integer - end -end diff --git a/db/migrate/20240624122411_add_ptime_employee_id_to_people.rb b/db/migrate/20240624122411_add_ptime_employee_id_to_people.rb new file mode 100644 index 000000000..d2a4f3dfb --- /dev/null +++ b/db/migrate/20240624122411_add_ptime_employee_id_to_people.rb @@ -0,0 +1,5 @@ +class AddPtimeEmployeeIdToPeople < ActiveRecord::Migration[7.0] + def change + add_column :people, :ptime_employee_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index d4e7f888b..038f495fa 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_21_131028) do +ActiveRecord::Schema[7.0].define(version: 2024_06_24_122411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -148,7 +148,7 @@ t.string "email" t.integer "department_id" t.string "shortname" - t.integer "ptime_id" + t.integer "ptime_employee_id" t.index ["company_id"], name: "index_people_on_company_id" end From 83fa511875d2e98522e1531c7315743fd45e58d5 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 24 Jun 2024 15:45:55 +0200 Subject: [PATCH 05/79] Add first test to see how webmock works --- spec/domain/ptime/client.spec.rb | 15 +++++++++++++++ spec/spec_helper.rb | 1 + 2 files changed, 16 insertions(+) create mode 100644 spec/domain/ptime/client.spec.rb diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb new file mode 100644 index 000000000..463d5e57f --- /dev/null +++ b/spec/domain/ptime/client.spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +describe Ptime::Client do + before(:each) do + ENV["PTIME_BASE_URL"] = "www.api.com" + ENV["PTIME_API_USERNAME"] = "" + ENV["PTIME_API_PASSWORD"] = "" + stub_request(:get, "www.api.com"). + to_return(body: "abc".to_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + end + + it 'should test' do + Ptime::Client.new.get(""); + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3a432a8e6..1a58838d1 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +require 'webmock/rspec' require 'simplecov' SimpleCov.start SimpleCov.coverage_dir 'spec/coverage' From fbc898785c00771e69754e22241fa91dfff7c813 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 24 Jun 2024 16:03:11 +0200 Subject: [PATCH 06/79] Fix first client spec --- spec/domain/ptime/client.spec.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index 463d5e57f..e0d2da0e7 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -1,15 +1,16 @@ require 'rails_helper' +ENV["PTIME_BASE_URL"] = "www.api.com" +ENV["PTIME_API_USERNAME"] = "test username" +ENV["PTIME_API_PASSWORD"] = "test password" + describe Ptime::Client do before(:each) do - ENV["PTIME_BASE_URL"] = "www.api.com" - ENV["PTIME_API_USERNAME"] = "" - ENV["PTIME_API_PASSWORD"] = "" - stub_request(:get, "www.api.com"). + stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees"). to_return(body: "abc".to_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) end - it 'should test' do - Ptime::Client.new.get(""); + it 'should be able to fetch employee data' do + fetched_employees = Ptime::Client.new.get("employees"); end end From 6a75e33908d95a7fac428e33fb89148c88f810f7 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 08:46:47 +0200 Subject: [PATCH 07/79] Write json body to test employee endpoint --- spec/domain/ptime/client.spec.rb | 61 ++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index e0d2da0e7..8e07af651 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -5,12 +5,69 @@ ENV["PTIME_API_PASSWORD"] = "test password" describe Ptime::Client do + employees_json = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'LSM', + 'firstname': 'Longmax', + 'lastname': 'Smith', + 'email': 'longmax@smith.com', + 'single': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'BSc in Architecture', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 21, + 'type': 'employee', + 'attributes': { + 'shortname': 'AMA', + 'firstname': 'Alice', + 'lastname': 'Mante', + 'email': 'alice@mante.com', + 'single': 'single', + 'nationalities': [ + 'AU' + ], + 'graduation': 'MSc in writing', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 45, + 'type': 'employee', + 'attributes': { + 'shortname': 'CFO', + 'firstname': 'Charlie', + 'lastname': 'Ford', + 'email': 'charlie@ford.com', + 'single': 'married', + 'nationalities': [ + 'GB' + ], + 'graduation': 'MSc in networking', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + ] + }.to_json + before(:each) do stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees"). - to_return(body: "abc".to_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + to_return(body: employees_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) end it 'should be able to fetch employee data' do - fetched_employees = Ptime::Client.new.get("employees"); + fetched_employees = Ptime::Client.new.get("employees") + expect(fetched_employees).to eq(JSON.parse(employees_json)) end end From 6a9a89a74e8edf31b457bb790401049679d30a34 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 09:16:19 +0200 Subject: [PATCH 08/79] Fix tests by allowing localhost connection and write negative test for the ptime client --- app/domain/ptime/client.rb | 6 ++++-- spec/domain/ptime/client.spec.rb | 15 +++++++++++---- spec/spec_helper.rb | 2 ++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 2a82a4e37..fd62521dd 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -4,10 +4,12 @@ module Ptime class Client - BASE_URL = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/".freeze + def initialize + @base_url = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/".freeze + end def get(endpoint, params = {}) - request(:get, BASE_URL + endpoint, params) + request(:get, @base_url + endpoint, params) end private diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index 8e07af651..25bcb2019 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -61,13 +61,20 @@ ] }.to_json - before(:each) do + it 'should be able to fetch employee data' do stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees"). - to_return(body: employees_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - end + to_return(body: employees_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - it 'should be able to fetch employee data' do fetched_employees = Ptime::Client.new.get("employees") expect(fetched_employees).to eq(JSON.parse(employees_json)) end + + it 'should throw error message when host is not reachable' do + ENV["PTIME_BASE_URL"] = "www.unreachablehost.com" + + stub_request(:get, "www.unreachablehost.com/api/v1/"). + to_return(body: employees_json, status: 404) + + expect{ Ptime::Client.new.get("") }.to raise_error(RestClient::NotFound) + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1a58838d1..5d9fed904 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,8 @@ SimpleCov.start SimpleCov.coverage_dir 'spec/coverage' +WebMock.disable_net_connect!(allow_localhost: true) + RSpec.configure do |config| config.before(:suite) do From 9ddd72361e03f1e25e449f5522e4cce12ca91a9f Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 09:22:58 +0200 Subject: [PATCH 09/79] Make ptime client specs not read values from env variables --- spec/domain/ptime/client.spec.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index 25bcb2019..1ea6956f7 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -1,8 +1,11 @@ require 'rails_helper' -ENV["PTIME_BASE_URL"] = "www.api.com" -ENV["PTIME_API_USERNAME"] = "test username" -ENV["PTIME_API_PASSWORD"] = "test password" +ptime_base_test_url = "www.api.com" +ptime_api_test_username = "test username" +ptime_api_test_password = "test password" +ENV["PTIME_BASE_URL"] = ptime_base_test_url +ENV["PTIME_API_USERNAME"] = ptime_api_test_username +ENV["PTIME_API_PASSWORD"] = ptime_api_test_password describe Ptime::Client do employees_json = { @@ -62,8 +65,9 @@ }.to_json it 'should be able to fetch employee data' do - stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees"). + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees"). to_return(body: employees_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) fetched_employees = Ptime::Client.new.get("employees") expect(fetched_employees).to eq(JSON.parse(employees_json)) @@ -74,6 +78,7 @@ stub_request(:get, "www.unreachablehost.com/api/v1/"). to_return(body: employees_json, status: 404) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) expect{ Ptime::Client.new.get("") }.to raise_error(RestClient::NotFound) end From 7ab67272a589bf5a59dec0a504ce4281f5876136 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 09:49:27 +0200 Subject: [PATCH 10/79] Set error messages on errors in client and change test data urls to example.com --- app/domain/ptime/client.rb | 6 ++++++ spec/domain/ptime/client.spec.rb | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index fd62521dd..7efcc2c1b 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -23,6 +23,12 @@ def request(method, path, params = nil) raise e end + def response_error_message(exception) + JSON.parse(exception.response.body).dig('error', 'message') + rescue # do not fail if response is not JSON + nil + end + def headers { authorization: "Basic #{basic_token}", diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index 1ea6956f7..88edf98cb 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -ptime_base_test_url = "www.api.com" +ptime_base_test_url = "www.ptime.example.com" ptime_api_test_username = "test username" ptime_api_test_password = "test password" ENV["PTIME_BASE_URL"] = ptime_base_test_url @@ -17,7 +17,7 @@ 'shortname': 'LSM', 'firstname': 'Longmax', 'lastname': 'Smith', - 'email': 'longmax@smith.com', + 'email': 'longmax@example.com', 'single': 'single', 'nationalities': [ 'ZW' @@ -34,7 +34,7 @@ 'shortname': 'AMA', 'firstname': 'Alice', 'lastname': 'Mante', - 'email': 'alice@mante.com', + 'email': 'alice@example.com', 'single': 'single', 'nationalities': [ 'AU' @@ -51,7 +51,7 @@ 'shortname': 'CFO', 'firstname': 'Charlie', 'lastname': 'Ford', - 'email': 'charlie@ford.com', + 'email': 'charlie@example.com', 'single': 'married', 'nationalities': [ 'GB' @@ -74,9 +74,9 @@ end it 'should throw error message when host is not reachable' do - ENV["PTIME_BASE_URL"] = "www.unreachablehost.com" + ENV["PTIME_BASE_URL"] = "www.unreachablehost.example.com" - stub_request(:get, "www.unreachablehost.com/api/v1/"). + stub_request(:get, "www.unreachablehost.example.com/api/v1/"). to_return(body: employees_json, status: 404) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) From 8f85e918de315d0fe146649633a344ded9e9f5c0 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 14:14:55 +0200 Subject: [PATCH 11/79] Fix params of ptime client and implement basic mapper script --- app/domain/ptime/assign_employee_ids.rb | 57 +++++++++++++++++++++++++ app/domain/ptime/client.rb | 7 ++- lib/tasks/ptime.rake | 6 +++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 app/domain/ptime/assign_employee_ids.rb create mode 100644 lib/tasks/ptime.rake diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb new file mode 100644 index 000000000..2eeebbf77 --- /dev/null +++ b/app/domain/ptime/assign_employee_ids.rb @@ -0,0 +1,57 @@ +require_relative '../../../config/environment' + +# This script will assign each person the corresponding employee ID from PuzzleTime +module Ptime + class AssignEmployeeIds + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/AbcSize + def run + puts 'Fetching required data...' + ptime_employees = Ptime::Client.new.get('employees', { per_page: 2 })['data'] + skills_people = Person.all + puts 'Successfully fetched data' + + puts "Currently there are: + - #{ptime_employees.length} employees in PuzzleTime + - #{skills_people.count} people in PuzzleSkills + This is a difference of #{(skills_people.count - ptime_employees.length).abs} entries" + + puts 'Assigning employee IDs now...' + + ambiguous_entries = [] + unmatched_entries = [] + mapped_people_count = 0 + + ptime_employees.each do |ptime_employee| + ptime_employee_firstname = ptime_employee['attributes']['first_name'] + ptime_employee_lastname = ptime_employee['attributes']['last_name'] + ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" + matched_skills_people = Person.where(ptime_employee_id: nil) + .where(name: ptime_employee_name) + + if matched_skills_people.empty? + unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] } + elsif matched_skills_people.count == 1 + matched_skills_person = matched_skills_people.first + matched_skills_person.ptime_employee_id = ptime_employee['id'] + matched_skills_person.save! + mapped_people_count += 1 + else + ambiguous_entries << { name: ptime_employee_name, id: ptime_employee['id'] } + end + end + + puts '--------------------------' + puts "#{mapped_people_count} people were matched successfully" + puts '--------------------------' + puts "#{unmatched_entries.size} people didn't match" + unmatched_entries.each { |entry| puts "- #{entry[:name]} with id #{entry[:id]}" } + puts '--------------------------' + puts "#{ambiguous_entries.size} people ambiguous matched" + ambiguous_entries.each { |entry| puts "- #{entry[:name]} with id #{entry[:id]}" } + end + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/AbcSize + end +end + diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 7efcc2c1b..f7880f06a 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rest_client' require 'base64' require_relative '../../../config/environment' @@ -5,7 +7,7 @@ module Ptime class Client def initialize - @base_url = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/".freeze + @base_url = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/" end def get(endpoint, params = {}) @@ -15,7 +17,8 @@ def get(endpoint, params = {}) private def request(method, path, params = nil) - response = RestClient.send(method, path, headers.merge(params)) + path = "#{path}?#{URI.encode_www_form(params)}" + response = RestClient.send(method, path, headers) JSON.parse(response.body) rescue RestClient::BadRequest => e msg = response_error_message(e) diff --git a/lib/tasks/ptime.rake b/lib/tasks/ptime.rake new file mode 100644 index 000000000..2fb7c883b --- /dev/null +++ b/lib/tasks/ptime.rake @@ -0,0 +1,6 @@ +namespace :ptime do + desc 'assign puzzletime employee ids to people' + task :assign => :environment do + Ptime::AssignEmployeeIds.new.run + end +end \ No newline at end of file From f9453787a50587db34264c2f08103f2369865eb0 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 25 Jun 2024 15:46:43 +0200 Subject: [PATCH 12/79] Add new tests and remove unnecessary --- app/domain/ptime/assign_employee_ids.rb | 6 +- spec/domain/ptime/assign_emplyoee_ids.spec.rb | 101 ++++++++++++++++++ spec/domain/ptime/client.spec.rb | 2 +- 3 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 spec/domain/ptime/assign_emplyoee_ids.spec.rb diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 2eeebbf77..e73727750 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -7,7 +7,7 @@ class AssignEmployeeIds # rubocop:disable Metrics/AbcSize def run puts 'Fetching required data...' - ptime_employees = Ptime::Client.new.get('employees', { per_page: 2 })['data'] + ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] skills_people = Person.all puts 'Successfully fetched data' @@ -23,8 +23,8 @@ def run mapped_people_count = 0 ptime_employees.each do |ptime_employee| - ptime_employee_firstname = ptime_employee['attributes']['first_name'] - ptime_employee_lastname = ptime_employee['attributes']['last_name'] + ptime_employee_firstname = ptime_employee['attributes']['firstname'] + ptime_employee_lastname = ptime_employee['attributes']['lastname'] ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" matched_skills_people = Person.where(ptime_employee_id: nil) .where(name: ptime_employee_name) diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb new file mode 100644 index 000000000..e4ea17a42 --- /dev/null +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -0,0 +1,101 @@ +require 'rails_helper' + +ptime_base_test_url = "www.ptime.example.com" +ptime_api_test_username = "test username" +ptime_api_test_password = "test password" +ENV["PTIME_BASE_URL"] = ptime_base_test_url +ENV["PTIME_API_USERNAME"] = ptime_api_test_username +ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + +describe Ptime::AssignEmployeeIds do + employees_json = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'LSM', + 'firstname': 'Longmax', + 'lastname': 'Smith', + 'email': 'longmax@example.com', + 'single': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'BSc in Architecture', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 21, + 'type': 'employee', + 'attributes': { + 'shortname': 'AMA', + 'firstname': 'Alice', + 'lastname': 'Mante', + 'email': 'alice@example.com', + 'single': 'single', + 'nationalities': [ + 'AU' + ], + 'graduation': 'MSc in writing', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 45, + 'type': 'employee', + 'attributes': { + 'shortname': 'CFO', + 'firstname': 'Charlie', + 'lastname': 'Ford', + 'email': 'charlie@example.com', + 'single': 'married', + 'nationalities': [ + 'GB' + ], + 'graduation': 'MSc in networking', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + ] + }.to_json + + it 'should map people with the correct puzzletime id' do + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + person_longmax = people(:longmax) + person_alice = people(:alice) + person_charlie = people(:charlie) + + Ptime::AssignEmployeeIds.new.run + + expect(person_longmax.reload.ptime_employee_id).to eq(33) + expect(person_alice.reload.ptime_employee_id).to eq(21) + expect(person_charlie.reload.ptime_employee_id).to eq(45) + end + + it 'should not match people that are not found' do + parsed_employees_json = JSON.parse(employees_json) + parsed_employees_json['data'].first["attributes"]["firstname"] = "Rochus" + parsed_employees_json['data'].second["attributes"]["firstname"] = "Melchior" + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + person_longmax = people(:longmax) + person_alice = people(:alice) + person_charlie = people(:charlie) + + Ptime::AssignEmployeeIds.new.run + + expect(person_longmax.reload.ptime_employee_id).to be_nil + expect(person_alice.reload.ptime_employee_id).to be_nil + expect(person_charlie.reload.ptime_employee_id).to eq(45) + end +end \ No newline at end of file diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client.spec.rb index 88edf98cb..b44b33e99 100644 --- a/spec/domain/ptime/client.spec.rb +++ b/spec/domain/ptime/client.spec.rb @@ -66,7 +66,7 @@ it 'should be able to fetch employee data' do stub_request(:get, "#{ptime_base_test_url}/api/v1/employees"). - to_return(body: employees_json, headers: { 'pagination-total-count': 200, 'pagination-per-page': 20, 'pagination-current-page': 5, 'pagination-total-pages': 10, 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) fetched_employees = Ptime::Client.new.get("employees") From 933c2fc40162b65fd92ba7b9aa3522119211f991 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 26 Jun 2024 10:29:43 +0200 Subject: [PATCH 13/79] Add test for ambiguous matched people --- spec/domain/ptime/assign_emplyoee_ids.spec.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb index e4ea17a42..98b05a6bf 100644 --- a/spec/domain/ptime/assign_emplyoee_ids.spec.rb +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -98,4 +98,23 @@ expect(person_alice.reload.ptime_employee_id).to be_nil expect(person_charlie.reload.ptime_employee_id).to eq(45) end + + it 'should not match people that are ambiguous' do + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + person_longmax = people(:longmax) + person_alice = people(:alice) + person_charlie = people(:charlie) + + person_charlie.name = "Alice Mante" + person_charlie.save! + + Ptime::AssignEmployeeIds.new.run + + expect(person_longmax.reload.ptime_employee_id).to eq(33) + expect(person_alice.reload.ptime_employee_id).to be_nil + expect(person_charlie.reload.ptime_employee_id).to be_nil + end end \ No newline at end of file From ff37bcc7eb8dce1b8be66e02e1d1d9c0b2d6f794 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 26 Jun 2024 11:29:10 +0200 Subject: [PATCH 14/79] Add email to filter before matching as well --- app/domain/ptime/assign_employee_ids.rb | 2 ++ spec/domain/ptime/assign_emplyoee_ids.spec.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index e73727750..9f63aedb8 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -26,8 +26,10 @@ def run ptime_employee_firstname = ptime_employee['attributes']['firstname'] ptime_employee_lastname = ptime_employee['attributes']['lastname'] ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" + ptime_employee_email = ptime_employee['attributes']['email'] matched_skills_people = Person.where(ptime_employee_id: nil) .where(name: ptime_employee_name) + .where(email: ptime_employee_email) if matched_skills_people.empty? unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] } diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb index 98b05a6bf..d6b602e08 100644 --- a/spec/domain/ptime/assign_emplyoee_ids.spec.rb +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -109,6 +109,7 @@ person_charlie = people(:charlie) person_charlie.name = "Alice Mante" + person_charlie.email = "alice@example.com" person_charlie.save! Ptime::AssignEmployeeIds.new.run From 244369f3223035f4bd301ee32cb1f2304e7c49b1 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 26 Jun 2024 12:49:23 +0200 Subject: [PATCH 15/79] Possibly make rubocop happy --- app/domain/ptime/assign_employee_ids.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 9f63aedb8..757b2c240 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -5,6 +5,7 @@ module Ptime class AssignEmployeeIds # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/AbcSize + # rubocop:disable Rails/Output def run puts 'Fetching required data...' ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] @@ -54,6 +55,7 @@ def run end # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize + # rubocop:enable Rails/Output end end From 7e5808421a52a975153a844f8da4b262f2161e29 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 26 Jun 2024 12:59:22 +0200 Subject: [PATCH 16/79] Try to make rubocop happy again --- app/domain/ptime/assign_employee_ids.rb | 1 - app/domain/ptime/client.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 757b2c240..8746cac86 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -58,4 +58,3 @@ def run # rubocop:enable Rails/Output end end - diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index f7880f06a..77230f729 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -28,7 +28,7 @@ def request(method, path, params = nil) def response_error_message(exception) JSON.parse(exception.response.body).dig('error', 'message') - rescue # do not fail if response is not JSON + rescue JSON::ParserError # rescue only JSON parsing errors nil end From 132424a67ab9f4849cdabfc7898a0de8acc4c806 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 07:47:26 +0200 Subject: [PATCH 17/79] Add evaluate task for mapping script --- app/domain/ptime/assign_employee_ids.rb | 14 ++++++++++---- lib/tasks/ptime.rake | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 8746cac86..d253eb777 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -6,7 +6,10 @@ class AssignEmployeeIds # rubocop:disable Metrics/MethodLength # rubocop:disable Metrics/AbcSize # rubocop:disable Rails/Output - def run + # rubocop:disable Metrics/CyclomaticComplexity + def run(should_map: false) + puts 'Notice this is a dry run and mapping will not happen!' if should_map + puts '--------------------------' puts 'Fetching required data...' ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] skills_people = Person.all @@ -35,9 +38,11 @@ def run if matched_skills_people.empty? unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] } elsif matched_skills_people.count == 1 - matched_skills_person = matched_skills_people.first - matched_skills_person.ptime_employee_id = ptime_employee['id'] - matched_skills_person.save! + if should_map + matched_skills_person = matched_skills_people.first + matched_skills_person.ptime_employee_id = ptime_employee['id'] + matched_skills_person.save! + end mapped_people_count += 1 else ambiguous_entries << { name: ptime_employee_name, id: ptime_employee['id'] } @@ -56,5 +61,6 @@ def run # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize # rubocop:enable Rails/Output + # rubocop:enable Metrics/CyclomaticComplexity end end diff --git a/lib/tasks/ptime.rake b/lib/tasks/ptime.rake index 2fb7c883b..e16bc1aba 100644 --- a/lib/tasks/ptime.rake +++ b/lib/tasks/ptime.rake @@ -1,6 +1,10 @@ namespace :ptime do desc 'assign puzzletime employee ids to people' task :assign => :environment do + Ptime::AssignEmployeeIds.new.run(should_map: true) + end + + task :evaluate_assign => :environment do Ptime::AssignEmployeeIds.new.run end end \ No newline at end of file From 2070ffbc9493a637e528ee2d8fcb2d67098543bb Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 08:17:00 +0200 Subject: [PATCH 18/79] Outsource mapper script code to methods and fix tests --- app/domain/ptime/assign_employee_ids.rb | 38 ++++++++++++------- lib/tasks/ptime.rake | 1 + spec/domain/ptime/assign_emplyoee_ids.spec.rb | 6 +-- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index d253eb777..f8744eb08 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -3,30 +3,32 @@ # This script will assign each person the corresponding employee ID from PuzzleTime module Ptime class AssignEmployeeIds - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/AbcSize + # rubocop:disable Rails/Output - # rubocop:disable Metrics/CyclomaticComplexity def run(should_map: false) - puts 'Notice this is a dry run and mapping will not happen!' if should_map - puts '--------------------------' - puts 'Fetching required data...' - ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] - skills_people = Person.all - puts 'Successfully fetched data' + puts 'Notice this is a dry run and mapping will not happen!' unless should_map + fetch_data puts "Currently there are: - - #{ptime_employees.length} employees in PuzzleTime - - #{skills_people.count} people in PuzzleSkills - This is a difference of #{(skills_people.count - ptime_employees.length).abs} entries" + - #{@ptime_employees.length} employees in PuzzleTime + - #{@skills_people.count} people in PuzzleSkills + This is a difference of #{(@skills_people.count - @ptime_employees.length).abs} entries" + map_employees(should_map) + end + private + + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/CyclomaticComplexity + def map_employees(should_map) puts 'Assigning employee IDs now...' ambiguous_entries = [] unmatched_entries = [] mapped_people_count = 0 - ptime_employees.each do |ptime_employee| + @ptime_employees.each do |ptime_employee| ptime_employee_firstname = ptime_employee['attributes']['firstname'] ptime_employee_lastname = ptime_employee['attributes']['lastname'] ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" @@ -60,7 +62,15 @@ def run(should_map: false) end # rubocop:enable Metrics/MethodLength # rubocop:enable Metrics/AbcSize - # rubocop:enable Rails/Output # rubocop:enable Metrics/CyclomaticComplexity + + def fetch_data + puts 'Fetching required data...' + @ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + @skills_people = Person.all + puts 'Successfully fetched data' + end + # rubocop:enable Rails/Output end end + diff --git a/lib/tasks/ptime.rake b/lib/tasks/ptime.rake index e16bc1aba..b43cefc71 100644 --- a/lib/tasks/ptime.rake +++ b/lib/tasks/ptime.rake @@ -4,6 +4,7 @@ namespace :ptime do Ptime::AssignEmployeeIds.new.run(should_map: true) end + desc 'evaluate assignment of employee ids to people' task :evaluate_assign => :environment do Ptime::AssignEmployeeIds.new.run end diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb index d6b602e08..60996b5de 100644 --- a/spec/domain/ptime/assign_emplyoee_ids.spec.rb +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -73,7 +73,7 @@ person_alice = people(:alice) person_charlie = people(:charlie) - Ptime::AssignEmployeeIds.new.run + Ptime::AssignEmployeeIds.new.run(should_map: true) expect(person_longmax.reload.ptime_employee_id).to eq(33) expect(person_alice.reload.ptime_employee_id).to eq(21) @@ -92,7 +92,7 @@ person_alice = people(:alice) person_charlie = people(:charlie) - Ptime::AssignEmployeeIds.new.run + Ptime::AssignEmployeeIds.new.run(should_map: true) expect(person_longmax.reload.ptime_employee_id).to be_nil expect(person_alice.reload.ptime_employee_id).to be_nil @@ -112,7 +112,7 @@ person_charlie.email = "alice@example.com" person_charlie.save! - Ptime::AssignEmployeeIds.new.run + Ptime::AssignEmployeeIds.new.run(should_map: true) expect(person_longmax.reload.ptime_employee_id).to eq(33) expect(person_alice.reload.ptime_employee_id).to be_nil From b89c9336f81e656fe81c5b00ae2cbdcb4cbae78d Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 08:22:14 +0200 Subject: [PATCH 19/79] Add test for dry run --- spec/domain/ptime/assign_emplyoee_ids.spec.rb | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb index 60996b5de..f1fe5a5a5 100644 --- a/spec/domain/ptime/assign_emplyoee_ids.spec.rb +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -80,7 +80,7 @@ expect(person_charlie.reload.ptime_employee_id).to eq(45) end - it 'should not match people that are not found' do + it 'should not map people that are not found' do parsed_employees_json = JSON.parse(employees_json) parsed_employees_json['data'].first["attributes"]["firstname"] = "Rochus" parsed_employees_json['data'].second["attributes"]["firstname"] = "Melchior" @@ -99,7 +99,7 @@ expect(person_charlie.reload.ptime_employee_id).to eq(45) end - it 'should not match people that are ambiguous' do + it 'should not map people that are ambiguous' do stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) @@ -118,4 +118,21 @@ expect(person_alice.reload.ptime_employee_id).to be_nil expect(person_charlie.reload.ptime_employee_id).to be_nil end + + it 'should not map people on dry run' do + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + person_longmax = people(:longmax) + person_alice = people(:alice) + person_charlie = people(:charlie) + + Ptime::AssignEmployeeIds.new.run + + expect(person_longmax.reload.ptime_employee_id).to be_nil + expect(person_alice.reload.ptime_employee_id).to be_nil + expect(person_charlie.reload.ptime_employee_id).to be_nil + end + end \ No newline at end of file From b44a2d029472a4690733f755be1dd7115f6ce0ca Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 09:26:21 +0200 Subject: [PATCH 20/79] Make rubocop happy :) --- app/domain/ptime/assign_employee_ids.rb | 1 - spec/domain/ptime/assign_emplyoee_ids.spec.rb | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index f8744eb08..ffc9ded0c 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -73,4 +73,3 @@ def fetch_data # rubocop:enable Rails/Output end end - diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids.spec.rb index f1fe5a5a5..37aa82f6f 100644 --- a/spec/domain/ptime/assign_emplyoee_ids.spec.rb +++ b/spec/domain/ptime/assign_emplyoee_ids.spec.rb @@ -134,5 +134,4 @@ expect(person_alice.reload.ptime_employee_id).to be_nil expect(person_charlie.reload.ptime_employee_id).to be_nil end - -end \ No newline at end of file +end From f9be66c1c8e93da16ecad89178d6501ba54fab34 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 09:41:41 +0200 Subject: [PATCH 21/79] Remove unnecessary requires --- app/domain/ptime/assign_employee_ids.rb | 2 -- app/domain/ptime/client.rb | 1 - 2 files changed, 3 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index ffc9ded0c..57f89cdda 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -1,5 +1,3 @@ -require_relative '../../../config/environment' - # This script will assign each person the corresponding employee ID from PuzzleTime module Ptime class AssignEmployeeIds diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 77230f729..def0d8c5c 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -2,7 +2,6 @@ require 'rest_client' require 'base64' -require_relative '../../../config/environment' module Ptime class Client From 104185e6ff0c4134a7bad78a6dd1430e36744303 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 11:00:41 +0200 Subject: [PATCH 22/79] Replace .count == 1 with .one? --- app/domain/ptime/assign_employee_ids.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 57f89cdda..1485961b0 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -37,7 +37,7 @@ def map_employees(should_map) if matched_skills_people.empty? unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] } - elsif matched_skills_people.count == 1 + elsif matched_skills_people.one? if should_map matched_skills_person = matched_skills_people.first matched_skills_person.ptime_employee_id = ptime_employee['id'] From aa4c5f513f7f7ed2ed72ece1f0ee25e1893b4d30 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Thu, 27 Jun 2024 11:34:34 +0200 Subject: [PATCH 23/79] Start writing script that updates the data of the people in skills --- app/domain/ptime/update_people_data.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/domain/ptime/update_people_data.rb diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb new file mode 100644 index 000000000..922b697b3 --- /dev/null +++ b/app/domain/ptime/update_people_data.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class UpdatePeopleData + module Ptime + ATTRIBUTES = [] + def run + ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + person_ptime_ids = Person.pluck(:ptime_employee_id) + ptime_employees.each do |ptime_employee| + if ptime_employee['id'].in?(person_ptime_ids) + person = Person.where(ptime_employee_id: ptime_employee['id']) + end + end + end + end +end From 7d775c338928b9843d8849c29527dfd4efeedce3 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 08:50:39 +0200 Subject: [PATCH 24/79] Write script that maps the data from a ptime employee to the corresponding skills person --- app/domain/ptime/update_people_data.rb | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 922b697b3..a744f47cd 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -2,14 +2,23 @@ class UpdatePeopleData module Ptime - ATTRIBUTES = [] + ATTRIBUTE_MAPPING = { shortname: :shortname, email: :email, marital_status: :marital_status, + graduation: :title }.freeze def run ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] - person_ptime_ids = Person.pluck(:ptime_employee_id) ptime_employees.each do |ptime_employee| - if ptime_employee['id'].in?(person_ptime_ids) - person = Person.where(ptime_employee_id: ptime_employee['id']) + ptime_employee_firstname = ptime_employee['attributes']['firstname'] + ptime_employee_lastname = ptime_employee['attributes']['lastname'] + ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" + + skills_person = Person.find_by(ptime_employee_id: ptime_employee['id']) + skills_person ||= Person.new + + skills_person[:name] = ptime_employee_name + ptime_employee['attributes'].each do |key, value| + skills_person[ATTRIBUTE_MAPPING[key]] = value end + skills_person.save! end end end From 82d03f0b79ddb1c2de204553466c05a72a3abe4c Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 08:55:05 +0200 Subject: [PATCH 25/79] Disable rubocop metrics all together instead of one by one in assign employee id and update people data scripts --- app/domain/ptime/assign_employee_ids.rb | 8 ++------ app/domain/ptime/update_people_data.rb | 3 +++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 1485961b0..f7a40d1af 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -16,9 +16,7 @@ def run(should_map: false) private - # rubocop:disable Metrics/MethodLength - # rubocop:disable Metrics/AbcSize - # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics def map_employees(should_map) puts 'Assigning employee IDs now...' @@ -58,9 +56,7 @@ def map_employees(should_map) puts "#{ambiguous_entries.size} people ambiguous matched" ambiguous_entries.each { |entry| puts "- #{entry[:name]} with id #{entry[:id]}" } end - # rubocop:enable Metrics/MethodLength - # rubocop:enable Metrics/AbcSize - # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics def fetch_data puts 'Fetching required data...' diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index a744f47cd..9a4d0ddc2 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -4,6 +4,8 @@ class UpdatePeopleData module Ptime ATTRIBUTE_MAPPING = { shortname: :shortname, email: :email, marital_status: :marital_status, graduation: :title }.freeze + + # rubocop:disable Metrics def run ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] ptime_employees.each do |ptime_employee| @@ -21,5 +23,6 @@ def run skills_person.save! end end + # rubocop:enable Metrics end end From 96913d2b6686002ee18840194f902e08fd340378 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 08:59:58 +0200 Subject: [PATCH 26/79] Fix file naming of spec files --- .../{assign_emplyoee_ids.spec.rb => assign_emplyoee_ids_spec.rb} | 0 spec/domain/ptime/{client.spec.rb => client_spec.rb} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename spec/domain/ptime/{assign_emplyoee_ids.spec.rb => assign_emplyoee_ids_spec.rb} (100%) rename spec/domain/ptime/{client.spec.rb => client_spec.rb} (100%) diff --git a/spec/domain/ptime/assign_emplyoee_ids.spec.rb b/spec/domain/ptime/assign_emplyoee_ids_spec.rb similarity index 100% rename from spec/domain/ptime/assign_emplyoee_ids.spec.rb rename to spec/domain/ptime/assign_emplyoee_ids_spec.rb diff --git a/spec/domain/ptime/client.spec.rb b/spec/domain/ptime/client_spec.rb similarity index 100% rename from spec/domain/ptime/client.spec.rb rename to spec/domain/ptime/client_spec.rb From 907da9038b97ce717b6b7d7acfc3e2f72805048f Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 09:44:03 +0200 Subject: [PATCH 27/79] Move class into module and fix mapping of person to employee data, write specs to test mapping of people data --- app/domain/ptime/update_people_data.rb | 6 +- spec/domain/ptime/update_people_data_spec.rb | 97 ++++++++++++++++++++ 2 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 spec/domain/ptime/update_people_data_spec.rb diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 9a4d0ddc2..4d1bb44bb 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -class UpdatePeopleData - module Ptime +module Ptime + class UpdatePeopleData ATTRIBUTE_MAPPING = { shortname: :shortname, email: :email, marital_status: :marital_status, graduation: :title }.freeze @@ -18,7 +18,7 @@ def run skills_person[:name] = ptime_employee_name ptime_employee['attributes'].each do |key, value| - skills_person[ATTRIBUTE_MAPPING[key]] = value + skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value if key.to_sym.in?(ATTRIBUTE_MAPPING.keys) end skills_person.save! end diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb new file mode 100644 index 000000000..be3c3ef48 --- /dev/null +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -0,0 +1,97 @@ +require 'rails_helper' + +ptime_base_test_url = "www.ptime.example.com" +ptime_api_test_username = "test username" +ptime_api_test_password = "test password" +ENV["PTIME_BASE_URL"] = ptime_base_test_url +ENV["PTIME_API_USERNAME"] = ptime_api_test_username +ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + +describe Ptime::UpdatePeopleData do + employees_json = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'LSM', + 'firstname': 'Longmax', + 'lastname': 'Smith', + 'email': 'longmax@example.com', + 'single': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'BSc in Architecture', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 21, + 'type': 'employee', + 'attributes': { + 'shortname': 'AMA', + 'firstname': 'Alice', + 'lastname': 'Mante', + 'email': 'alice@example.com', + 'single': 'single', + 'nationalities': [ + 'AU' + ], + 'graduation': 'MSc in writing', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 45, + 'type': 'employee', + 'attributes': { + 'shortname': 'CFO', + 'firstname': 'Charlie', + 'lastname': 'Ford', + 'email': 'charlie@example.com', + 'single': 'married', + 'nationalities': [ + 'GB' + ], + 'graduation': 'MSc in networking', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + ] + }.to_json + + it 'should update the data of existing people after mapping' do + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + person_longmax = people(:longmax) + person_alice = people(:alice) + person_charlie = people(:charlie) + + Ptime::AssignEmployeeIds.new.run(should_map: true) + + person_longmax.reload + person_alice.reload + person_charlie.reload + + parsed_employees_json = JSON.parse(employees_json) + parsed_employees_json['data'].first["attributes"]["email"] = "changedmax@example.com" + parsed_employees_json['data'].second["attributes"]["graduation"] = "MSc in some other field" + parsed_employees_json['data'].last["attributes"]["firstname"] = "Claudius" + + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + Ptime::UpdatePeopleData.new.run + + expect(person_longmax.reload.email).to eq("changedmax@example.com") + expect(person_alice.reload.title).to eq("MSc in some other field") + expect(person_charlie.reload.name).to eq("Claudius Ford") + end +end \ No newline at end of file From 35f4b0dd8bec64f3480b3cc2662f2ec96b4ac218 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 11:01:58 +0200 Subject: [PATCH 28/79] Fix updating of people data and test it and fix faulty key in json used for testing requests --- app/domain/ptime/update_people_data.rb | 11 +++- ...ds_spec.rb => assign_employee_ids_spec.rb} | 6 +- spec/domain/ptime/client_spec.rb | 6 +- spec/domain/ptime/update_people_data_spec.rb | 59 ++++++++++++++++--- 4 files changed, 67 insertions(+), 15 deletions(-) rename spec/domain/ptime/{assign_emplyoee_ids_spec.rb => assign_employee_ids_spec.rb} (97%) diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 4d1bb44bb..9238cb034 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -16,10 +16,17 @@ def run skills_person = Person.find_by(ptime_employee_id: ptime_employee['id']) skills_person ||= Person.new - skills_person[:name] = ptime_employee_name + skills_person.name = ptime_employee_name + skills_person.ptime_employee_id = ptime_employee['id'] ptime_employee['attributes'].each do |key, value| - skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value if key.to_sym.in?(ATTRIBUTE_MAPPING.keys) + if key.to_sym.in?(ATTRIBUTE_MAPPING.keys) + skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value + end end + skills_person.company = Company.first + skills_person.birthdate = '1.1.2000' + skills_person.location = 'Bern' + skills_person.nationality = 'CH' skills_person.save! end end diff --git a/spec/domain/ptime/assign_emplyoee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb similarity index 97% rename from spec/domain/ptime/assign_emplyoee_ids_spec.rb rename to spec/domain/ptime/assign_employee_ids_spec.rb index 37aa82f6f..1e7e7a462 100644 --- a/spec/domain/ptime/assign_emplyoee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -18,7 +18,7 @@ 'firstname': 'Longmax', 'lastname': 'Smith', 'email': 'longmax@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'ZW' ], @@ -35,7 +35,7 @@ 'firstname': 'Alice', 'lastname': 'Mante', 'email': 'alice@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'AU' ], @@ -52,7 +52,7 @@ 'firstname': 'Charlie', 'lastname': 'Ford', 'email': 'charlie@example.com', - 'single': 'married', + 'marital_status': 'married', 'nationalities': [ 'GB' ], diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index b44b33e99..bdcc6b9c7 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -18,7 +18,7 @@ 'firstname': 'Longmax', 'lastname': 'Smith', 'email': 'longmax@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'ZW' ], @@ -35,7 +35,7 @@ 'firstname': 'Alice', 'lastname': 'Mante', 'email': 'alice@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'AU' ], @@ -52,7 +52,7 @@ 'firstname': 'Charlie', 'lastname': 'Ford', 'email': 'charlie@example.com', - 'single': 'married', + 'marital_status': 'married', 'nationalities': [ 'GB' ], diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index be3c3ef48..a87cefbc8 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -18,7 +18,7 @@ 'firstname': 'Longmax', 'lastname': 'Smith', 'email': 'longmax@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'ZW' ], @@ -35,7 +35,7 @@ 'firstname': 'Alice', 'lastname': 'Mante', 'email': 'alice@example.com', - 'single': 'single', + 'marital_status': 'single', 'nationalities': [ 'AU' ], @@ -52,7 +52,7 @@ 'firstname': 'Charlie', 'lastname': 'Ford', 'email': 'charlie@example.com', - 'single': 'married', + 'marital_status': 'married', 'nationalities': [ 'GB' ], @@ -75,10 +75,6 @@ Ptime::AssignEmployeeIds.new.run(should_map: true) - person_longmax.reload - person_alice.reload - person_charlie.reload - parsed_employees_json = JSON.parse(employees_json) parsed_employees_json['data'].first["attributes"]["email"] = "changedmax@example.com" parsed_employees_json['data'].second["attributes"]["graduation"] = "MSc in some other field" @@ -94,4 +90,53 @@ expect(person_alice.reload.title).to eq("MSc in some other field") expect(person_charlie.reload.name).to eq("Claudius Ford") end + + it 'should create new person when person does not exist' do + ATTRIBUTE_MAPPING = { shortname: :shortname, email: :email, marital_status: :marital_status, + graduation: :title }.freeze + + new_employee = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'PFI', + 'firstname': 'Peterson', + 'lastname': 'Findus', + 'email': 'peterson@example.com', + 'marital_status': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'Cat caretaker', + 'department_shortname': 'CAT', + 'employment_roles': [] + } + } + ] + } + + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: new_employee.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + Ptime::AssignEmployeeIds.new.run(should_map: true) + Ptime::UpdatePeopleData.new.run + + new_employee_attributes = new_employee[:data].first[:attributes] + new_employee_name = "#{new_employee_attributes[:firstname]} #{new_employee_attributes[:lastname]}" + created_person = Person.find_by(name: new_employee_name) + expect(created_person).not_to be_nil + expect(created_person.ptime_employee_id).to eq(new_employee[:data].first[:id]) + expect(created_person.shortname).to eq(new_employee_attributes[:shortname]) + expect(created_person.name).to eq(new_employee_name) + expect(created_person.email).to eq(new_employee_attributes[:email]) + expect(created_person.marital_status).to eq(new_employee_attributes[:marital_status]) + expect(created_person.title).to eq(new_employee_attributes[:graduation]) + expect(created_person.company).to eq(Company.first) + expect(created_person.birthdate).to eq('1.1.2000') + expect(created_person.location).to eq('Bern') + expect(created_person.nationality).to eq('CH') + end end \ No newline at end of file From 1190569532bbb9458f89f4ff0bd8b24135cb9528 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 11:30:31 +0200 Subject: [PATCH 29/79] Fix update people data specs by assigning the ptime base url env var in before each --- spec/domain/ptime/update_people_data_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index a87cefbc8..7ddb8904f 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -3,7 +3,6 @@ ptime_base_test_url = "www.ptime.example.com" ptime_api_test_username = "test username" ptime_api_test_password = "test password" -ENV["PTIME_BASE_URL"] = ptime_base_test_url ENV["PTIME_API_USERNAME"] = ptime_api_test_username ENV["PTIME_API_PASSWORD"] = ptime_api_test_password @@ -64,6 +63,10 @@ ] }.to_json + before(:each) do + ENV["PTIME_BASE_URL"] = ptime_base_test_url + end + it 'should update the data of existing people after mapping' do stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) @@ -92,9 +95,6 @@ end it 'should create new person when person does not exist' do - ATTRIBUTE_MAPPING = { shortname: :shortname, email: :email, marital_status: :marital_status, - graduation: :title }.freeze - new_employee = { 'data': [ { From 5ac5585bf50f4ecbafbdba9d52c8c1c327b0e394 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 11:35:27 +0200 Subject: [PATCH 30/79] Only update ptime employee id if its not already set --- app/domain/ptime/update_people_data.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 9238cb034..db885ea87 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -17,7 +17,7 @@ def run skills_person ||= Person.new skills_person.name = ptime_employee_name - skills_person.ptime_employee_id = ptime_employee['id'] + skills_person.ptime_employee_id ||= ptime_employee['id'] ptime_employee['attributes'].each do |key, value| if key.to_sym.in?(ATTRIBUTE_MAPPING.keys) skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value From 8c8e0e4a274e252475b6f94413e55c3048ec9f20 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 12:03:16 +0200 Subject: [PATCH 31/79] Test if marital status can be changed in specs --- spec/domain/ptime/update_people_data_spec.rb | 143 +++++++++++-------- 1 file changed, 81 insertions(+), 62 deletions(-) diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index 7ddb8904f..45d6fd365 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -7,84 +7,102 @@ ENV["PTIME_API_PASSWORD"] = ptime_api_test_password describe Ptime::UpdatePeopleData do - employees_json = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'LSM', - 'firstname': 'Longmax', - 'lastname': 'Smith', - 'email': 'longmax@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'BSc in Architecture', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 21, - 'type': 'employee', - 'attributes': { - 'shortname': 'AMA', - 'firstname': 'Alice', - 'lastname': 'Mante', - 'email': 'alice@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'AU' - ], - 'graduation': 'MSc in writing', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 45, - 'type': 'employee', - 'attributes': { - 'shortname': 'CFO', - 'firstname': 'Charlie', - 'lastname': 'Ford', - 'email': 'charlie@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'GB' - ], - 'graduation': 'MSc in networking', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - ] - }.to_json - before(:each) do ENV["PTIME_BASE_URL"] = ptime_base_test_url end it 'should update the data of existing people after mapping' do + employees = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'LSM', + 'firstname': 'Longmax', + 'lastname': 'Smith', + 'email': 'longmax@example.com', + 'marital_status': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'BSc in Architecture', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 21, + 'type': 'employee', + 'attributes': { + 'shortname': 'AMA', + 'firstname': 'Alice', + 'lastname': 'Mante', + 'email': 'alice@example.com', + 'marital_status': 'single', + 'nationalities': [ + 'AU' + ], + 'graduation': 'MSc in writing', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 45, + 'type': 'employee', + 'attributes': { + 'shortname': 'CFO', + 'firstname': 'Charlie', + 'lastname': 'Ford', + 'email': 'charlie@example.com', + 'marital_status': 'married', + 'nationalities': [ + 'GB' + ], + 'graduation': 'MSc in networking', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 50, + 'type': 'employee', + 'attributes': { + 'shortname': 'WAL', + 'firstname': 'Wally', + 'lastname': 'Allround', + 'email': 'wally@example.com', + 'marital_status': 'married', + 'nationalities': [ + 'US' + ], + 'graduation': 'Full-Stack Developer', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + ] + } + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) person_longmax = people(:longmax) person_alice = people(:alice) person_charlie = people(:charlie) + person_wally = people(:wally) Ptime::AssignEmployeeIds.new.run(should_map: true) - parsed_employees_json = JSON.parse(employees_json) - parsed_employees_json['data'].first["attributes"]["email"] = "changedmax@example.com" - parsed_employees_json['data'].second["attributes"]["graduation"] = "MSc in some other field" - parsed_employees_json['data'].last["attributes"]["firstname"] = "Claudius" + employees[:data].first[:attributes][:email] = "changedmax@example.com" + employees[:data].second[:attributes][:graduation] = "MSc in some other field" + employees[:data].third[:attributes][:firstname] = "Claudius" + employees[:data].fourth[:attributes][:marital_status] = "single" stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) Ptime::UpdatePeopleData.new.run @@ -92,6 +110,7 @@ expect(person_longmax.reload.email).to eq("changedmax@example.com") expect(person_alice.reload.title).to eq("MSc in some other field") expect(person_charlie.reload.name).to eq("Claudius Ford") + expect(person_wally.reload.marital_status).to eq("single") end it 'should create new person when person does not exist' do From dd0bacdb09b1903b1e91d3b2ce7b4dd994156e5e Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 13:46:20 +0200 Subject: [PATCH 32/79] Write rake task that runs the people update --- lib/tasks/ptime.rake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/tasks/ptime.rake b/lib/tasks/ptime.rake index b43cefc71..71ef62194 100644 --- a/lib/tasks/ptime.rake +++ b/lib/tasks/ptime.rake @@ -8,4 +8,9 @@ namespace :ptime do task :evaluate_assign => :environment do Ptime::AssignEmployeeIds.new.run end + + desc 'update person data with the data from ptime' + task :update_people => :environment do + Ptime::UpdatePeopleData.new.run + end end \ No newline at end of file From b2d5d0b9eb2b55ee3cb0b363f513bb850b92aec3 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Fri, 28 Jun 2024 14:42:02 +0200 Subject: [PATCH 33/79] Show message in assign employee ids script conditionally --- app/domain/ptime/assign_employee_ids.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index f7a40d1af..ea4416952 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -18,7 +18,7 @@ def run(should_map: false) # rubocop:disable Metrics def map_employees(should_map) - puts 'Assigning employee IDs now...' + puts 'Assigning employee IDs now...' if should_map ambiguous_entries = [] unmatched_entries = [] From dbe7132680cf1349d50756f78a4d9f53db35cecd Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 1 Jul 2024 15:54:48 +0200 Subject: [PATCH 34/79] Add delayed jobs and daemon gems and start writing delayed jobs --- Gemfile | 2 ++ Gemfile.lock | 8 +++++++ app/domain/ptime/update_people_data.rb | 3 +++ bin/delayed_job | 5 +++++ config/application.rb | 2 ++ .../20240701085558_create_delayed_jobs.rb | 22 +++++++++++++++++++ db/schema.rb | 17 +++++++++++++- 7 files changed, 58 insertions(+), 1 deletion(-) create mode 100755 bin/delayed_job create mode 100644 db/migrate/20240701085558_create_delayed_jobs.rb diff --git a/Gemfile b/Gemfile index ca6809334..4e6f858eb 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,9 @@ gem 'carrierwave' gem 'config' gem 'countries' gem 'cssbundling-rails' +gem 'daemons' gem 'database_cleaner' +gem 'delayed_job_active_record' gem 'devise' gem 'faker' gem 'haml-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 53b350008..22c5b1e14 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -125,6 +125,7 @@ GEM crass (1.0.6) cssbundling-rails (1.4.0) railties (>= 6.0.0) + daemons (1.4.1) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.1.0) @@ -133,6 +134,11 @@ GEM database_cleaner-core (2.0.1) date (3.3.4) deep_merge (1.2.2) + delayed_job (4.1.11) + activesupport (>= 3.0, < 8.0) + delayed_job_active_record (4.1.8) + activerecord (>= 3.0, < 8.0) + delayed_job (>= 3.0, < 5) devise (4.9.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -478,7 +484,9 @@ DEPENDENCIES config countries cssbundling-rails + daemons database_cleaner + delayed_job_active_record devise dotenv faker diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index db885ea87..ceeeef9de 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -28,8 +28,11 @@ def run skills_person.location = 'Bern' skills_person.nationality = 'CH' skills_person.save! + + # Ptime::UpdatePeopleData.run end end # rubocop:enable Metrics + # handle_asynchronously :run, :run_at => Proc.new { 15.minutes.from_now } end end diff --git a/bin/delayed_job b/bin/delayed_job new file mode 100755 index 000000000..edf195985 --- /dev/null +++ b/bin/delayed_job @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) +require 'delayed/command' +Delayed::Command.new(ARGV).daemonize diff --git a/config/application.rb b/config/application.rb index dee2a1781..0a6ebec84 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,5 +37,7 @@ class Application < Rails::Application config.assets.enabled = true config.assets.paths << Rails.root.join("uploads") + + config.active_job.queue_adapter = :delayed_job end end diff --git a/db/migrate/20240701085558_create_delayed_jobs.rb b/db/migrate/20240701085558_create_delayed_jobs.rb new file mode 100644 index 000000000..c3ce5afc9 --- /dev/null +++ b/db/migrate/20240701085558_create_delayed_jobs.rb @@ -0,0 +1,22 @@ +class CreateDelayedJobs < ActiveRecord::Migration[7.0] + def self.up + create_table :delayed_jobs do |table| + table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue + table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. + table.text :handler, null: false # YAML-encoded string of the object that will do work + table.text :last_error # reason for last failure (See Note below) + table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. + table.datetime :locked_at # Set when a client is working on this object + table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) + table.string :locked_by # Who is working on this object (if locked) + table.string :queue # The name of the queue this job is in + table.timestamps null: true + end + + add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" + end + + def self.down + drop_table :delayed_jobs + end +end diff --git a/db/schema.rb b/db/schema.rb index 038f495fa..cfb6306f6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_06_24_122411) do +ActiveRecord::Schema[7.0].define(version: 2024_07_01_085558) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -77,6 +77,21 @@ t.datetime "updated_at", precision: nil, null: false end + create_table "delayed_jobs", force: :cascade do |t| + t.integer "priority", default: 0, null: false + t.integer "attempts", default: 0, null: false + t.text "handler", null: false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + t.index ["priority", "run_at"], name: "delayed_jobs_priority" + end + create_table "departments", force: :cascade do |t| t.string "name", null: false t.datetime "created_at", null: false From 6fb4df1529524008c95dcf7036ebb29bcc8a0fb7 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 2 Jul 2024 10:48:51 +0200 Subject: [PATCH 35/79] Fix specs to work with delayed job --- app/domain/ptime/update_people_data.rb | 4 ++-- spec/domain/ptime/update_people_data_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index ceeeef9de..23dc8e34f 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -29,10 +29,10 @@ def run skills_person.nationality = 'CH' skills_person.save! - # Ptime::UpdatePeopleData.run + Ptime::UpdatePeopleData.run end end # rubocop:enable Metrics - # handle_asynchronously :run, :run_at => Proc.new { 15.minutes.from_now } + handle_asynchronously :run, :run_at => proc { 15.minutes.from_now } end end diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index 45d6fd365..2c45a05f5 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -105,7 +105,7 @@ to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - Ptime::UpdatePeopleData.new.run + Ptime::UpdatePeopleData.new.run_without_delay expect(person_longmax.reload.email).to eq("changedmax@example.com") expect(person_alice.reload.title).to eq("MSc in some other field") @@ -141,7 +141,7 @@ .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) Ptime::AssignEmployeeIds.new.run(should_map: true) - Ptime::UpdatePeopleData.new.run + Ptime::UpdatePeopleData.new.run_without_delay new_employee_attributes = new_employee[:data].first[:attributes] new_employee_name = "#{new_employee_attributes[:firstname]} #{new_employee_attributes[:lastname]}" From 480e32883024031d828fa0e07c4888b610527c24 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Wed, 3 Jul 2024 10:54:23 +0200 Subject: [PATCH 36/79] Remove delayed job functionality --- Gemfile | 2 -- app/domain/ptime/update_people_data.rb | 3 --- spec/domain/ptime/update_people_data_spec.rb | 4 ++-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 4e6f858eb..ca6809334 100644 --- a/Gemfile +++ b/Gemfile @@ -13,9 +13,7 @@ gem 'carrierwave' gem 'config' gem 'countries' gem 'cssbundling-rails' -gem 'daemons' gem 'database_cleaner' -gem 'delayed_job_active_record' gem 'devise' gem 'faker' gem 'haml-rails' diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 23dc8e34f..db885ea87 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -28,11 +28,8 @@ def run skills_person.location = 'Bern' skills_person.nationality = 'CH' skills_person.save! - - Ptime::UpdatePeopleData.run end end # rubocop:enable Metrics - handle_asynchronously :run, :run_at => proc { 15.minutes.from_now } end end diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index 2c45a05f5..45d6fd365 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -105,7 +105,7 @@ to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - Ptime::UpdatePeopleData.new.run_without_delay + Ptime::UpdatePeopleData.new.run expect(person_longmax.reload.email).to eq("changedmax@example.com") expect(person_alice.reload.title).to eq("MSc in some other field") @@ -141,7 +141,7 @@ .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) Ptime::AssignEmployeeIds.new.run(should_map: true) - Ptime::UpdatePeopleData.new.run_without_delay + Ptime::UpdatePeopleData.new.run new_employee_attributes = new_employee[:data].first[:attributes] new_employee_name = "#{new_employee_attributes[:firstname]} #{new_employee_attributes[:lastname]}" From 138fab798df2776e2c61347357aa9dc85348d1bd Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 4 Jul 2024 11:55:11 +0200 Subject: [PATCH 37/79] Add first approach for fetching people from ptime API --- Gemfile.lock | 8 -------- app/helpers/person_helper.rb | 20 ++++++++++++++++++++ app/views/people/_search.html.haml | 2 +- bin/delayed_job | 5 ----- config/application.rb | 2 -- 5 files changed, 21 insertions(+), 16 deletions(-) delete mode 100755 bin/delayed_job diff --git a/Gemfile.lock b/Gemfile.lock index 22c5b1e14..53b350008 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -125,7 +125,6 @@ GEM crass (1.0.6) cssbundling-rails (1.4.0) railties (>= 6.0.0) - daemons (1.4.1) database_cleaner (2.0.2) database_cleaner-active_record (>= 2, < 3) database_cleaner-active_record (2.1.0) @@ -134,11 +133,6 @@ GEM database_cleaner-core (2.0.1) date (3.3.4) deep_merge (1.2.2) - delayed_job (4.1.11) - activesupport (>= 3.0, < 8.0) - delayed_job_active_record (4.1.8) - activerecord (>= 3.0, < 8.0) - delayed_job (>= 3.0, < 5) devise (4.9.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -484,9 +478,7 @@ DEPENDENCIES config countries cssbundling-rails - daemons database_cleaner - delayed_job_active_record devise dotenv faker diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 6d2bcd6b3..a75fe1e5e 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -76,4 +76,24 @@ def not_rated_default_skills(person) certificate: false, core_competence: false }) end end + + def fetch_ptime_employees + ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + ptime_employee_id_map = Person.take(3).map do |p| + { p.ptime_employee_id.to_s => p.id } + end.reduce({}, :merge) + ptime_employees_dropdown_data = [] + ptime_employees.each do |ptime_employee| + ptime_employee_name = append_ptime_employee_name(ptime_employee) + person_id = ptime_employee_id_map[ptime_employee['id']] + ptime_employees_dropdown_data << [person_id, ptime_employee_name] + end + ptime_employees_dropdown_data + end + + def append_ptime_employee_name(ptime_employee) + ptime_employee_firstname = ptime_employee['attributes']['firstname'] + ptime_employee_lastname = ptime_employee['attributes']['lastname'] + "#{ptime_employee_firstname} #{ptime_employee_lastname}" + end end diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index be4edee70..d25fb849b 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,7 +1,7 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - = collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, {}, {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} diff --git a/bin/delayed_job b/bin/delayed_job deleted file mode 100755 index edf195985..000000000 --- a/bin/delayed_job +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env ruby - -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) -require 'delayed/command' -Delayed::Command.new(ARGV).daemonize diff --git a/config/application.rb b/config/application.rb index 0a6ebec84..dee2a1781 100644 --- a/config/application.rb +++ b/config/application.rb @@ -37,7 +37,5 @@ class Application < Rails::Application config.assets.enabled = true config.assets.paths << Rails.root.join("uploads") - - config.active_job.queue_adapter = :delayed_job end end From 7f6abdd1511ca6548767b76379e827bbe02eef42 Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 4 Jul 2024 15:49:46 +0200 Subject: [PATCH 38/79] Add helper and write test for fetching employee data --- spec/features/people_spec.rb | 78 +++++++++++++++++++++++++++++++++++ spec/support/ptime_helpers.rb | 0 2 files changed, 78 insertions(+) create mode 100644 spec/support/ptime_helpers.rb diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 32942bfbc..c9bfc3f2e 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -2,6 +2,61 @@ describe :people do describe 'People Search', type: :feature, js: true do + employees_json = { + 'data': [ + { + 'id': 33, + 'type': 'employee', + 'attributes': { + 'shortname': 'LSM', + 'firstname': 'Longmax', + 'lastname': 'Smith', + 'email': 'longmax@example.com', + 'marital_status': 'single', + 'nationalities': [ + 'ZW' + ], + 'graduation': 'BSc in Architecture', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 21, + 'type': 'employee', + 'attributes': { + 'shortname': 'AMA', + 'firstname': 'Alice', + 'lastname': 'Mante', + 'email': 'alice@example.com', + 'marital_status': 'single', + 'nationalities': [ + 'AU' + ], + 'graduation': 'MSc in writing', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + { + 'id': 45, + 'type': 'employee', + 'attributes': { + 'shortname': 'CFO', + 'firstname': 'Charlie', + 'lastname': 'Ford', + 'email': 'charlie@example.com', + 'marital_status': 'married', + 'nationalities': [ + 'GB' + ], + 'graduation': 'MSc in networking', + 'department_shortname': 'SYS', + 'employment_roles': [] + } + }, + ] + }.to_json before(:each) do sign_in auth_users(:user), scope: :auth_user @@ -49,6 +104,29 @@ expect(page).to have_no_text(name) end end + + it 'should redirect to correct person ' do + visit people_path + longmax = people(:longmax) + alice = people(:alice) + charlie = people(:charlie) + + longmax.ptime_employee_id = 33 + alice.ptime_employee_id = 21 + charlie.ptime_employee_id = 45 + longmax.save! + alice.save! + charlie.save! + + stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + + fetch_ptime_employees + + select_from_slim_select("#person_id_person", longmax.name) + expect(page).to have_current_path(person_path(longmax)) + end end def common_languages_translated diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb new file mode 100644 index 000000000..e69de29bb From ea3d4e56ebd3374d8b6e95d4b6cb74cc23b1c6ca Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 5 Jul 2024 09:50:22 +0200 Subject: [PATCH 39/79] Finish test and fix logic in displaying people --- app/helpers/person_helper.rb | 4 ++-- app/views/people/_search.html.haml | 2 +- spec/features/people_spec.rb | 28 +++++++++++++--------------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index a75fe1e5e..ce4d8a4fe 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -79,13 +79,13 @@ def not_rated_default_skills(person) def fetch_ptime_employees ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] - ptime_employee_id_map = Person.take(3).map do |p| + ptime_employee_id_map = Person.order(:name).all.map do |p| { p.ptime_employee_id.to_s => p.id } end.reduce({}, :merge) ptime_employees_dropdown_data = [] ptime_employees.each do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) - person_id = ptime_employee_id_map[ptime_employee['id']] + person_id = ptime_employee_id_map[ptime_employee['id'].to_s] ptime_employees_dropdown_data << [person_id, ptime_employee_name] end ptime_employees_dropdown_data diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index d25fb849b..e52108dbd 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,7 +1,7 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, {}, {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index c9bfc3f2e..3f4f87080 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -1,5 +1,12 @@ require 'rails_helper' +ptime_base_test_url = "www.ptime.example.com" +ptime_api_test_username = "test username" +ptime_api_test_password = "test password" +ENV["PTIME_BASE_URL"] = ptime_base_test_url +ENV["PTIME_API_USERNAME"] = ptime_api_test_username +ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + describe :people do describe 'People Search', type: :feature, js: true do employees_json = { @@ -106,26 +113,17 @@ end it 'should redirect to correct person ' do - visit people_path - longmax = people(:longmax) alice = people(:alice) - charlie = people(:charlie) - - longmax.ptime_employee_id = 33 alice.ptime_employee_id = 21 - charlie.ptime_employee_id = 45 - longmax.save! alice.save! - charlie.save! - - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - - fetch_ptime_employees - - select_from_slim_select("#person_id_person", longmax.name) - expect(page).to have_current_path(person_path(longmax)) + visit people_path + select_from_slim_select("#person_id_person", alice.name) + require "pry"; binding.pry + expect(page).to have_current_path(person_path(alice)) + expect(page).to have_css('.ss-single', text: 'Alice Mante') end end From 3a6b7c0a38e6c8b9e4bd2073b5a1cd553b066b8b Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 5 Jul 2024 15:47:41 +0200 Subject: [PATCH 40/79] Implement correct routing of person and fix a problem in the docker setup with yminder --- app/helpers/person_helper.rb | 10 +- .../controllers/dropdown_controller.js | 2 +- app/views/people/_search.html.haml | 3 +- docker-compose.yml | 2 +- package.json | 5 +- spec/features/people_spec.rb | 4 + yarn.lock | 301 +++++++++--------- 7 files changed, 175 insertions(+), 152 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index ce4d8a4fe..b181f3019 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -79,14 +79,20 @@ def not_rated_default_skills(person) def fetch_ptime_employees ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + # employed_employees = ptime_employees.select { |employee| employee['is_employed'] } ptime_employee_id_map = Person.order(:name).all.map do |p| { p.ptime_employee_id.to_s => p.id } end.reduce({}, :merge) ptime_employees_dropdown_data = [] - ptime_employees.each do |ptime_employee| + ptime_employee_ids = Person.all.pluck(:ptime_employee_id) + ptime_employees.each do |ptime_employee| # Replace 'ptime_employees' with 'employed_employees' ptime_employee_name = append_ptime_employee_name(ptime_employee) person_id = ptime_employee_id_map[ptime_employee['id'].to_s] - ptime_employees_dropdown_data << [person_id, ptime_employee_name] + ptime_employees_dropdown_data << {id: person_id, + ptime_employee_id: ptime_employee['id'], + name: ptime_employee_name, + already_exists: ptime_employee['id'].in?(ptime_employee_ids) + } end ptime_employees_dropdown_data end diff --git a/app/javascript/controllers/dropdown_controller.js b/app/javascript/controllers/dropdown_controller.js index 5639ce0ac..370e15e4c 100644 --- a/app/javascript/controllers/dropdown_controller.js +++ b/app/javascript/controllers/dropdown_controller.js @@ -11,6 +11,6 @@ export default class extends Controller { } handleChange(event) { - window.location.href = event.target.dataset.value + event.target.value; + window.location.href = event.target.dataset.value + event.target.value; } } diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index e52108dbd..28398c39e 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,7 +1,8 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + = select :person_id, :person, options_for_select(fetch_ptime_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} + -# = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} diff --git a/docker-compose.yml b/docker-compose.yml index 8568cb03a..b3e7e2063 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: /bin/bash -c " curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs && - npm install -g yarn && bin/assets && + npm install -g yarn && yarn add nodemon esbuild add && bin/assets && sleep infinity" volumes: - ./:/myapp diff --git a/package.json b/package.json index 41be726a2..bc5fe6873 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,12 @@ "@hotwired/stimulus": "^3.2.2", "@hotwired/turbo-rails": "^7.3.0", "@popperjs/core": "^2.11.8", + "add": "^2.0.6", "autoprefixer": "^10.4.17", "bootstrap": "^5.3.2", "bootstrap-icons": "^1.11.3", - "esbuild": "^0.20.0", - "nodemon": "^3.0.3", + "esbuild": "^0.23.0", + "nodemon": "^3.1.4", "postcss": "^8.4.33", "postcss-cli": "^11.0.0", "sass": "^1.70.0", diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 3f4f87080..e94f65f90 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -35,6 +35,7 @@ 'shortname': 'AMA', 'firstname': 'Alice', 'lastname': 'Mante', + 'full_name': 'Alice Mante', 'email': 'alice@example.com', 'marital_status': 'single', 'nationalities': [ @@ -43,6 +44,9 @@ 'graduation': 'MSc in writing', 'department_shortname': 'SYS', 'employment_roles': [] + 'is_employed': false, + 'birthdate': '01.04.2001' + 'location': 'Bern' } }, { diff --git a/yarn.lock b/yarn.lock index 00836deb0..00ff6b4cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,120 +2,125 @@ # yarn lockfile v1 -"@esbuild/aix-ppc64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz#eafa8775019b3650a77e8310ba4dbd17ca7af6d5" - integrity sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA== - -"@esbuild/android-arm64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz#68791afa389550736f682c15b963a4f37ec2f5f6" - integrity sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A== - -"@esbuild/android-arm@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.1.tgz#38c91d8ee8d5196f7fbbdf4f0061415dde3a473a" - integrity sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw== - -"@esbuild/android-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.1.tgz#93f6190ce997b313669c20edbf3645fc6c8d8f22" - integrity sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA== - -"@esbuild/darwin-arm64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz#0d391f2e81fda833fe609182cc2fbb65e03a3c46" - integrity sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA== - -"@esbuild/darwin-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz#92504077424584684862f483a2242cfde4055ba2" - integrity sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA== - -"@esbuild/freebsd-arm64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz#a1646fa6ba87029c67ac8a102bb34384b9290774" - integrity sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw== - -"@esbuild/freebsd-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz#41c9243ab2b3254ea7fb512f71ffdb341562e951" - integrity sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg== - -"@esbuild/linux-arm64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz#f3c1e1269fbc9eedd9591a5bdd32bf707a883156" - integrity sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w== - -"@esbuild/linux-arm@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz#4503ca7001a8ee99589c072801ce9d7540717a21" - integrity sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw== - -"@esbuild/linux-ia32@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz#98c474e3e0cbb5bcbdd8561a6e65d18f5767ce48" - integrity sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw== - -"@esbuild/linux-loong64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz#a8097d28d14b9165c725fe58fc438f80decd2f33" - integrity sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA== - -"@esbuild/linux-mips64el@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz#c44f6f0d7d017c41ad3bb15bfdb69b690656b5ea" - integrity sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA== - -"@esbuild/linux-ppc64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz#0765a55389a99237b3c84227948c6e47eba96f0d" - integrity sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw== - -"@esbuild/linux-riscv64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz#e4153b032288e3095ddf4c8be07893781b309a7e" - integrity sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg== - -"@esbuild/linux-s390x@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz#b9ab8af6e4b73b26d63c1c426d7669a5d53eb5a7" - integrity sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ== - -"@esbuild/linux-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz#0b25da17ac38c3e11cdd06ca3691d4d6bef2755f" - integrity sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA== - -"@esbuild/netbsd-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz#3148e48406cd0d4f7ba1e0bf3f4d77d548c98407" - integrity sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg== - -"@esbuild/openbsd-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz#7b73e852986a9750192626d377ac96ac2b749b76" - integrity sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw== - -"@esbuild/sunos-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz#402a441cdac2eee98d8be378c7bc23e00c1861c5" - integrity sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q== - -"@esbuild/win32-arm64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz#36c4e311085806a6a0c5fc54d1ac4d7b27e94d7b" - integrity sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A== - -"@esbuild/win32-ia32@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz#0cf933be3fb9dc58b45d149559fe03e9e22b54fe" - integrity sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw== - -"@esbuild/win32-x64@0.20.1": - version "0.20.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz#77583b6ea54cee7c1410ebbd54051b6a3fcbd8ba" - integrity sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA== +"@esbuild/aix-ppc64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz#145b74d5e4a5223489cabdc238d8dad902df5259" + integrity sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ== + +"@esbuild/android-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz#453bbe079fc8d364d4c5545069e8260228559832" + integrity sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ== + +"@esbuild/android-arm@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.0.tgz#26c806853aa4a4f7e683e519cd9d68e201ebcf99" + integrity sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g== + +"@esbuild/android-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.0.tgz#1e51af9a6ac1f7143769f7ee58df5b274ed202e6" + integrity sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ== + +"@esbuild/darwin-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz#d996187a606c9534173ebd78c58098a44dd7ef9e" + integrity sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow== + +"@esbuild/darwin-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz#30c8f28a7ef4e32fe46501434ebe6b0912e9e86c" + integrity sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ== + +"@esbuild/freebsd-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz#30f4fcec8167c08a6e8af9fc14b66152232e7fb4" + integrity sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw== + +"@esbuild/freebsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz#1003a6668fe1f5d4439e6813e5b09a92981bc79d" + integrity sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ== + +"@esbuild/linux-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz#3b9a56abfb1410bb6c9138790f062587df3e6e3a" + integrity sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw== + +"@esbuild/linux-arm@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz#237a8548e3da2c48cd79ae339a588f03d1889aad" + integrity sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw== + +"@esbuild/linux-ia32@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz#4269cd19cb2de5de03a7ccfc8855dde3d284a238" + integrity sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA== + +"@esbuild/linux-loong64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz#82b568f5658a52580827cc891cb69d2cb4f86280" + integrity sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A== + +"@esbuild/linux-mips64el@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz#9a57386c926262ae9861c929a6023ed9d43f73e5" + integrity sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w== + +"@esbuild/linux-ppc64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz#f3a79fd636ba0c82285d227eb20ed8e31b4444f6" + integrity sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw== + +"@esbuild/linux-riscv64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz#f9d2ef8356ce6ce140f76029680558126b74c780" + integrity sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw== + +"@esbuild/linux-s390x@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz#45390f12e802201f38a0229e216a6aed4351dfe8" + integrity sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg== + +"@esbuild/linux-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz#c8409761996e3f6db29abcf9b05bee8d7d80e910" + integrity sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ== + +"@esbuild/netbsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz#ba70db0114380d5f6cfb9003f1d378ce989cd65c" + integrity sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw== + +"@esbuild/openbsd-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz#72fc55f0b189f7a882e3cf23f332370d69dfd5db" + integrity sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ== + +"@esbuild/openbsd-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz#b6ae7a0911c18fe30da3db1d6d17a497a550e5d8" + integrity sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg== + +"@esbuild/sunos-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz#58f0d5e55b9b21a086bfafaa29f62a3eb3470ad8" + integrity sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA== + +"@esbuild/win32-arm64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz#b858b2432edfad62e945d5c7c9e5ddd0f528ca6d" + integrity sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ== + +"@esbuild/win32-ia32@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz#167ef6ca22a476c6c0c014a58b4f43ae4b80dec7" + integrity sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA== + +"@esbuild/win32-x64@0.23.0": + version "0.23.0" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz#db44a6a08520b5f25bbe409f34a59f2d4bcc7ced" + integrity sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g== "@hotwired/stimulus@^3.2.2": version "3.2.2" @@ -176,6 +181,11 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +add@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" + integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -321,34 +331,35 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -esbuild@^0.20.0: - version "0.20.1" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.1.tgz#1e4cbb380ad1959db7609cb9573ee77257724a3e" - integrity sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA== +esbuild@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.0.tgz#de06002d48424d9fdb7eb52dbe8e95927f852599" + integrity sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.1" - "@esbuild/android-arm" "0.20.1" - "@esbuild/android-arm64" "0.20.1" - "@esbuild/android-x64" "0.20.1" - "@esbuild/darwin-arm64" "0.20.1" - "@esbuild/darwin-x64" "0.20.1" - "@esbuild/freebsd-arm64" "0.20.1" - "@esbuild/freebsd-x64" "0.20.1" - "@esbuild/linux-arm" "0.20.1" - "@esbuild/linux-arm64" "0.20.1" - "@esbuild/linux-ia32" "0.20.1" - "@esbuild/linux-loong64" "0.20.1" - "@esbuild/linux-mips64el" "0.20.1" - "@esbuild/linux-ppc64" "0.20.1" - "@esbuild/linux-riscv64" "0.20.1" - "@esbuild/linux-s390x" "0.20.1" - "@esbuild/linux-x64" "0.20.1" - "@esbuild/netbsd-x64" "0.20.1" - "@esbuild/openbsd-x64" "0.20.1" - "@esbuild/sunos-x64" "0.20.1" - "@esbuild/win32-arm64" "0.20.1" - "@esbuild/win32-ia32" "0.20.1" - "@esbuild/win32-x64" "0.20.1" + "@esbuild/aix-ppc64" "0.23.0" + "@esbuild/android-arm" "0.23.0" + "@esbuild/android-arm64" "0.23.0" + "@esbuild/android-x64" "0.23.0" + "@esbuild/darwin-arm64" "0.23.0" + "@esbuild/darwin-x64" "0.23.0" + "@esbuild/freebsd-arm64" "0.23.0" + "@esbuild/freebsd-x64" "0.23.0" + "@esbuild/linux-arm" "0.23.0" + "@esbuild/linux-arm64" "0.23.0" + "@esbuild/linux-ia32" "0.23.0" + "@esbuild/linux-loong64" "0.23.0" + "@esbuild/linux-mips64el" "0.23.0" + "@esbuild/linux-ppc64" "0.23.0" + "@esbuild/linux-riscv64" "0.23.0" + "@esbuild/linux-s390x" "0.23.0" + "@esbuild/linux-x64" "0.23.0" + "@esbuild/netbsd-x64" "0.23.0" + "@esbuild/openbsd-arm64" "0.23.0" + "@esbuild/openbsd-x64" "0.23.0" + "@esbuild/sunos-x64" "0.23.0" + "@esbuild/win32-arm64" "0.23.0" + "@esbuild/win32-ia32" "0.23.0" + "@esbuild/win32-x64" "0.23.0" escalade@^3.1.1: version "3.1.2" @@ -543,10 +554,10 @@ node-releases@^2.0.14: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -nodemon@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.3.tgz#244a62d1c690eece3f6165c6cdb0db03ebd80b76" - integrity sha512-7jH/NXbFPxVaMwmBCC2B9F/V6X1VkEdNgx3iu9jji8WxWcvhMWkmhNWhI5077zknOnZnBzba9hZP6bCPJLSReQ== +nodemon@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.4.tgz#c34dcd8eb46a05723ccde60cbdd25addcc8725e4" + integrity sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ== dependencies: chokidar "^3.5.2" debug "^4" From c25e18c8f0253f4e87bcd6f18554bcab329285de Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 8 Jul 2024 11:37:27 +0200 Subject: [PATCH 41/79] Possibly fix docker compose file --- docker-compose.yml | 2 +- package.json | 1 - yarn.lock | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index b3e7e2063..c54c7c2ce 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,7 +41,7 @@ services: /bin/bash -c " curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && apt-get install -y nodejs && - npm install -g yarn && yarn add nodemon esbuild add && bin/assets && + npm install -g yarn && yarn add nodemon esbuild && bin/assets && sleep infinity" volumes: - ./:/myapp diff --git a/package.json b/package.json index bc5fe6873..1316e6270 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "@hotwired/stimulus": "^3.2.2", "@hotwired/turbo-rails": "^7.3.0", "@popperjs/core": "^2.11.8", - "add": "^2.0.6", "autoprefixer": "^10.4.17", "bootstrap": "^5.3.2", "bootstrap-icons": "^1.11.3", diff --git a/yarn.lock b/yarn.lock index 00ff6b4cc..1c57f5884 100644 --- a/yarn.lock +++ b/yarn.lock @@ -181,11 +181,6 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -add@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" - integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" From 4385c4ac5779f0149dc96a7230c4c6b4a81cd821 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 8 Jul 2024 14:58:59 +0200 Subject: [PATCH 42/79] Fix tests and implement logic for sorting people --- app/views/people/_search.html.haml | 3 +- spec/features/people_spec.rb | 109 ++++++++++++++--------------- 2 files changed, 53 insertions(+), 59 deletions(-) diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index 28398c39e..746cba0ab 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,7 +1,8 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - = select :person_id, :person, options_for_select(fetch_ptime_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} + - sorted_employees = fetch_ptime_employees.sort_by { |p| p[:name] } + = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} -# = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index e94f65f90..b9d022776 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -10,64 +10,58 @@ describe :people do describe 'People Search', type: :feature, js: true do employees_json = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'LSM', - 'firstname': 'Longmax', - 'lastname': 'Smith', - 'email': 'longmax@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'BSc in Architecture', - 'department_shortname': 'SYS', - 'employment_roles': [] + 'data' => [ + { + 'id' => 33, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'LSM', + 'firstname' => 'Longmax', + 'lastname' => 'Smith', + 'email' => 'longmax@example.com', + 'marital_status' => 'single', + 'nationalities' => ['ZW'], + 'graduation' => 'BSc in Architecture', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } + }, + { + 'id' => 21, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'AMA', + 'firstname' => 'Alice', + 'lastname' => 'Mante', + 'full_name' => 'Alice Mante', + 'email' => 'alice@example.com', + 'marital_status' => 'single', + 'nationalities' => ['AU'], + 'graduation' => 'MSc in writing', + 'department_shortname' => 'SYS', + 'employment_roles' => [], + 'is_employed' => false, + 'birthdate' => '01.04.2001', + 'location' => 'Bern' + } + }, + { + 'id' => 45, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'CFO', + 'firstname' => 'Charlie', + 'lastname' => 'Ford', + 'email' => 'charlie@example.com', + 'marital_status' => 'married', + 'nationalities' => ['GB'], + 'graduation' => 'MSc in networking', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } } - }, - { - 'id': 21, - 'type': 'employee', - 'attributes': { - 'shortname': 'AMA', - 'firstname': 'Alice', - 'lastname': 'Mante', - 'full_name': 'Alice Mante', - 'email': 'alice@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'AU' - ], - 'graduation': 'MSc in writing', - 'department_shortname': 'SYS', - 'employment_roles': [] - 'is_employed': false, - 'birthdate': '01.04.2001' - 'location': 'Bern' - } - }, - { - 'id': 45, - 'type': 'employee', - 'attributes': { - 'shortname': 'CFO', - 'firstname': 'Charlie', - 'lastname': 'Ford', - 'email': 'charlie@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'GB' - ], - 'graduation': 'MSc in networking', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - ] - }.to_json + ] + }.to_json before(:each) do sign_in auth_users(:user), scope: :auth_user @@ -125,7 +119,6 @@ .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) visit people_path select_from_slim_select("#person_id_person", alice.name) - require "pry"; binding.pry expect(page).to have_current_path(person_path(alice)) expect(page).to have_css('.ss-single', text: 'Alice Mante') end From 202006a9bd9508577557e0032c1a11b73f1982fc Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 9 Jul 2024 12:46:25 +0200 Subject: [PATCH 43/79] Implement logic for fallback and cleanup helper method --- app/domain/ptime/client.rb | 5 +-- app/helpers/person_helper.rb | 51 +++++++++++++++++++----------- app/views/people/_search.html.haml | 8 +++-- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index def0d8c5c..52356c92b 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -16,13 +16,14 @@ def get(endpoint, params = {}) private def request(method, path, params = nil) + ENV['PTIME_API_ACCESSIBLE'] = 'true' path = "#{path}?#{URI.encode_www_form(params)}" response = RestClient.send(method, path, headers) JSON.parse(response.body) - rescue RestClient::BadRequest => e + rescue RestClient::ExceptionWithResponse => e + ENV['PTIME_API_ACCESSIBLE'] = 'false' msg = response_error_message(e) e.message = msg if msg.present? - raise e end def response_error_message(exception) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index b181f3019..bfd49920c 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -78,28 +78,43 @@ def not_rated_default_skills(person) end def fetch_ptime_employees - ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] - # employed_employees = ptime_employees.select { |employee| employee['is_employed'] } - ptime_employee_id_map = Person.order(:name).all.map do |p| - { p.ptime_employee_id.to_s => p.id } - end.reduce({}, :merge) - ptime_employees_dropdown_data = [] - ptime_employee_ids = Person.all.pluck(:ptime_employee_id) - ptime_employees.each do |ptime_employee| # Replace 'ptime_employees' with 'employed_employees' + ptime_employees = fetch_all_ptime_employees + ptime_employee_ids = fetch_all_ptime_employee_ids + build_dropdown_data(ptime_employees, ptime_employee_ids) + end + + def fetch_all_ptime_employees + Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + end + + def fetch_all_ptime_employee_ids + Person.all.pluck(:ptime_employee_id) + end + + def build_dropdown_data(ptime_employees, ptime_employee_ids) + ptime_employees.map do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) - person_id = ptime_employee_id_map[ptime_employee['id'].to_s] - ptime_employees_dropdown_data << {id: person_id, - ptime_employee_id: ptime_employee['id'], - name: ptime_employee_name, - already_exists: ptime_employee['id'].in?(ptime_employee_ids) - } + person_id = map_ptime_employee_id(ptime_employee) + { + id: person_id, + ptime_employee_id: ptime_employee['id'], + name: ptime_employee_name, + already_exists: ptime_employee['id'].in?(ptime_employee_ids) + } end - ptime_employees_dropdown_data + end + + def map_ptime_employee_id(ptime_employee) + ptime_employee_id_map = Person.all.each_with_object({}) do |person, hash| + hash[person.ptime_employee_id.to_s] = person.id + end + + ptime_employee_id_map[ptime_employee['id'].to_s] end def append_ptime_employee_name(ptime_employee) - ptime_employee_firstname = ptime_employee['attributes']['firstname'] - ptime_employee_lastname = ptime_employee['attributes']['lastname'] - "#{ptime_employee_firstname} #{ptime_employee_lastname}" + firstname = ptime_employee['attributes']['firstname'] + lastname = ptime_employee['attributes']['lastname'] + "#{firstname} #{lastname}" end end diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index 746cba0ab..f9f9e4da9 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,9 +1,11 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - - sorted_employees = fetch_ptime_employees.sort_by { |p| p[:name] } - = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} - -# = collection_select :person_id, :person, fetch_ptime_employees, :first, :last, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + - if ENV['PTIME_API_ACCESSIBLE'] == 'true' + - sorted_employees = fetch_ptime_employees.sort_by { |p| p[:name] } + = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} + - else + = collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} From 1dc306579a88c5b492472a58734af4edef518c39 Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 9 Jul 2024 15:43:42 +0200 Subject: [PATCH 44/79] Improve fallback logic by making it more readable and shorter --- app/controllers/people_controller.rb | 7 +++++++ app/domain/ptime/client.rb | 3 +-- app/views/people/_search.html.haml | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 6d1fed1b8..78e148cef 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -5,6 +5,8 @@ class PeopleController < CrudController include ParamConverters include PeopleControllerConcerns + helper_method :ptime_broken? + self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, :nationality2, :title, :competence_notes, :company_id, :email, :department_id, :shortname, :picture, :picture_cache, @@ -69,4 +71,9 @@ def fetch_entries def person @person ||= Person.find(params[:person_id]) end + + def ptime_broken? + # Test what happens when ptime_accessible is nil + !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + end end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 52356c92b..ab3d55ffd 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -10,13 +10,12 @@ def initialize end def get(endpoint, params = {}) - request(:get, @base_url + endpoint, params) + request(:get, @base_url + endpoint, params) unless ENV['PTIME_API_ACCESSIBLE'] end private def request(method, path, params = nil) - ENV['PTIME_API_ACCESSIBLE'] = 'true' path = "#{path}?#{URI.encode_www_form(params)}" response = RestClient.send(method, path, headers) JSON.parse(response.body) diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index f9f9e4da9..a3cfcb51f 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,11 +1,11 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - - if ENV['PTIME_API_ACCESSIBLE'] == 'true' + - if ptime_broken? + = collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + - else - sorted_employees = fetch_ptime_employees.sort_by { |p| p[:name] } = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} - - else - = collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} From 12677362eb19496706507c5e1bec4b1c4273b4ee Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 10 Jul 2024 13:42:01 +0200 Subject: [PATCH 45/79] Implement first approach on calling the ptime api after 5 minutes --- app/domain/ptime/client.rb | 3 +++ app/helpers/person_helper.rb | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index ab3d55ffd..77860dbe9 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -21,8 +21,11 @@ def request(method, path, params = nil) JSON.parse(response.body) rescue RestClient::ExceptionWithResponse => e ENV['PTIME_API_ACCESSIBLE'] = 'false' + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s msg = response_error_message(e) e.message = msg if msg.present? + + get('employees', { per_page: 1000 })['data'] end def response_error_message(exception) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index bfd49920c..6bb90bffe 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -117,4 +117,14 @@ def append_ptime_employee_name(ptime_employee) lastname = ptime_employee['attributes']['lastname'] "#{firstname} #{lastname}" end + + def try_new_ptime_api_call + last_datetime = ENV['LAST_PTIME_API_REQUEST'].to_datetime + current_datetime = DateTime.now + difference_in_minutes = ((current_datetime - last_datetime) * 24 * 60).to_i + + if difference_in_minutes >= 5 + fetch_all_ptime_employees + end + end end From 512593bad81f9a061a8746cf6228069e237e0e4a Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 11 Jul 2024 09:44:00 +0200 Subject: [PATCH 46/79] Improve logic of 5 minutes request and change client.rb --- app/domain/ptime/assign_employee_ids.rb | 2 +- app/domain/ptime/client.rb | 44 ++++++++++++++++--------- app/domain/ptime/update_people_data.rb | 2 +- app/helpers/person_helper.rb | 12 +------ spec/domain/ptime/client_spec.rb | 4 +-- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index ea4416952..c9ee84a0a 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -60,7 +60,7 @@ def map_employees(should_map) def fetch_data puts 'Fetching required data...' - @ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] @skills_people = Person.all puts 'Successfully fetched data' end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 77860dbe9..f463d099b 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -9,25 +9,19 @@ def initialize @base_url = "#{ENV.fetch('PTIME_BASE_URL')}/api/v1/" end - def get(endpoint, params = {}) - request(:get, @base_url + endpoint, params) unless ENV['PTIME_API_ACCESSIBLE'] + def request(method, endpoint, params = {}) + path = @base_url + endpoint + if ENV['PTIME_API_ACCESSIBLE'].nil? && last_ptime_api_request_more_than_5_minutes + send_request_and_parse_response(method, path, params) + else + skills_database_request + end + rescue RestClient::ExceptionWithResponse + skills_database_request end private - def request(method, path, params = nil) - path = "#{path}?#{URI.encode_www_form(params)}" - response = RestClient.send(method, path, headers) - JSON.parse(response.body) - rescue RestClient::ExceptionWithResponse => e - ENV['PTIME_API_ACCESSIBLE'] = 'false' - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s - msg = response_error_message(e) - e.message = msg if msg.present? - - get('employees', { per_page: 1000 })['data'] - end - def response_error_message(exception) JSON.parse(exception.response.body).dig('error', 'message') rescue JSON::ParserError # rescue only JSON parsing errors @@ -45,5 +39,25 @@ def headers def basic_token Base64.encode64("#{ENV.fetch('PTIME_API_USERNAME')}:#{ENV.fetch('PTIME_API_PASSWORD')}") end + + def last_ptime_api_request_more_than_5_minutes + last_request_time = ENV.fetch('LAST_PTIME_API_REQUEST', nil) + return true if last_request_time.nil? + + last_request_time.to_datetime <= 5.minutes.ago + end + + def send_request_and_parse_response(method, path, params) + path = "#{path}?#{URI.encode_www_form(params)}" if method == :get + response = RestClient.send(method, path, headers) + JSON.parse(response.body) + end + + def skills_database_request + ENV['PTIME_API_ACCESSIBLE'] = 'false' + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s + + get('employees', { per_page: 1000 })['data'] + end end end diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index db885ea87..24eb88558 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -7,7 +7,7 @@ class UpdatePeopleData # rubocop:disable Metrics def run - ptime_employees = Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] ptime_employees.each do |ptime_employee| ptime_employee_firstname = ptime_employee['attributes']['firstname'] ptime_employee_lastname = ptime_employee['attributes']['lastname'] diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 6bb90bffe..8c563123b 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -84,7 +84,7 @@ def fetch_ptime_employees end def fetch_all_ptime_employees - Ptime::Client.new.get('employees', { per_page: 1000 })['data'] + Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] end def fetch_all_ptime_employee_ids @@ -117,14 +117,4 @@ def append_ptime_employee_name(ptime_employee) lastname = ptime_employee['attributes']['lastname'] "#{firstname} #{lastname}" end - - def try_new_ptime_api_call - last_datetime = ENV['LAST_PTIME_API_REQUEST'].to_datetime - current_datetime = DateTime.now - difference_in_minutes = ((current_datetime - last_datetime) * 24 * 60).to_i - - if difference_in_minutes >= 5 - fetch_all_ptime_employees - end - end end diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index bdcc6b9c7..062d59c73 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -69,7 +69,7 @@ to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - fetched_employees = Ptime::Client.new.get("employees") + fetched_employees = Ptime::Client.new.request(:get, "employees") expect(fetched_employees).to eq(JSON.parse(employees_json)) end @@ -80,6 +80,6 @@ to_return(body: employees_json, status: 404) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - expect{ Ptime::Client.new.get("") }.to raise_error(RestClient::NotFound) + expect{ Ptime::Client.new.request(:get, "") }.to raise_error(RestClient::NotFound) end end From c9e982520724ab11f8445bfae2991c15d7630063 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 12 Jul 2024 09:50:11 +0200 Subject: [PATCH 47/79] Add logic to load site correctly and remove unnecessary code --- .../people/people_skills_create_controller.rb | 6 ++++++ app/controllers/people_controller.rb | 9 ++++----- app/domain/ptime/client.rb | 2 -- spec/domain/ptime/client_spec.rb | 10 ---------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/app/controllers/people/people_skills_create_controller.rb b/app/controllers/people/people_skills_create_controller.rb index 1c7430fb5..287c8ded6 100644 --- a/app/controllers/people/people_skills_create_controller.rb +++ b/app/controllers/people/people_skills_create_controller.rb @@ -8,6 +8,8 @@ class People::PeopleSkillsCreateController < CrudController self.nesting = Person layout 'person' + helper_method :ptime_broken? + def index return super if params[:rating].present? @@ -44,4 +46,8 @@ def filter_by_rating(people_skills, rating) def self.controller_path 'people/people_skills' end + + def ptime_broken? + !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + end end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 78e148cef..b47a5b3d7 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -62,6 +62,10 @@ def export disposition: content_disposition('attachment', filename) end + def ptime_broken? + !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + end + private def fetch_entries @@ -71,9 +75,4 @@ def fetch_entries def person @person ||= Person.find(params[:person_id]) end - - def ptime_broken? - # Test what happens when ptime_accessible is nil - !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) - end end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index f463d099b..bed6204a4 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -56,8 +56,6 @@ def send_request_and_parse_response(method, path, params) def skills_database_request ENV['PTIME_API_ACCESSIBLE'] = 'false' ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s - - get('employees', { per_page: 1000 })['data'] end end end diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 062d59c73..4b60f1b4d 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -72,14 +72,4 @@ fetched_employees = Ptime::Client.new.request(:get, "employees") expect(fetched_employees).to eq(JSON.parse(employees_json)) end - - it 'should throw error message when host is not reachable' do - ENV["PTIME_BASE_URL"] = "www.unreachablehost.example.com" - - stub_request(:get, "www.unreachablehost.example.com/api/v1/"). - to_return(body: employees_json, status: 404) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - - expect{ Ptime::Client.new.request(:get, "") }.to raise_error(RestClient::NotFound) - end end From 39acf6e4d0c722f4db0c69b53865c0d99535e53a Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 15 Jul 2024 09:51:35 +0200 Subject: [PATCH 48/79] Fix logic of rendering people and cleanup code --- app/domain/ptime/client.rb | 3 ++- app/helpers/person_helper.rb | 21 +++++++-------------- app/views/people/_search.html.haml | 9 +++++---- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index bed6204a4..2dd72f743 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -11,7 +11,7 @@ def initialize def request(method, endpoint, params = {}) path = @base_url + endpoint - if ENV['PTIME_API_ACCESSIBLE'].nil? && last_ptime_api_request_more_than_5_minutes + if last_ptime_api_request_more_than_5_minutes send_request_and_parse_response(method, path, params) else skills_database_request @@ -48,6 +48,7 @@ def last_ptime_api_request_more_than_5_minutes end def send_request_and_parse_response(method, path, params) + ENV['PTIME_API_ACCESSIBLE'] = 'true' path = "#{path}?#{URI.encode_www_form(params)}" if method == :get response = RestClient.send(method, path, headers) JSON.parse(response.body) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 8c563123b..61bf95bbb 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -77,18 +77,13 @@ def not_rated_default_skills(person) end end - def fetch_ptime_employees - ptime_employees = fetch_all_ptime_employees - ptime_employee_ids = fetch_all_ptime_employee_ids - build_dropdown_data(ptime_employees, ptime_employee_ids) - end + def fetch_ptime_or_skills_data + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] + all_skills_people = Person.all + return all_skills_people if ENV['PTIME_API_ACCESSIBLE'] == 'false' - def fetch_all_ptime_employees - Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] - end - - def fetch_all_ptime_employee_ids - Person.all.pluck(:ptime_employee_id) + ptime_employee_ids = all_skills_people.pluck(:ptime_employee_id) + build_dropdown_data(ptime_employees, ptime_employee_ids) end def build_dropdown_data(ptime_employees, ptime_employee_ids) @@ -113,8 +108,6 @@ def map_ptime_employee_id(ptime_employee) end def append_ptime_employee_name(ptime_employee) - firstname = ptime_employee['attributes']['firstname'] - lastname = ptime_employee['attributes']['lastname'] - "#{firstname} #{lastname}" + "#{ptime_employee['attributes']['firstname']} #{ptime_employee['attributes']['lastname']}" end end diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index a3cfcb51f..23ea31441 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,10 +1,11 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - - if ptime_broken? - = collection_select :person_id, :person, Person.all.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} - - else - - sorted_employees = fetch_ptime_employees.sort_by { |p| p[:name] } + - people_data = fetch_ptime_or_skills_data + - if ptime_broken? # people_data == skills + = collection_select :person_id, :person, people_data.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} + - elsif ENV['PTIME_API_ACCESSIBLE'] = 'true' # people_data == time + - sorted_employees = people_data.sort_by { |p| p[:name] } = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at From d967660aca62be755c64686645653cb1284fd384 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 17 Jul 2024 09:19:08 +0200 Subject: [PATCH 49/79] Add tests for person_helper --- spec/helpers/person_helper_spec.rb | 109 +++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 spec/helpers/person_helper_spec.rb diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb new file mode 100644 index 000000000..2289352eb --- /dev/null +++ b/spec/helpers/person_helper_spec.rb @@ -0,0 +1,109 @@ +require 'rails_helper' + +ptime_base_test_url = "www.ptime.example.com" +ptime_api_test_username = "test username" +ptime_api_test_password = "test password" +ENV["PTIME_BASE_URL"] = ptime_base_test_url +ENV["PTIME_API_USERNAME"] = ptime_api_test_username +ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + +RSpec.describe PersonHelper, type: :helper do + employees_json = { + 'data' => [ + { + 'id' => 33, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'LSM', + 'firstname' => 'Longmax', + 'lastname' => 'Smith', + 'email' => 'longmax@example.com', + 'marital_status' => 'single', + 'nationalities' => ['ZW'], + 'graduation' => 'BSc in Architecture', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } + }, + { + 'id' => 21, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'AMA', + 'firstname' => 'Alice', + 'lastname' => 'Mante', + 'full_name' => 'Alice Mante', + 'email' => 'alice@example.com', + 'marital_status' => 'single', + 'nationalities' => ['AU'], + 'graduation' => 'MSc in writing', + 'department_shortname' => 'SYS', + 'employment_roles' => [], + 'is_employed' => false, + 'birthdate' => '01.04.2001', + 'location' => 'Bern' + } + }, + { + 'id' => 45, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'CFO', + 'firstname' => 'Charlie', + 'lastname' => 'Ford', + 'email' => 'charlie@example.com', + 'marital_status' => 'married', + 'nationalities' => ['GB'], + 'graduation' => 'MSc in networking', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } + } + ] + }.to_json + + describe '#fetch_ptime_or_skills_data' do + it 'should send request to ptime api' do + stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + fetch_ptime_or_skills_data + end + + it 'should return people from skills database if last request was right now' do + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s + skills_people = fetch_ptime_or_skills_data + expect(skills_people).to eq(Person.all) + end + end + + describe '#build_dropdown_data' do + it 'should build correct dropdown data' do + longmax = people(:longmax) + alice = people(:alice) + charlie = people(:charlie) + + longmax.update!(ptime_employee_id: 33) + alice.update!(ptime_employee_id: 21) + charlie.update!(ptime_employee_id: 45) + + parsed_employees = JSON.parse(employees_json) + dropdown_data = build_dropdown_data(parsed_employees['data'], Person.all.pluck(:ptime_employee_id)) + + expect(dropdown_data[0][:id]).to eq(longmax.id) + expect(dropdown_data[0][:ptime_employee_id]).to eq(longmax.ptime_employee_id) + expect(dropdown_data[0][:name]).to eq("Longmax Smith") + expect(dropdown_data[0][:already_exists]).to be(true) + + expect(dropdown_data[1][:id]).to eq(alice.id) + expect(dropdown_data[1][:ptime_employee_id]).to eq(alice.ptime_employee_id) + expect(dropdown_data[1][:name]).to eq("Alice Mante") + expect(dropdown_data[1][:already_exists]).to be(true) + + expect(dropdown_data[2][:id]).to eq(charlie.id) + expect(dropdown_data[2][:ptime_employee_id]).to eq(charlie.ptime_employee_id) + expect(dropdown_data[2][:name]).to eq("Charlie Ford") + expect(dropdown_data[2][:already_exists]).to be(true) + end + end +end \ No newline at end of file From c657e8f3e2af6e41b57a4207ee305e54187467c0 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 17 Jul 2024 11:29:59 +0200 Subject: [PATCH 50/79] Add ptime_helpers to cleanup code --- spec/helpers/person_helper_spec.rb | 68 ++--------------------------- spec/rails_helper.rb | 1 + spec/support/ptime_helpers.rb | 70 ++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 65 deletions(-) diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index 2289352eb..f007140bf 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -1,72 +1,10 @@ require 'rails_helper' - -ptime_base_test_url = "www.ptime.example.com" -ptime_api_test_username = "test username" -ptime_api_test_password = "test password" -ENV["PTIME_BASE_URL"] = ptime_base_test_url -ENV["PTIME_API_USERNAME"] = ptime_api_test_username -ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - RSpec.describe PersonHelper, type: :helper do - employees_json = { - 'data' => [ - { - 'id' => 33, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'LSM', - 'firstname' => 'Longmax', - 'lastname' => 'Smith', - 'email' => 'longmax@example.com', - 'marital_status' => 'single', - 'nationalities' => ['ZW'], - 'graduation' => 'BSc in Architecture', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - }, - { - 'id' => 21, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'AMA', - 'firstname' => 'Alice', - 'lastname' => 'Mante', - 'full_name' => 'Alice Mante', - 'email' => 'alice@example.com', - 'marital_status' => 'single', - 'nationalities' => ['AU'], - 'graduation' => 'MSc in writing', - 'department_shortname' => 'SYS', - 'employment_roles' => [], - 'is_employed' => false, - 'birthdate' => '01.04.2001', - 'location' => 'Bern' - } - }, - { - 'id' => 45, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'CFO', - 'firstname' => 'Charlie', - 'lastname' => 'Ford', - 'email' => 'charlie@example.com', - 'marital_status' => 'married', - 'nationalities' => ['GB'], - 'graduation' => 'MSc in networking', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - } - ] - }.to_json describe '#fetch_ptime_or_skills_data' do + it 'should send request to ptime api' do - stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + set_env_variables_and_stub_request fetch_ptime_or_skills_data end @@ -87,7 +25,7 @@ alice.update!(ptime_employee_id: 21) charlie.update!(ptime_employee_id: 45) - parsed_employees = JSON.parse(employees_json) + parsed_employees = JSON.parse(return_ptime_employees_json) dropdown_data = build_dropdown_data(parsed_employees['data'], Person.all.pluck(:ptime_employee_id)) expect(dropdown_data[0][:id]).to eq(longmax.id) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index b2531af7d..bc7f2fca6 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -74,6 +74,7 @@ config.include(PersonRelationsHelpers, type: :feature) config.include(SlimselectHelpers, type: :feature) config.include(PeopleSkillsHelpers, type: :feature) + config.include(PtimeHelpers) config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index e69de29bb..8bd79203a 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -0,0 +1,70 @@ +module PtimeHelpers + def set_env_variables_and_stub_request + ptime_base_test_url = "www.ptime.example.com" + ptime_api_test_username = "test username" + ptime_api_test_password = "test password" + ENV["PTIME_BASE_URL"] = ptime_base_test_url + ENV["PTIME_API_USERNAME"] = ptime_api_test_username + ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + + stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + to_return(body: return_ptime_employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + end + + def return_ptime_employees_json + employees_json = { + 'data' => [ + { + 'id' => 33, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'LSM', + 'firstname' => 'Longmax', + 'lastname' => 'Smith', + 'email' => 'longmax@example.com', + 'marital_status' => 'single', + 'nationalities' => ['ZW'], + 'graduation' => 'BSc in Architecture', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } + }, + { + 'id' => 21, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'AMA', + 'firstname' => 'Alice', + 'lastname' => 'Mante', + 'full_name' => 'Alice Mante', + 'email' => 'alice@example.com', + 'marital_status' => 'single', + 'nationalities' => ['AU'], + 'graduation' => 'MSc in writing', + 'department_shortname' => 'SYS', + 'employment_roles' => [], + 'is_employed' => false, + 'birthdate' => '01.04.2001', + 'location' => 'Bern' + } + }, + { + 'id' => 45, + 'type' => 'employee', + 'attributes' => { + 'shortname' => 'CFO', + 'firstname' => 'Charlie', + 'lastname' => 'Ford', + 'email' => 'charlie@example.com', + 'marital_status' => 'married', + 'nationalities' => ['GB'], + 'graduation' => 'MSc in networking', + 'department_shortname' => 'SYS', + 'employment_roles' => [] + } + } + ] + }.to_json + end +end \ No newline at end of file From bcb3ebe373fc62e7047661851c63dbeab5d9f0c2 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 17 Jul 2024 16:07:17 +0200 Subject: [PATCH 51/79] Fix tests --- spec/features/activities_spec.rb | 2 + .../features/add_create_people_skills_spec.rb | 1 + spec/features/advanced_trainings_spec.rb | 2 + spec/features/auth_spec.rb | 2 + spec/features/core_competences_spec.rb | 1 + spec/features/cv_export_spec.rb | 1 + spec/features/cv_search_spec.rb | 1 + spec/features/edit_people_skills_spec.rb | 3 + spec/features/educations_spec.rb | 2 + spec/features/people_show_spec.rb | 1 + spec/features/people_spec.rb | 69 ++----------------- spec/support/people_skills_helper.rb | 1 + 12 files changed, 23 insertions(+), 63 deletions(-) diff --git a/spec/features/activities_spec.rb b/spec/features/activities_spec.rb index 56415ca3a..8441ecd0f 100644 --- a/spec/features/activities_spec.rb +++ b/spec/features/activities_spec.rb @@ -4,6 +4,8 @@ let(:person) { people(:bob) } before(:each) do + Capybara.page.driver.browser.manage.window.maximize + set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/add_create_people_skills_spec.rb b/spec/features/add_create_people_skills_spec.rb index cd6ef498b..7ecd6fcf9 100644 --- a/spec/features/add_create_people_skills_spec.rb +++ b/spec/features/add_create_people_skills_spec.rb @@ -5,6 +5,7 @@ let(:person) { people(:bob) } before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit person_people_skills_path(person) click_link text: "Skill hinzufügen" diff --git a/spec/features/advanced_trainings_spec.rb b/spec/features/advanced_trainings_spec.rb index 11ed6981d..8bf641ca4 100644 --- a/spec/features/advanced_trainings_spec.rb +++ b/spec/features/advanced_trainings_spec.rb @@ -4,6 +4,8 @@ let(:person) { people(:bob) } before(:each) do + Capybara.page.driver.browser.manage.window.maximize + set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/auth_spec.rb b/spec/features/auth_spec.rb index 5f7124d2e..e119750ee 100644 --- a/spec/features/auth_spec.rb +++ b/spec/features/auth_spec.rb @@ -4,6 +4,7 @@ context 'Check user privileges' do before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end @@ -23,6 +24,7 @@ context 'Check admin privileges' do before(:each) do + set_env_variables_and_stub_request sign_in(auth_users(:admin)) visit visit people_path end diff --git a/spec/features/core_competences_spec.rb b/spec/features/core_competences_spec.rb index a094c6a63..c2148cb0b 100644 --- a/spec/features/core_competences_spec.rb +++ b/spec/features/core_competences_spec.rb @@ -2,6 +2,7 @@ describe "Core competences" do before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/cv_export_spec.rb b/spec/features/cv_export_spec.rb index d6febe027..08fedf9e8 100644 --- a/spec/features/cv_export_spec.rb +++ b/spec/features/cv_export_spec.rb @@ -2,6 +2,7 @@ describe :people do before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/cv_search_spec.rb b/spec/features/cv_search_spec.rb index d44ed7908..a56e88d4a 100644 --- a/spec/features/cv_search_spec.rb +++ b/spec/features/cv_search_spec.rb @@ -5,6 +5,7 @@ let(:person) { people(:bob) } before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:admin) visit("/cv_search") end diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index 13a30b28d..2ec46e013 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -5,6 +5,7 @@ let(:person) { people(:bob) } before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -119,6 +120,8 @@ def not_rated_default_skills(person) let(:bob) { people(:bob) } before(:each) do + Capybara.page.driver.browser.manage.window.maximize + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit person_people_skills_path(bob, rating: 1) end diff --git a/spec/features/educations_spec.rb b/spec/features/educations_spec.rb index 9eea45190..de747f570 100644 --- a/spec/features/educations_spec.rb +++ b/spec/features/educations_spec.rb @@ -4,6 +4,8 @@ let(:person) { people(:bob) } before(:each) do + Capybara.page.driver.browser.manage.window.maximize + set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/people_show_spec.rb b/spec/features/people_show_spec.rb index a3304fed8..a548cb311 100644 --- a/spec/features/people_show_spec.rb +++ b/spec/features/people_show_spec.rb @@ -2,6 +2,7 @@ describe 'People skills Show', type: :feature, js: true do before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index b9d022776..67e16ea95 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -1,69 +1,11 @@ require 'rails_helper' -ptime_base_test_url = "www.ptime.example.com" -ptime_api_test_username = "test username" -ptime_api_test_password = "test password" -ENV["PTIME_BASE_URL"] = ptime_base_test_url -ENV["PTIME_API_USERNAME"] = ptime_api_test_username -ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - describe :people do describe 'People Search', type: :feature, js: true do - employees_json = { - 'data' => [ - { - 'id' => 33, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'LSM', - 'firstname' => 'Longmax', - 'lastname' => 'Smith', - 'email' => 'longmax@example.com', - 'marital_status' => 'single', - 'nationalities' => ['ZW'], - 'graduation' => 'BSc in Architecture', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - }, - { - 'id' => 21, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'AMA', - 'firstname' => 'Alice', - 'lastname' => 'Mante', - 'full_name' => 'Alice Mante', - 'email' => 'alice@example.com', - 'marital_status' => 'single', - 'nationalities' => ['AU'], - 'graduation' => 'MSc in writing', - 'department_shortname' => 'SYS', - 'employment_roles' => [], - 'is_employed' => false, - 'birthdate' => '01.04.2001', - 'location' => 'Bern' - } - }, - { - 'id' => 45, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'CFO', - 'firstname' => 'Charlie', - 'lastname' => 'Ford', - 'email' => 'charlie@example.com', - 'marital_status' => 'married', - 'nationalities' => ['GB'], - 'graduation' => 'MSc in networking', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - } - ] - }.to_json before(:each) do + set_env_variables_and_stub_request + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s sign_in auth_users(:user), scope: :auth_user end @@ -114,9 +56,6 @@ alice = people(:alice) alice.ptime_employee_id = 21 alice.save! - stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) visit people_path select_from_slim_select("#person_id_person", alice.name) expect(page).to have_current_path(person_path(alice)) @@ -265,6 +204,8 @@ def add_language(language) describe 'Edit person', type: :feature, js: true do before(:each) do + Capybara.page.driver.browser.manage.window.maximize + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -349,6 +290,7 @@ def add_language(language) describe 'Create person', type: :feature, js: true do before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -382,6 +324,7 @@ def add_language(language) let(:longmax) { people(:longmax) } before(:each) do + set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/support/people_skills_helper.rb b/spec/support/people_skills_helper.rb index 46e72bc35..b431e392f 100644 --- a/spec/support/people_skills_helper.rb +++ b/spec/support/people_skills_helper.rb @@ -44,6 +44,7 @@ def validate_skill_level_label(level) end def validate_interest(interest) + require "pry"; binding.pry star_labels = page.find_all("label[id^='star']", visible: false).to_a.reverse star_labels.each_with_index do |label, index| body = page.document.find('body') From 456f27b606da3602ee4cdfe187855fe00e8b9437 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 17 Jul 2024 16:32:27 +0200 Subject: [PATCH 52/79] Fix last test and remove pry --- spec/features/edit_people_skills_spec.rb | 1 + spec/support/people_skills_helper.rb | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index 2ec46e013..b1192c1b8 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -5,6 +5,7 @@ let(:person) { people(:bob) } before(:each) do + Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/support/people_skills_helper.rb b/spec/support/people_skills_helper.rb index b431e392f..46e72bc35 100644 --- a/spec/support/people_skills_helper.rb +++ b/spec/support/people_skills_helper.rb @@ -44,7 +44,6 @@ def validate_skill_level_label(level) end def validate_interest(interest) - require "pry"; binding.pry star_labels = page.find_all("label[id^='star']", visible: false).to_a.reverse star_labels.each_with_index do |label, index| body = page.document.find('body') From 4718e92e5bddc0607df8928f0d44763bebb74ac0 Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 18 Jul 2024 14:09:36 +0200 Subject: [PATCH 53/79] Fix test and add comment --- spec/features/edit_people_skills_spec.rb | 1 + spec/features/people_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index b1192c1b8..f841f7387 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -34,6 +34,7 @@ within("#default-skill-#{ember.skill.id}") do select_star_rating(2) select_level(3, "person[people_skills_attributes][0][level]") + find('#person_people_skills_attributes_0_certificate').hover end # Check if changes were saved diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 67e16ea95..14313b4fd 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -5,7 +5,7 @@ before(:each) do set_env_variables_and_stub_request - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s # This is needed to activate the fallback and still test for the skills people sign_in auth_users(:user), scope: :auth_user end @@ -204,7 +204,7 @@ def add_language(language) describe 'Edit person', type: :feature, js: true do before(:each) do - Capybara.page.driver.browser.manage.window.maximize + # Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end From bf771aa302f8549b8ec23044ab38b68c1e4054a4 Mon Sep 17 00:00:00 2001 From: Manuel Date: Thu, 18 Jul 2024 14:39:44 +0200 Subject: [PATCH 54/79] Generalize window resizing of capybara --- spec/features/activities_spec.rb | 1 - spec/features/advanced_trainings_spec.rb | 1 - spec/features/edit_people_skills_spec.rb | 2 -- spec/features/educations_spec.rb | 1 - spec/features/people_spec.rb | 1 - spec/features/profile_scroll_to_spec.rb | 1 - spec/rails_helper.rb | 4 ++++ 7 files changed, 4 insertions(+), 7 deletions(-) diff --git a/spec/features/activities_spec.rb b/spec/features/activities_spec.rb index 8441ecd0f..2957106b6 100644 --- a/spec/features/activities_spec.rb +++ b/spec/features/activities_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) diff --git a/spec/features/advanced_trainings_spec.rb b/spec/features/advanced_trainings_spec.rb index 8bf641ca4..3baa6adb8 100644 --- a/spec/features/advanced_trainings_spec.rb +++ b/spec/features/advanced_trainings_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index f841f7387..f44ad48e2 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -5,7 +5,6 @@ let(:person) { people(:bob) } before(:each) do - Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -122,7 +121,6 @@ def not_rated_default_skills(person) let(:bob) { people(:bob) } before(:each) do - Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit person_people_skills_path(bob, rating: 1) diff --git a/spec/features/educations_spec.rb b/spec/features/educations_spec.rb index de747f570..e6ea8ce06 100644 --- a/spec/features/educations_spec.rb +++ b/spec/features/educations_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 14313b4fd..10d935c73 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -204,7 +204,6 @@ def add_language(language) describe 'Edit person', type: :feature, js: true do before(:each) do - # Capybara.page.driver.browser.manage.window.maximize set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/features/profile_scroll_to_spec.rb b/spec/features/profile_scroll_to_spec.rb index ca99864d6..f227eb7c4 100644 --- a/spec/features/profile_scroll_to_spec.rb +++ b/spec/features/profile_scroll_to_spec.rb @@ -6,7 +6,6 @@ before(:each) do sign_in auth_users(:user), scope: :auth_user visit root_path - Capybara.page.driver.browser.manage.window.maximize end it 'Should change background of selected section' do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index bc7f2fca6..66bdf0270 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -45,6 +45,10 @@ self.class.fixtures :all end + config.before(:each, js: true) do + Capybara.page.current_window.resize_to(1920, 1080) + end + if Bullet.enable? config.before(:each) do Bullet.start_request From 189ab8009c1f7676c06236102775726300fb1bd6 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 19 Jul 2024 10:37:31 +0200 Subject: [PATCH 55/79] Cleanup code and add comments --- app/domain/ptime/client.rb | 1 + app/helpers/person_helper.rb | 1 + .../20240701085558_create_delayed_jobs.rb | 22 ----- spec/domain/ptime/assign_employee_ids_spec.rb | 83 ++----------------- spec/domain/ptime/client_spec.rb | 60 +------------- spec/features/people_spec.rb | 2 +- 6 files changed, 11 insertions(+), 158 deletions(-) delete mode 100644 db/migrate/20240701085558_create_delayed_jobs.rb diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 2dd72f743..173c59b94 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -22,6 +22,7 @@ def request(method, endpoint, params = {}) private + # Currently not in use can be removed def response_error_message(exception) JSON.parse(exception.response.body).dig('error', 'message') rescue JSON::ParserError # rescue only JSON parsing errors diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 61bf95bbb..84618f3b3 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -107,6 +107,7 @@ def map_ptime_employee_id(ptime_employee) ptime_employee_id_map[ptime_employee['id'].to_s] end + # Once https://github.com/puzzle/skills/issues/744 is merged there should be no need for this def append_ptime_employee_name(ptime_employee) "#{ptime_employee['attributes']['firstname']} #{ptime_employee['attributes']['lastname']}" end diff --git a/db/migrate/20240701085558_create_delayed_jobs.rb b/db/migrate/20240701085558_create_delayed_jobs.rb deleted file mode 100644 index c3ce5afc9..000000000 --- a/db/migrate/20240701085558_create_delayed_jobs.rb +++ /dev/null @@ -1,22 +0,0 @@ -class CreateDelayedJobs < ActiveRecord::Migration[7.0] - def self.up - create_table :delayed_jobs do |table| - table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue - table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. - table.text :handler, null: false # YAML-encoded string of the object that will do work - table.text :last_error # reason for last failure (See Note below) - table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. - table.datetime :locked_at # Set when a client is working on this object - table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) - table.string :locked_by # Who is working on this object (if locked) - table.string :queue # The name of the queue this job is in - table.timestamps null: true - end - - add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" - end - - def self.down - drop_table :delayed_jobs - end -end diff --git a/spec/domain/ptime/assign_employee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb index 1e7e7a462..5fd7e22b8 100644 --- a/spec/domain/ptime/assign_employee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -1,74 +1,11 @@ require 'rails_helper' -ptime_base_test_url = "www.ptime.example.com" -ptime_api_test_username = "test username" -ptime_api_test_password = "test password" -ENV["PTIME_BASE_URL"] = ptime_base_test_url -ENV["PTIME_API_USERNAME"] = ptime_api_test_username -ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - describe Ptime::AssignEmployeeIds do - employees_json = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'LSM', - 'firstname': 'Longmax', - 'lastname': 'Smith', - 'email': 'longmax@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'BSc in Architecture', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 21, - 'type': 'employee', - 'attributes': { - 'shortname': 'AMA', - 'firstname': 'Alice', - 'lastname': 'Mante', - 'email': 'alice@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'AU' - ], - 'graduation': 'MSc in writing', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 45, - 'type': 'employee', - 'attributes': { - 'shortname': 'CFO', - 'firstname': 'Charlie', - 'lastname': 'Ford', - 'email': 'charlie@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'GB' - ], - 'graduation': 'MSc in networking', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - ] - }.to_json + before(:each) do + set_env_variables_and_stub_request + end it 'should map people with the correct puzzletime id' do - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - person_longmax = people(:longmax) person_alice = people(:alice) person_charlie = people(:charlie) @@ -81,12 +18,12 @@ end it 'should not map people that are not found' do - parsed_employees_json = JSON.parse(employees_json) + parsed_employees_json = JSON.parse(return_ptime_employees_json) parsed_employees_json['data'].first["attributes"]["firstname"] = "Rochus" parsed_employees_json['data'].second["attributes"]["firstname"] = "Melchior" - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). + stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees?per_page=1000"). to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) person_longmax = people(:longmax) person_alice = people(:alice) @@ -100,10 +37,6 @@ end it 'should not map people that are ambiguous' do - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - person_longmax = people(:longmax) person_alice = people(:alice) person_charlie = people(:charlie) @@ -120,10 +53,6 @@ end it 'should not map people on dry run' do - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - person_longmax = people(:longmax) person_alice = people(:alice) person_charlie = people(:charlie) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 4b60f1b4d..26945e7ab 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -8,68 +8,12 @@ ENV["PTIME_API_PASSWORD"] = ptime_api_test_password describe Ptime::Client do - employees_json = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'LSM', - 'firstname': 'Longmax', - 'lastname': 'Smith', - 'email': 'longmax@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'BSc in Architecture', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 21, - 'type': 'employee', - 'attributes': { - 'shortname': 'AMA', - 'firstname': 'Alice', - 'lastname': 'Mante', - 'email': 'alice@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'AU' - ], - 'graduation': 'MSc in writing', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 45, - 'type': 'employee', - 'attributes': { - 'shortname': 'CFO', - 'firstname': 'Charlie', - 'lastname': 'Ford', - 'email': 'charlie@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'GB' - ], - 'graduation': 'MSc in networking', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - ] - }.to_json - it 'should be able to fetch employee data' do stub_request(:get, "#{ptime_base_test_url}/api/v1/employees"). - to_return(body: employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) + to_return(body: return_ptime_employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) fetched_employees = Ptime::Client.new.request(:get, "employees") - expect(fetched_employees).to eq(JSON.parse(employees_json)) + expect(fetched_employees).to eq(JSON.parse(return_ptime_employees_json)) end end diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 10d935c73..8015ccd58 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -5,7 +5,7 @@ before(:each) do set_env_variables_and_stub_request - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s # This is needed to activate the fallback and still test for the skills people + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s # This is needed to activate the fallback and test for the skills people sign_in auth_users(:user), scope: :auth_user end From 2e2ae6b48b0c1767a0091505b6f1ed728f938b95 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 19 Jul 2024 12:49:30 +0200 Subject: [PATCH 56/79] Add one more test for client.rb --- spec/domain/ptime/client_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 26945e7ab..b6e03cb4b 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -16,4 +16,12 @@ fetched_employees = Ptime::Client.new.request(:get, "employees") expect(fetched_employees).to eq(JSON.parse(return_ptime_employees_json)) end + + it 'should fallback to skills if last request was right now' do + ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s + + skills_people = Ptime::Client.new.request(:get, "employees") + + expect(ENV['PTIME_API_ACCESSIBLE']).to eq('false') + end end From 766e9423f80f5c3169a3afb58e01ad22b199d304 Mon Sep 17 00:00:00 2001 From: Manuel Date: Fri, 19 Jul 2024 13:15:14 +0200 Subject: [PATCH 57/79] Reverse test from last commit --- spec/domain/ptime/client_spec.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index b6e03cb4b..26945e7ab 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -16,12 +16,4 @@ fetched_employees = Ptime::Client.new.request(:get, "employees") expect(fetched_employees).to eq(JSON.parse(return_ptime_employees_json)) end - - it 'should fallback to skills if last request was right now' do - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s - - skills_people = Ptime::Client.new.request(:get, "employees") - - expect(ENV['PTIME_API_ACCESSIBLE']).to eq('false') - end end From aa36e826b5ccbb9e7619a2bc2f328fdd5f21b9f4 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 09:06:31 +0200 Subject: [PATCH 58/79] change location of helper --- app/controllers/people/people_skills_create_controller.rb | 6 ------ app/controllers/people_controller.rb | 6 ------ app/helpers/auth_helper.rb | 4 ++++ 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/app/controllers/people/people_skills_create_controller.rb b/app/controllers/people/people_skills_create_controller.rb index 287c8ded6..1c7430fb5 100644 --- a/app/controllers/people/people_skills_create_controller.rb +++ b/app/controllers/people/people_skills_create_controller.rb @@ -8,8 +8,6 @@ class People::PeopleSkillsCreateController < CrudController self.nesting = Person layout 'person' - helper_method :ptime_broken? - def index return super if params[:rating].present? @@ -46,8 +44,4 @@ def filter_by_rating(people_skills, rating) def self.controller_path 'people/people_skills' end - - def ptime_broken? - !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) - end end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index b47a5b3d7..6d1fed1b8 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -5,8 +5,6 @@ class PeopleController < CrudController include ParamConverters include PeopleControllerConcerns - helper_method :ptime_broken? - self.permitted_attrs = [:birthdate, :location, :marital_status, :updated_by, :name, :nationality, :nationality2, :title, :competence_notes, :company_id, :email, :department_id, :shortname, :picture, :picture_cache, @@ -62,10 +60,6 @@ def export disposition: content_disposition('attachment', filename) end - def ptime_broken? - !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) - end - private def fetch_entries diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index 2d98e159f..b5e216197 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -21,4 +21,8 @@ def find_person_by_auth_user def devise? AuthConfig.keycloak? || Rails.env.test? end + + def ptime_broken? + !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + end end From 4153a5ba4158074d6e2d1c7ab8fecf367d313ae3 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 09:24:57 +0200 Subject: [PATCH 59/79] set ptime stubing global --- spec/domain/ptime/assign_employee_ids_spec.rb | 3 --- spec/features/activities_spec.rb | 1 - spec/features/add_create_people_skills_spec.rb | 1 - spec/features/advanced_trainings_spec.rb | 1 - spec/features/auth_spec.rb | 2 -- spec/features/core_competences_spec.rb | 1 - spec/features/cv_export_spec.rb | 1 - spec/features/cv_search_spec.rb | 1 - spec/features/edit_people_skills_spec.rb | 2 -- spec/features/educations_spec.rb | 1 - spec/features/people_show_spec.rb | 1 - spec/features/people_spec.rb | 4 ---- spec/helpers/person_helper_spec.rb | 3 +-- spec/rails_helper.rb | 4 ++++ 14 files changed, 5 insertions(+), 21 deletions(-) diff --git a/spec/domain/ptime/assign_employee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb index 5fd7e22b8..50a948a9a 100644 --- a/spec/domain/ptime/assign_employee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -1,9 +1,6 @@ require 'rails_helper' describe Ptime::AssignEmployeeIds do - before(:each) do - set_env_variables_and_stub_request - end it 'should map people with the correct puzzletime id' do person_longmax = people(:longmax) diff --git a/spec/features/activities_spec.rb b/spec/features/activities_spec.rb index 2957106b6..56415ca3a 100644 --- a/spec/features/activities_spec.rb +++ b/spec/features/activities_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/add_create_people_skills_spec.rb b/spec/features/add_create_people_skills_spec.rb index 7ecd6fcf9..cd6ef498b 100644 --- a/spec/features/add_create_people_skills_spec.rb +++ b/spec/features/add_create_people_skills_spec.rb @@ -5,7 +5,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit person_people_skills_path(person) click_link text: "Skill hinzufügen" diff --git a/spec/features/advanced_trainings_spec.rb b/spec/features/advanced_trainings_spec.rb index 3baa6adb8..11ed6981d 100644 --- a/spec/features/advanced_trainings_spec.rb +++ b/spec/features/advanced_trainings_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/auth_spec.rb b/spec/features/auth_spec.rb index e119750ee..5f7124d2e 100644 --- a/spec/features/auth_spec.rb +++ b/spec/features/auth_spec.rb @@ -4,7 +4,6 @@ context 'Check user privileges' do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end @@ -24,7 +23,6 @@ context 'Check admin privileges' do before(:each) do - set_env_variables_and_stub_request sign_in(auth_users(:admin)) visit visit people_path end diff --git a/spec/features/core_competences_spec.rb b/spec/features/core_competences_spec.rb index c2148cb0b..a094c6a63 100644 --- a/spec/features/core_competences_spec.rb +++ b/spec/features/core_competences_spec.rb @@ -2,7 +2,6 @@ describe "Core competences" do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/cv_export_spec.rb b/spec/features/cv_export_spec.rb index 08fedf9e8..d6febe027 100644 --- a/spec/features/cv_export_spec.rb +++ b/spec/features/cv_export_spec.rb @@ -2,7 +2,6 @@ describe :people do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/cv_search_spec.rb b/spec/features/cv_search_spec.rb index a56e88d4a..d44ed7908 100644 --- a/spec/features/cv_search_spec.rb +++ b/spec/features/cv_search_spec.rb @@ -5,7 +5,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:admin) visit("/cv_search") end diff --git a/spec/features/edit_people_skills_spec.rb b/spec/features/edit_people_skills_spec.rb index f44ad48e2..da178ab78 100644 --- a/spec/features/edit_people_skills_spec.rb +++ b/spec/features/edit_people_skills_spec.rb @@ -5,7 +5,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -121,7 +120,6 @@ def not_rated_default_skills(person) let(:bob) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit person_people_skills_path(bob, rating: 1) end diff --git a/spec/features/educations_spec.rb b/spec/features/educations_spec.rb index e6ea8ce06..9eea45190 100644 --- a/spec/features/educations_spec.rb +++ b/spec/features/educations_spec.rb @@ -4,7 +4,6 @@ let(:person) { people(:bob) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:admin) visit person_path(person) end diff --git a/spec/features/people_show_spec.rb b/spec/features/people_show_spec.rb index a548cb311..a3304fed8 100644 --- a/spec/features/people_show_spec.rb +++ b/spec/features/people_show_spec.rb @@ -2,7 +2,6 @@ describe 'People skills Show', type: :feature, js: true do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user visit root_path end diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 8015ccd58..9cfda38c6 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -4,7 +4,6 @@ describe 'People Search', type: :feature, js: true do before(:each) do - set_env_variables_and_stub_request ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s # This is needed to activate the fallback and test for the skills people sign_in auth_users(:user), scope: :auth_user end @@ -204,7 +203,6 @@ def add_language(language) describe 'Edit person', type: :feature, js: true do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -289,7 +287,6 @@ def add_language(language) describe 'Create person', type: :feature, js: true do before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end @@ -323,7 +320,6 @@ def add_language(language) let(:longmax) { people(:longmax) } before(:each) do - set_env_variables_and_stub_request sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index f007140bf..9072eceab 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -4,7 +4,6 @@ describe '#fetch_ptime_or_skills_data' do it 'should send request to ptime api' do - set_env_variables_and_stub_request fetch_ptime_or_skills_data end @@ -44,4 +43,4 @@ expect(dropdown_data[2][:already_exists]).to be(true) end end -end \ No newline at end of file +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 66bdf0270..f5a7ffb73 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -62,6 +62,10 @@ config.infer_spec_type_from_file_location! + config.before(:each) do + set_env_variables_and_stub_request + end + # Controller helper config.include(JsonMacros, type: :controller) config.include(JsonAssertion, type: :controller) From 87d84d8e9534d82738dd208d2453c2a78f20e6c5 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 09:41:13 +0200 Subject: [PATCH 60/79] clean up ptime client specs --- app/domain/ptime/client.rb | 2 +- spec/domain/ptime/client_spec.rb | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 173c59b94..f84120f39 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -50,7 +50,7 @@ def last_ptime_api_request_more_than_5_minutes def send_request_and_parse_response(method, path, params) ENV['PTIME_API_ACCESSIBLE'] = 'true' - path = "#{path}?#{URI.encode_www_form(params)}" if method == :get + path = "#{path}?#{URI.encode_www_form(params)}" if method == :get && params.present? response = RestClient.send(method, path, headers) JSON.parse(response.body) end diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 26945e7ab..12401112e 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -1,19 +1,8 @@ require 'rails_helper' -ptime_base_test_url = "www.ptime.example.com" -ptime_api_test_username = "test username" -ptime_api_test_password = "test password" -ENV["PTIME_BASE_URL"] = ptime_base_test_url -ENV["PTIME_API_USERNAME"] = ptime_api_test_username -ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - describe Ptime::Client do it 'should be able to fetch employee data' do - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees"). - to_return(body: return_ptime_employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) - - fetched_employees = Ptime::Client.new.request(:get, "employees") + fetched_employees = Ptime::Client.new.request(:get, "employees?per_page=1000") expect(fetched_employees).to eq(JSON.parse(return_ptime_employees_json)) end end From 96391b22c00c9f12ecef3f9c626896fa6a71c358 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 09:59:25 +0200 Subject: [PATCH 61/79] create json file for fixtures --- .../files/json/all_ptime_employees.json | 53 ++++++++++++++++++ spec/rails_helper.rb | 6 +- spec/support/json_helpers.rb | 6 ++ spec/support/ptime_helpers.rb | 56 +------------------ 4 files changed, 66 insertions(+), 55 deletions(-) create mode 100644 spec/fixtures/files/json/all_ptime_employees.json create mode 100644 spec/support/json_helpers.rb diff --git a/spec/fixtures/files/json/all_ptime_employees.json b/spec/fixtures/files/json/all_ptime_employees.json new file mode 100644 index 000000000..685e11445 --- /dev/null +++ b/spec/fixtures/files/json/all_ptime_employees.json @@ -0,0 +1,53 @@ +{ + "data": [ + { + "id" : 33, + "type" : "employee", + "attributes" : { + "shortname" : "LSM", + "firstname" : "Longmax", + "lastname" : "Smith", + "email" : "longmax@example.com", + "marital_status" : "single", + "nationalities" : ["ZW"], + "graduation" : "BSc in Architecture", + "department_shortname" : "SYS", + "employment_roles" : [] + } + }, + { + "id" : 21, + "type" : "employee", + "attributes" : { + "shortname" : "AMA", + "firstname" : "Alice", + "lastname" : "Mante", + "full_name" : "Alice Mante", + "email" : "alice@example.com", + "marital_status" : "single", + "nationalities" : ["AU"], + "graduation" : "MSc in writing", + "department_shortname" : "SYS", + "employment_roles" : [], + "is_employed" : false, + "birthdate" : "01.04.2001", + "location" : "Bern" + } + }, + { + "id" : 45, + "type" : "employee", + "attributes" : { + "shortname" : "CFO", + "firstname" : "Charlie", + "lastname" : "Ford", + "email" : "charlie@example.com", + "marital_status" : "married", + "nationalities" : ["GB"], + "graduation" : "MSc in networking", + "department_shortname" : "SYS", + "employment_roles" : [] + } + } + ] +} \ No newline at end of file diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index f5a7ffb73..dacc6e9ba 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -79,10 +79,14 @@ config.include(ActionView::RecordIdentifier, type: :feature) # Custom helpers + ## Global helpers + config.include(PtimeHelpers) + config.include(JsonHelpers) + + ## Feature helpers config.include(PersonRelationsHelpers, type: :feature) config.include(SlimselectHelpers, type: :feature) config.include(PeopleSkillsHelpers, type: :feature) - config.include(PtimeHelpers) config.infer_spec_type_from_file_location! config.filter_rails_from_backtrace! diff --git a/spec/support/json_helpers.rb b/spec/support/json_helpers.rb new file mode 100644 index 000000000..fa66633ac --- /dev/null +++ b/spec/support/json_helpers.rb @@ -0,0 +1,6 @@ +module JsonHelpers + + def json_data(filename:) + file_fixture("json/#{filename}.json").read + end +end diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index 8bd79203a..cbfda4d06 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -13,58 +13,6 @@ def set_env_variables_and_stub_request end def return_ptime_employees_json - employees_json = { - 'data' => [ - { - 'id' => 33, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'LSM', - 'firstname' => 'Longmax', - 'lastname' => 'Smith', - 'email' => 'longmax@example.com', - 'marital_status' => 'single', - 'nationalities' => ['ZW'], - 'graduation' => 'BSc in Architecture', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - }, - { - 'id' => 21, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'AMA', - 'firstname' => 'Alice', - 'lastname' => 'Mante', - 'full_name' => 'Alice Mante', - 'email' => 'alice@example.com', - 'marital_status' => 'single', - 'nationalities' => ['AU'], - 'graduation' => 'MSc in writing', - 'department_shortname' => 'SYS', - 'employment_roles' => [], - 'is_employed' => false, - 'birthdate' => '01.04.2001', - 'location' => 'Bern' - } - }, - { - 'id' => 45, - 'type' => 'employee', - 'attributes' => { - 'shortname' => 'CFO', - 'firstname' => 'Charlie', - 'lastname' => 'Ford', - 'email' => 'charlie@example.com', - 'marital_status' => 'married', - 'nationalities' => ['GB'], - 'graduation' => 'MSc in networking', - 'department_shortname' => 'SYS', - 'employment_roles' => [] - } - } - ] - }.to_json + json_data filename: "all_ptime_employees" end -end \ No newline at end of file +end From cce291b5e637d887463e15ff7c3318a16532bde8 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 12:03:22 +0200 Subject: [PATCH 62/79] use hashes instead of strings for json keys create global ptime stub method --- app/domain/ptime/assign_employee_ids.rb | 14 +-- app/domain/ptime/client.rb | 3 +- app/domain/ptime/update_people_data.rb | 12 +- app/helpers/person_helper.rb | 10 +- spec/domain/ptime/assign_employee_ids_spec.rb | 8 +- spec/domain/ptime/client_spec.rb | 5 +- spec/domain/ptime/update_people_data_spec.rb | 118 ++---------------- .../files/json/new_ptime_employee.json | 21 ++++ .../files/json/updating_ptime_employees.json | 72 +++++++++++ spec/helpers/person_helper_spec.rb | 4 +- spec/rails_helper.rb | 2 + spec/support/json_helpers.rb | 5 +- spec/support/ptime_helpers.rb | 18 ++- 13 files changed, 152 insertions(+), 140 deletions(-) create mode 100644 spec/fixtures/files/json/new_ptime_employee.json create mode 100644 spec/fixtures/files/json/updating_ptime_employees.json diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index c9ee84a0a..c25518004 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -25,25 +25,25 @@ def map_employees(should_map) mapped_people_count = 0 @ptime_employees.each do |ptime_employee| - ptime_employee_firstname = ptime_employee['attributes']['firstname'] - ptime_employee_lastname = ptime_employee['attributes']['lastname'] + ptime_employee_firstname = ptime_employee[:attributes][:firstname] + ptime_employee_lastname = ptime_employee[:attributes][:lastname] ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" - ptime_employee_email = ptime_employee['attributes']['email'] + ptime_employee_email = ptime_employee[:attributes][:email] matched_skills_people = Person.where(ptime_employee_id: nil) .where(name: ptime_employee_name) .where(email: ptime_employee_email) if matched_skills_people.empty? - unmatched_entries << { name: ptime_employee_name, id: ptime_employee['id'] } + unmatched_entries << { name: ptime_employee_name, id: ptime_employee[:id] } elsif matched_skills_people.one? if should_map matched_skills_person = matched_skills_people.first - matched_skills_person.ptime_employee_id = ptime_employee['id'] + matched_skills_person.ptime_employee_id = ptime_employee[:id] matched_skills_person.save! end mapped_people_count += 1 else - ambiguous_entries << { name: ptime_employee_name, id: ptime_employee['id'] } + ambiguous_entries << { name: ptime_employee_name, id: ptime_employee[:id] } end end @@ -60,7 +60,7 @@ def map_employees(should_map) def fetch_data puts 'Fetching required data...' - @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] + @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] @skills_people = Person.all puts 'Successfully fetched data' end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index f84120f39..f9e528ff0 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -52,12 +52,13 @@ def send_request_and_parse_response(method, path, params) ENV['PTIME_API_ACCESSIBLE'] = 'true' path = "#{path}?#{URI.encode_www_form(params)}" if method == :get && params.present? response = RestClient.send(method, path, headers) - JSON.parse(response.body) + JSON.parse(response.body, symbolize_names: true) end def skills_database_request ENV['PTIME_API_ACCESSIBLE'] = 'false' ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s + {} end end end diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 24eb88558..1edcf2de5 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -7,18 +7,18 @@ class UpdatePeopleData # rubocop:disable Metrics def run - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] ptime_employees.each do |ptime_employee| - ptime_employee_firstname = ptime_employee['attributes']['firstname'] - ptime_employee_lastname = ptime_employee['attributes']['lastname'] + ptime_employee_firstname = ptime_employee[:attributes][:firstname] + ptime_employee_lastname = ptime_employee[:attributes][:lastname] ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" - skills_person = Person.find_by(ptime_employee_id: ptime_employee['id']) + skills_person = Person.find_by(ptime_employee_id: ptime_employee[:id]) skills_person ||= Person.new skills_person.name = ptime_employee_name - skills_person.ptime_employee_id ||= ptime_employee['id'] - ptime_employee['attributes'].each do |key, value| + skills_person.ptime_employee_id ||= ptime_employee[:id] + ptime_employee[:attributes].each do |key, value| if key.to_sym.in?(ATTRIBUTE_MAPPING.keys) skills_person[ATTRIBUTE_MAPPING[key.to_sym]] = value end diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 84618f3b3..23fc3456b 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -78,7 +78,7 @@ def not_rated_default_skills(person) end def fetch_ptime_or_skills_data - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })['data'] + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] all_skills_people = Person.all return all_skills_people if ENV['PTIME_API_ACCESSIBLE'] == 'false' @@ -92,9 +92,9 @@ def build_dropdown_data(ptime_employees, ptime_employee_ids) person_id = map_ptime_employee_id(ptime_employee) { id: person_id, - ptime_employee_id: ptime_employee['id'], + ptime_employee_id: ptime_employee[:id], name: ptime_employee_name, - already_exists: ptime_employee['id'].in?(ptime_employee_ids) + already_exists: ptime_employee[:id].in?(ptime_employee_ids) } end end @@ -104,11 +104,11 @@ def map_ptime_employee_id(ptime_employee) hash[person.ptime_employee_id.to_s] = person.id end - ptime_employee_id_map[ptime_employee['id'].to_s] + ptime_employee_id_map[ptime_employee[:id].to_s] end # Once https://github.com/puzzle/skills/issues/744 is merged there should be no need for this def append_ptime_employee_name(ptime_employee) - "#{ptime_employee['attributes']['firstname']} #{ptime_employee['attributes']['lastname']}" + "#{ptime_employee[:attributes][:firstname]} #{ptime_employee[:attributes][:lastname]}" end end diff --git a/spec/domain/ptime/assign_employee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb index 50a948a9a..464260b13 100644 --- a/spec/domain/ptime/assign_employee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -15,9 +15,11 @@ end it 'should not map people that are not found' do - parsed_employees_json = JSON.parse(return_ptime_employees_json) - parsed_employees_json['data'].first["attributes"]["firstname"] = "Rochus" - parsed_employees_json['data'].second["attributes"]["firstname"] = "Melchior" + parsed_employees_json = ptime_employees + parsed_employees_json[:data].first[:attributes][:firstname] = "Rochus" + parsed_employees_json[:data].second[:attributes][:firstname] = "Melchior" + + stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees?per_page=1000"). to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 12401112e..98cedb545 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -2,7 +2,8 @@ describe Ptime::Client do it 'should be able to fetch employee data' do - fetched_employees = Ptime::Client.new.request(:get, "employees?per_page=1000") - expect(fetched_employees).to eq(JSON.parse(return_ptime_employees_json)) + fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) + ptime_employee_json = fixture_data("all_ptime_employees") + expect(fetched_employees).to eq(ptime_employee_json) end end diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index 45d6fd365..fa345dfe9 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -12,82 +12,9 @@ end it 'should update the data of existing people after mapping' do - employees = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'LSM', - 'firstname': 'Longmax', - 'lastname': 'Smith', - 'email': 'longmax@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'BSc in Architecture', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 21, - 'type': 'employee', - 'attributes': { - 'shortname': 'AMA', - 'firstname': 'Alice', - 'lastname': 'Mante', - 'email': 'alice@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'AU' - ], - 'graduation': 'MSc in writing', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 45, - 'type': 'employee', - 'attributes': { - 'shortname': 'CFO', - 'firstname': 'Charlie', - 'lastname': 'Ford', - 'email': 'charlie@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'GB' - ], - 'graduation': 'MSc in networking', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - { - 'id': 50, - 'type': 'employee', - 'attributes': { - 'shortname': 'WAL', - 'firstname': 'Wally', - 'lastname': 'Allround', - 'email': 'wally@example.com', - 'marital_status': 'married', - 'nationalities': [ - 'US' - ], - 'graduation': 'Full-Stack Developer', - 'department_shortname': 'SYS', - 'employment_roles': [] - } - }, - ] - } + employees = fixture_data "updating_ptime_employees" - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + stub_ptime_request(employees.to_json) person_longmax = people(:longmax) person_alice = people(:alice) @@ -95,15 +22,14 @@ person_wally = people(:wally) Ptime::AssignEmployeeIds.new.run(should_map: true) + employees_data = employees[:data] + employees_data.first[:attributes][:email] = "changedmax@example.com" + employees_data.second[:attributes][:graduation] = "MSc in some other field" + employees_data.third[:attributes][:firstname] = "Claudius" + employees_data.fourth[:attributes][:marital_status] = "single" - employees[:data].first[:attributes][:email] = "changedmax@example.com" - employees[:data].second[:attributes][:graduation] = "MSc in some other field" - employees[:data].third[:attributes][:firstname] = "Claudius" - employees[:data].fourth[:attributes][:marital_status] = "single" - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: employees.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + stub_ptime_request(employees.to_json) Ptime::UpdatePeopleData.new.run @@ -114,31 +40,9 @@ end it 'should create new person when person does not exist' do - new_employee = { - 'data': [ - { - 'id': 33, - 'type': 'employee', - 'attributes': { - 'shortname': 'PFI', - 'firstname': 'Peterson', - 'lastname': 'Findus', - 'email': 'peterson@example.com', - 'marital_status': 'single', - 'nationalities': [ - 'ZW' - ], - 'graduation': 'Cat caretaker', - 'department_shortname': 'CAT', - 'employment_roles': [] - } - } - ] - } + new_employee = fixture_data "new_ptime_employee" - stub_request(:get, "#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: new_employee.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + stub_ptime_request(new_employee.to_json) Ptime::AssignEmployeeIds.new.run(should_map: true) Ptime::UpdatePeopleData.new.run @@ -158,4 +62,4 @@ expect(created_person.location).to eq('Bern') expect(created_person.nationality).to eq('CH') end -end \ No newline at end of file +end diff --git a/spec/fixtures/files/json/new_ptime_employee.json b/spec/fixtures/files/json/new_ptime_employee.json new file mode 100644 index 000000000..308d4fcb4 --- /dev/null +++ b/spec/fixtures/files/json/new_ptime_employee.json @@ -0,0 +1,21 @@ +{ + "data": [ + { + "id": 33, + "type": "employee", + "attributes": { + "shortname": "PFI", + "firstname": "Peterson", + "lastname": "Findus", + "email": "peterson@example.com", + "marital_status": "single", + "nationalities": [ + "ZW" + ], + "graduation": "Cat caretaker", + "department_shortname": "CAT", + "employment_roles": [] + } + } + ] + } \ No newline at end of file diff --git a/spec/fixtures/files/json/updating_ptime_employees.json b/spec/fixtures/files/json/updating_ptime_employees.json new file mode 100644 index 000000000..14be70aba --- /dev/null +++ b/spec/fixtures/files/json/updating_ptime_employees.json @@ -0,0 +1,72 @@ +{ + "data": [ + { + "id": 33, + "type": "employee", + "attributes": { + "shortname": "LSM", + "firstname": "Longmax", + "lastname": "Smith", + "email": "longmax@example.com", + "marital_status": "single", + "nationalities": [ + "ZW" + ], + "graduation": "BSc in Architecture", + "department_shortname": "SYS", + "employment_roles": [] + } + }, + { + "id": 21, + "type": "employee", + "attributes": { + "shortname": "AMA", + "firstname": "Alice", + "lastname": "Mante", + "email": "alice@example.com", + "marital_status": "single", + "nationalities": [ + "AU" + ], + "graduation": "MSc in writing", + "department_shortname": "SYS", + "employment_roles": [] + } + }, + { + "id": 45, + "type": "employee", + "attributes": { + "shortname": "CFO", + "firstname": "Charlie", + "lastname": "Ford", + "email": "charlie@example.com", + "marital_status": "married", + "nationalities": [ + "GB" + ], + "graduation": "MSc in networking", + "department_shortname": "SYS", + "employment_roles": [] + } + }, + { + "id": 50, + "type": "employee", + "attributes": { + "shortname": "WAL", + "firstname": "Wally", + "lastname": "Allround", + "email": "wally@example.com", + "marital_status": "married", + "nationalities": [ + "US" + ], + "graduation": "Full-Stack Developer", + "department_shortname": "SYS", + "employment_roles": [] + } + } + ] + } \ No newline at end of file diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index 9072eceab..e5c2d93bb 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -24,8 +24,8 @@ alice.update!(ptime_employee_id: 21) charlie.update!(ptime_employee_id: 45) - parsed_employees = JSON.parse(return_ptime_employees_json) - dropdown_data = build_dropdown_data(parsed_employees['data'], Person.all.pluck(:ptime_employee_id)) + parsed_employees = ptime_employees + dropdown_data = build_dropdown_data(parsed_employees[:data], Person.all.pluck(:ptime_employee_id)) expect(dropdown_data[0][:id]).to eq(longmax.id) expect(dropdown_data[0][:ptime_employee_id]).to eq(longmax.ptime_employee_id) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index dacc6e9ba..4e8d29fe8 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -66,6 +66,8 @@ set_env_variables_and_stub_request end + config.before { allow($stdout).to receive(:puts) } + # Controller helper config.include(JsonMacros, type: :controller) config.include(JsonAssertion, type: :controller) diff --git a/spec/support/json_helpers.rb b/spec/support/json_helpers.rb index fa66633ac..66c213946 100644 --- a/spec/support/json_helpers.rb +++ b/spec/support/json_helpers.rb @@ -1,6 +1,7 @@ module JsonHelpers - def json_data(filename:) - file_fixture("json/#{filename}.json").read + def fixture_data(filename, symbolize_names= true) + file_content= file_fixture("json/#{filename}.json").read + JSON.parse(file_content, symbolize_names: symbolize_names) end end diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index cbfda4d06..45aa3fd41 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -7,12 +7,20 @@ def set_env_variables_and_stub_request ENV["PTIME_API_USERNAME"] = ptime_api_test_username ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - stub_request(:get, "http://#{ptime_base_test_url}/api/v1/employees?per_page=1000"). - to_return(body: return_ptime_employees_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ptime_api_test_username, ptime_api_test_password]) + stub_ptime_request(ptime_employees.to_json) end - def return_ptime_employees_json - json_data filename: "all_ptime_employees" + def ptime_employees + fixture_data "all_ptime_employees" + end + + def stub_ptime_request(return_body, path =nil) + path ||= "employees?per_page=1000" + url = "http://#{ENV["PTIME_BASE_URL"]}/api/v1/#{path}" + content_type = "application/vnd.api+json; charset=utf-8" + + stub_request(:get, url) + .to_return(body: return_body, headers: { 'content-type': content_type }, status: 200) + .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) end end From d3bb9c3d28e93b5bf353cd74a3d5b337e0fbcf09 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 12:15:17 +0200 Subject: [PATCH 63/79] use custom ptime stubbing method everywhere --- spec/domain/ptime/assign_employee_ids_spec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/domain/ptime/assign_employee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb index 464260b13..3e8f01a6c 100644 --- a/spec/domain/ptime/assign_employee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -20,9 +20,7 @@ parsed_employees_json[:data].second[:attributes][:firstname] = "Melchior" - stub_request(:get, "#{ENV["PTIME_BASE_URL"]}/api/v1/employees?per_page=1000"). - to_return(body: parsed_employees_json.to_json, headers: { 'content-type': "application/vnd.api+json; charset=utf-8" }, status: 200) - .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) + stub_ptime_request(parsed_employees_json.to_json) person_longmax = people(:longmax) person_alice = people(:alice) From dd969005648b47201586af566c5a2058e1e50e1a Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 12:37:05 +0200 Subject: [PATCH 64/79] fix tests after always using [:data] --- app/domain/ptime/assign_employee_ids.rb | 2 +- app/domain/ptime/client.rb | 2 +- app/domain/ptime/update_people_data.rb | 2 +- app/helpers/person_helper.rb | 2 +- spec/domain/ptime/client_spec.rb | 3 +-- spec/domain/ptime/update_people_data_spec.rb | 15 +++++++-------- spec/helpers/person_helper_spec.rb | 3 +-- spec/support/ptime_helpers.rb | 6 +++++- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index c25518004..b916ad6fc 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -60,7 +60,7 @@ def map_employees(should_map) def fetch_data puts 'Fetching required data...' - @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] + @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) @skills_people = Person.all puts 'Successfully fetched data' end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index f9e528ff0..0dc50d13a 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -52,7 +52,7 @@ def send_request_and_parse_response(method, path, params) ENV['PTIME_API_ACCESSIBLE'] = 'true' path = "#{path}?#{URI.encode_www_form(params)}" if method == :get && params.present? response = RestClient.send(method, path, headers) - JSON.parse(response.body, symbolize_names: true) + JSON.parse(response.body, symbolize_names: true)[:data] end def skills_database_request diff --git a/app/domain/ptime/update_people_data.rb b/app/domain/ptime/update_people_data.rb index 1edcf2de5..b785f1f0e 100644 --- a/app/domain/ptime/update_people_data.rb +++ b/app/domain/ptime/update_people_data.rb @@ -7,7 +7,7 @@ class UpdatePeopleData # rubocop:disable Metrics def run - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) ptime_employees.each do |ptime_employee| ptime_employee_firstname = ptime_employee[:attributes][:firstname] ptime_employee_lastname = ptime_employee[:attributes][:lastname] diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 23fc3456b..59dd9e568 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -78,7 +78,7 @@ def not_rated_default_skills(person) end def fetch_ptime_or_skills_data - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 })[:data] + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) all_skills_people = Person.all return all_skills_people if ENV['PTIME_API_ACCESSIBLE'] == 'false' diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 98cedb545..4f0af30a2 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -3,7 +3,6 @@ describe Ptime::Client do it 'should be able to fetch employee data' do fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) - ptime_employee_json = fixture_data("all_ptime_employees") - expect(fetched_employees).to eq(ptime_employee_json) + expect(fetched_employees).to eq(ptime_employees_data) end end diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index fa345dfe9..8e3273f85 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -22,11 +22,10 @@ person_wally = people(:wally) Ptime::AssignEmployeeIds.new.run(should_map: true) - employees_data = employees[:data] - employees_data.first[:attributes][:email] = "changedmax@example.com" - employees_data.second[:attributes][:graduation] = "MSc in some other field" - employees_data.third[:attributes][:firstname] = "Claudius" - employees_data.fourth[:attributes][:marital_status] = "single" + employees[:data].first[:attributes][:email] = "changedmax@example.com" + employees[:data].second[:attributes][:graduation] = "MSc in some other field" + employees[:data].third[:attributes][:firstname] = "Claudius" + employees[:data].fourth[:attributes][:marital_status] = "single" stub_ptime_request(employees.to_json) @@ -41,17 +40,17 @@ it 'should create new person when person does not exist' do new_employee = fixture_data "new_ptime_employee" - + new_employee_data = new_employee[:data] stub_ptime_request(new_employee.to_json) Ptime::AssignEmployeeIds.new.run(should_map: true) Ptime::UpdatePeopleData.new.run - new_employee_attributes = new_employee[:data].first[:attributes] + new_employee_attributes = new_employee_data.first[:attributes] new_employee_name = "#{new_employee_attributes[:firstname]} #{new_employee_attributes[:lastname]}" created_person = Person.find_by(name: new_employee_name) expect(created_person).not_to be_nil - expect(created_person.ptime_employee_id).to eq(new_employee[:data].first[:id]) + expect(created_person.ptime_employee_id).to eq(new_employee_data.first[:id]) expect(created_person.shortname).to eq(new_employee_attributes[:shortname]) expect(created_person.name).to eq(new_employee_name) expect(created_person.email).to eq(new_employee_attributes[:email]) diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index e5c2d93bb..1503d152c 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -24,8 +24,7 @@ alice.update!(ptime_employee_id: 21) charlie.update!(ptime_employee_id: 45) - parsed_employees = ptime_employees - dropdown_data = build_dropdown_data(parsed_employees[:data], Person.all.pluck(:ptime_employee_id)) + dropdown_data = build_dropdown_data(ptime_employees_data, Person.all.pluck(:ptime_employee_id)) expect(dropdown_data[0][:id]).to eq(longmax.id) expect(dropdown_data[0][:ptime_employee_id]).to eq(longmax.ptime_employee_id) diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index 45aa3fd41..aee588ad5 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -11,7 +11,11 @@ def set_env_variables_and_stub_request end def ptime_employees - fixture_data "all_ptime_employees" + fixture_data("all_ptime_employees") + end + + def ptime_employees_data + fixture_data("all_ptime_employees")[:data] end def stub_ptime_request(return_body, path =nil) From 0d1c4ff67d160bd4ccb1f7b8468b9a84fdfcf5eb Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 13:16:08 +0200 Subject: [PATCH 65/79] clean up ptime client --- app/domain/ptime/client.rb | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 0dc50d13a..548133572 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -29,18 +29,6 @@ def response_error_message(exception) nil end - def headers - { - authorization: "Basic #{basic_token}", - content_type: :json, - accept: :json - } - end - - def basic_token - Base64.encode64("#{ENV.fetch('PTIME_API_USERNAME')}:#{ENV.fetch('PTIME_API_PASSWORD')}") - end - def last_ptime_api_request_more_than_5_minutes last_request_time = ENV.fetch('LAST_PTIME_API_REQUEST', nil) return true if last_request_time.nil? @@ -48,10 +36,20 @@ def last_ptime_api_request_more_than_5_minutes last_request_time.to_datetime <= 5.minutes.ago end - def send_request_and_parse_response(method, path, params) + def ptime_request(method, url) + RestClient::Request.new( + :method => method, + :url => url, + :user => ENV.fetch('PTIME_API_USERNAME'), + :password => ENV.fetch('PTIME_API_PASSWORD'), + :headers => { :accept => :json, :content_type => :json } + ) + end + + def send_request_and_parse_response(method, url, params) ENV['PTIME_API_ACCESSIBLE'] = 'true' - path = "#{path}?#{URI.encode_www_form(params)}" if method == :get && params.present? - response = RestClient.send(method, path, headers) + url += "?#{params.to_query}" if method == :get && params.present? + response = ptime_request(method, url).execute JSON.parse(response.body, symbolize_names: true)[:data] end From 7550234abbe0d586b94656f1e461ad7343df6711 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 14:39:35 +0200 Subject: [PATCH 66/79] improve structure of people search --- app/helpers/auth_helper.rb | 4 ++-- app/helpers/person_helper.rb | 24 ++++++++++++------- app/helpers/select_helper.rb | 4 ++-- .../controllers/dropdown_controller.js | 2 +- app/views/people/_search.html.haml | 7 +----- 5 files changed, 21 insertions(+), 20 deletions(-) diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index b5e216197..c5cfbcdfc 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -22,7 +22,7 @@ def devise? AuthConfig.keycloak? || Rails.env.test? end - def ptime_broken? - !ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + def ptime_available? + ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) end end diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 59dd9e568..215546a7c 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -77,12 +77,18 @@ def not_rated_default_skills(person) end end + def sorted_people + fetch_ptime_or_skills_data.sort_by(&:first) + end + def fetch_ptime_or_skills_data + all_skills_people = Person.all.map { |p| [p.name, person_path(p)] } + + return all_skills_people unless ptime_available? + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) - all_skills_people = Person.all - return all_skills_people if ENV['PTIME_API_ACCESSIBLE'] == 'false' - ptime_employee_ids = all_skills_people.pluck(:ptime_employee_id) + ptime_employee_ids = Person.pluck(:ptime_employee_id) build_dropdown_data(ptime_employees, ptime_employee_ids) end @@ -90,12 +96,12 @@ def build_dropdown_data(ptime_employees, ptime_employee_ids) ptime_employees.map do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) person_id = map_ptime_employee_id(ptime_employee) - { - id: person_id, - ptime_employee_id: ptime_employee[:id], - name: ptime_employee_name, - already_exists: ptime_employee[:id].in?(ptime_employee_ids) - } + ptime_employee_id = ptime_employee[:id] + already_exists = ptime_employee_id.in?(ptime_employee_ids) + + path = person_path(person_id) + path = new_person_path(ptime_employee_id: ptime_employee_id) unless already_exists + [ptime_employee_name, path] end end diff --git a/app/helpers/select_helper.rb b/app/helpers/select_helper.rb index fa69b73b2..5183f0401 100644 --- a/app/helpers/select_helper.rb +++ b/app/helpers/select_helper.rb @@ -2,8 +2,8 @@ module SelectHelper def select_when_availabale(obj) - selected = obj ? obj.id : '' - prompt = obj ? false : true + selected = obj.present? ? polymorphic_path(obj) : '' + prompt = obj.nil? { selected: selected, prompt: prompt, disabled: '' } end diff --git a/app/javascript/controllers/dropdown_controller.js b/app/javascript/controllers/dropdown_controller.js index 370e15e4c..e9a88982f 100644 --- a/app/javascript/controllers/dropdown_controller.js +++ b/app/javascript/controllers/dropdown_controller.js @@ -11,6 +11,6 @@ export default class extends Controller { } handleChange(event) { - window.location.href = event.target.dataset.value + event.target.value; + window.location.href = event.target.value; } } diff --git a/app/views/people/_search.html.haml b/app/views/people/_search.html.haml index 23ea31441..ebc4c114a 100644 --- a/app/views/people/_search.html.haml +++ b/app/views/people/_search.html.haml @@ -1,12 +1,7 @@ %div.d-flex.align-items-center.justify-content-between %div.d-flex.col-9.gap-3 %span.col-6{"data-controller": "dropdown"} - - people_data = fetch_ptime_or_skills_data - - if ptime_broken? # people_data == skills - = collection_select :person_id, :person, people_data.sort_by {|p| p.name.downcase }, :id, :name, select_when_availabale(person), {data:{"dropdown-target": "dropdown" , action: "change->dropdown#handleChange", value: "/people/"}} - - elsif ENV['PTIME_API_ACCESSIBLE'] = 'true' # people_data == time - - sorted_employees = people_data.sort_by { |p| p[:name] } - = select :person_id, :person, options_for_select(sorted_employees.map { |p| [ p[:name], p[:already_exists] ? p[:id] : "new?ptime_employee_id=#{p[:ptime_employee_id]}" ] }), {}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange", value: "/people/" }} + = select :person_id, :person, options_for_select(sorted_people, select_when_availabale(person)), {prompt: person.nil?}, {data: { "dropdown-target" => "dropdown", action: "change->dropdown#handleChange"}} %div.d-flex.align-items-center.text-gray = "#{t 'profile.updated_at'}: #{@person&.last_updated_at.strftime("%d.%m.%Y")}" if @person&.last_updated_at %a.d-flex.justify-content-between#new-person-button{href: "/people/new"} From 552cf7d92edf96717e9acf950db7ae7d2179113b Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 17:09:03 +0200 Subject: [PATCH 67/79] Client isn't longer controlled by random env vars --- app/domain/ptime/client.rb | 11 ++----- app/exceptions/custom_exceptions.rb | 5 +++ app/helpers/person_helper.rb | 18 ++++++----- spec/helpers/person_helper_spec.rb | 47 +++++++++++++++++------------ 4 files changed, 44 insertions(+), 37 deletions(-) create mode 100644 app/exceptions/custom_exceptions.rb diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 548133572..4ba7c9bbd 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -14,10 +14,10 @@ def request(method, endpoint, params = {}) if last_ptime_api_request_more_than_5_minutes send_request_and_parse_response(method, path, params) else - skills_database_request + raise CustomExceptions::PTimeError, 'Error' end rescue RestClient::ExceptionWithResponse - skills_database_request + raise CustomExceptions::PTimeError, 'Error' end private @@ -47,16 +47,9 @@ def ptime_request(method, url) end def send_request_and_parse_response(method, url, params) - ENV['PTIME_API_ACCESSIBLE'] = 'true' url += "?#{params.to_query}" if method == :get && params.present? response = ptime_request(method, url).execute JSON.parse(response.body, symbolize_names: true)[:data] end - - def skills_database_request - ENV['PTIME_API_ACCESSIBLE'] = 'false' - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s - {} - end end end diff --git a/app/exceptions/custom_exceptions.rb b/app/exceptions/custom_exceptions.rb new file mode 100644 index 000000000..fe50cc70b --- /dev/null +++ b/app/exceptions/custom_exceptions.rb @@ -0,0 +1,5 @@ +module CustomExceptions + + class PTimeError < StandardError; end + +end diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 215546a7c..200732d8e 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -78,18 +78,20 @@ def not_rated_default_skills(person) end def sorted_people - fetch_ptime_or_skills_data.sort_by(&:first) + fetch_ptime_or_skills_data.sort_by { |e| e.first.downcase } end def fetch_ptime_or_skills_data all_skills_people = Person.all.map { |p| [p.name, person_path(p)] } - return all_skills_people unless ptime_available? - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) - - ptime_employee_ids = Person.pluck(:ptime_employee_id) - build_dropdown_data(ptime_employees, ptime_employee_ids) + begin + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) + ptime_employee_ids = Person.pluck(:ptime_employee_id) + build_dropdown_data(ptime_employees, ptime_employee_ids) + rescue CustomExceptions::PTimeError + all_skills_people + end end def build_dropdown_data(ptime_employees, ptime_employee_ids) @@ -98,9 +100,9 @@ def build_dropdown_data(ptime_employees, ptime_employee_ids) person_id = map_ptime_employee_id(ptime_employee) ptime_employee_id = ptime_employee[:id] already_exists = ptime_employee_id.in?(ptime_employee_ids) + path = new_person_path(ptime_employee_id: ptime_employee_id) + path = person_path(person_id) if already_exists - path = person_path(person_id) - path = new_person_path(ptime_employee_id: ptime_employee_id) unless already_exists [ptime_employee_name, path] end end diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index 1503d152c..76946558d 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -4,13 +4,30 @@ describe '#fetch_ptime_or_skills_data' do it 'should send request to ptime api' do - fetch_ptime_or_skills_data + allow(helper).to receive(:ptime_available?).and_return(true) + expected = skills_people = helper.fetch_ptime_or_skills_data + [ + ["Longmax Smith", "/people/new?ptime_employee_id=33"], + ["Alice Mante", "/people/new?ptime_employee_id=21"], + ["Charlie Ford", "/people/new?ptime_employee_id=45"] + ] + expect(skills_people).to eq(expected) end it 'should return people from skills database if last request was right now' do - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s - skills_people = fetch_ptime_or_skills_data - expect(skills_people).to eq(Person.all) + allow(helper).to receive(:ptime_available?).and_return(false) + + skills_people = helper.fetch_ptime_or_skills_data + expected = [ + ["Bob Anderson", "/people/902541635"], + ["Alice Mante", "/people/663665735"], + ["ken", "/people/155397742"], + ["Charlie Ford", "/people/786122151"], + ["Wally Allround", "/people/790004949"], + ["Hope Sunday", "/people/247095502"], + ["Longmax Smith", "/people/169654640"] + ] + expect(skills_people).to eq(expected) end end @@ -18,28 +35,18 @@ it 'should build correct dropdown data' do longmax = people(:longmax) alice = people(:alice) - charlie = people(:charlie) + people(:charlie) longmax.update!(ptime_employee_id: 33) alice.update!(ptime_employee_id: 21) - charlie.update!(ptime_employee_id: 45) dropdown_data = build_dropdown_data(ptime_employees_data, Person.all.pluck(:ptime_employee_id)) + expected = [ + ["Longmax Smith", "/people/169654640"], + ["Alice Mante", "/people/663665735"], + ["Charlie Ford", "/people/new?ptime_employee_id=45"]] + expect(dropdown_data).to eq(expected) - expect(dropdown_data[0][:id]).to eq(longmax.id) - expect(dropdown_data[0][:ptime_employee_id]).to eq(longmax.ptime_employee_id) - expect(dropdown_data[0][:name]).to eq("Longmax Smith") - expect(dropdown_data[0][:already_exists]).to be(true) - - expect(dropdown_data[1][:id]).to eq(alice.id) - expect(dropdown_data[1][:ptime_employee_id]).to eq(alice.ptime_employee_id) - expect(dropdown_data[1][:name]).to eq("Alice Mante") - expect(dropdown_data[1][:already_exists]).to be(true) - - expect(dropdown_data[2][:id]).to eq(charlie.id) - expect(dropdown_data[2][:ptime_employee_id]).to eq(charlie.ptime_employee_id) - expect(dropdown_data[2][:name]).to eq("Charlie Ford") - expect(dropdown_data[2][:already_exists]).to be(true) end end end From d9c02be8a22e9ed4cee1b95f8b83ba04584a2c6d Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Thu, 25 Jul 2024 17:19:20 +0200 Subject: [PATCH 68/79] simplify ptime_helpers --- spec/support/ptime_helpers.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index aee588ad5..ca40110a4 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -1,11 +1,8 @@ module PtimeHelpers def set_env_variables_and_stub_request - ptime_base_test_url = "www.ptime.example.com" - ptime_api_test_username = "test username" - ptime_api_test_password = "test password" - ENV["PTIME_BASE_URL"] = ptime_base_test_url - ENV["PTIME_API_USERNAME"] = ptime_api_test_username - ENV["PTIME_API_PASSWORD"] = ptime_api_test_password + ENV["PTIME_BASE_URL"] = "www.ptime.example.com" + ENV["PTIME_API_USERNAME"] = "test username" + ENV["PTIME_API_PASSWORD"] = "test password" stub_ptime_request(ptime_employees.to_json) end From 44d76bd9549742ae33b7519c52d6e383ee81a657 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Fri, 26 Jul 2024 09:41:25 +0200 Subject: [PATCH 69/79] clean up PR --- app/helpers/person_helper.rb | 10 +--------- db/schema.rb | 17 +---------------- spec/domain/ptime/update_people_data_spec.rb | 10 ---------- 3 files changed, 2 insertions(+), 35 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 200732d8e..7f06697c5 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -97,7 +97,7 @@ def fetch_ptime_or_skills_data def build_dropdown_data(ptime_employees, ptime_employee_ids) ptime_employees.map do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) - person_id = map_ptime_employee_id(ptime_employee) + person_id = Person.find_by(ptime_employee_id: ptime_employee[:id]) ptime_employee_id = ptime_employee[:id] already_exists = ptime_employee_id.in?(ptime_employee_ids) path = new_person_path(ptime_employee_id: ptime_employee_id) @@ -107,14 +107,6 @@ def build_dropdown_data(ptime_employees, ptime_employee_ids) end end - def map_ptime_employee_id(ptime_employee) - ptime_employee_id_map = Person.all.each_with_object({}) do |person, hash| - hash[person.ptime_employee_id.to_s] = person.id - end - - ptime_employee_id_map[ptime_employee[:id].to_s] - end - # Once https://github.com/puzzle/skills/issues/744 is merged there should be no need for this def append_ptime_employee_name(ptime_employee) "#{ptime_employee[:attributes][:firstname]} #{ptime_employee[:attributes][:lastname]}" diff --git a/db/schema.rb b/db/schema.rb index cfb6306f6..038f495fa 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_07_01_085558) do +ActiveRecord::Schema[7.0].define(version: 2024_06_24_122411) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -77,21 +77,6 @@ t.datetime "updated_at", precision: nil, null: false end - create_table "delayed_jobs", force: :cascade do |t| - t.integer "priority", default: 0, null: false - t.integer "attempts", default: 0, null: false - t.text "handler", null: false - t.text "last_error" - t.datetime "run_at" - t.datetime "locked_at" - t.datetime "failed_at" - t.string "locked_by" - t.string "queue" - t.datetime "created_at" - t.datetime "updated_at" - t.index ["priority", "run_at"], name: "delayed_jobs_priority" - end - create_table "departments", force: :cascade do |t| t.string "name", null: false t.datetime "created_at", null: false diff --git a/spec/domain/ptime/update_people_data_spec.rb b/spec/domain/ptime/update_people_data_spec.rb index 8e3273f85..dd38186df 100644 --- a/spec/domain/ptime/update_people_data_spec.rb +++ b/spec/domain/ptime/update_people_data_spec.rb @@ -1,16 +1,6 @@ require 'rails_helper' -ptime_base_test_url = "www.ptime.example.com" -ptime_api_test_username = "test username" -ptime_api_test_password = "test password" -ENV["PTIME_API_USERNAME"] = ptime_api_test_username -ENV["PTIME_API_PASSWORD"] = ptime_api_test_password - describe Ptime::UpdatePeopleData do - before(:each) do - ENV["PTIME_BASE_URL"] = ptime_base_test_url - end - it 'should update the data of existing people after mapping' do employees = fixture_data "updating_ptime_employees" From 71db98a099461e040720df0b0aa0a74a5f4a4daa Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Fri, 26 Jul 2024 11:54:03 +0200 Subject: [PATCH 70/79] Clean up Skills db fallback logic --- app/domain/ptime/client.rb | 20 +++++++------------- app/exceptions/custom_exceptions.rb | 2 +- app/helpers/person_helper.rb | 13 ++++++------- spec/domain/ptime/client_spec.rb | 13 +++++++++++++ spec/features/people_spec.rb | 2 +- spec/helpers/person_helper_spec.rb | 4 ++-- 6 files changed, 30 insertions(+), 24 deletions(-) diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 4ba7c9bbd..254305b17 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -11,26 +11,18 @@ def initialize def request(method, endpoint, params = {}) path = @base_url + endpoint - if last_ptime_api_request_more_than_5_minutes + + if last_ptime_error_more_than_5_minutes_ago? send_request_and_parse_response(method, path, params) else - raise CustomExceptions::PTimeError, 'Error' + raise CustomExceptions::PTimeClientError, 'Error' end - rescue RestClient::ExceptionWithResponse - raise CustomExceptions::PTimeError, 'Error' end private - # Currently not in use can be removed - def response_error_message(exception) - JSON.parse(exception.response.body).dig('error', 'message') - rescue JSON::ParserError # rescue only JSON parsing errors - nil - end - - def last_ptime_api_request_more_than_5_minutes - last_request_time = ENV.fetch('LAST_PTIME_API_REQUEST', nil) + def last_ptime_error_more_than_5_minutes_ago? + last_request_time = ENV.fetch('LAST_PTIME_ERROR', nil) return true if last_request_time.nil? last_request_time.to_datetime <= 5.minutes.ago @@ -50,6 +42,8 @@ def send_request_and_parse_response(method, url, params) url += "?#{params.to_query}" if method == :get && params.present? response = ptime_request(method, url).execute JSON.parse(response.body, symbolize_names: true)[:data] + rescue RestClient::ExceptionWithResponse + raise CustomExceptions::PTimeClientError, 'Error' end end end diff --git a/app/exceptions/custom_exceptions.rb b/app/exceptions/custom_exceptions.rb index fe50cc70b..b59a9ef87 100644 --- a/app/exceptions/custom_exceptions.rb +++ b/app/exceptions/custom_exceptions.rb @@ -1,5 +1,5 @@ module CustomExceptions - class PTimeError < StandardError; end + class PTimeClientError < StandardError; end end diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 7f06697c5..10661b7b2 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -85,13 +85,12 @@ def fetch_ptime_or_skills_data all_skills_people = Person.all.map { |p| [p.name, person_path(p)] } return all_skills_people unless ptime_available? - begin - ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) - ptime_employee_ids = Person.pluck(:ptime_employee_id) - build_dropdown_data(ptime_employees, ptime_employee_ids) - rescue CustomExceptions::PTimeError - all_skills_people - end + ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) + ptime_employee_ids = Person.pluck(:ptime_employee_id) + build_dropdown_data(ptime_employees, ptime_employee_ids) + rescue CustomExceptions::PTimeClientError + ENV['LAST_PTIME_ERROR'] = DateTime.current.to_s + all_skills_people end def build_dropdown_data(ptime_employees, ptime_employee_ids) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 4f0af30a2..2ac931ff7 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -5,4 +5,17 @@ fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) expect(fetched_employees).to eq(ptime_employees_data) end + + it 'should not raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do + ENV['LAST_PTIME_ERROR'] = 6.minutes.ago.to_s + fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) + expect(fetched_employees).to eq(ptime_employees_data) + end + + it 'should raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do + ENV['LAST_PTIME_ERROR'] = 4.minutes.ago.to_s + expect { + Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) + }.to raise_error(CustomExceptions::PTimeClientError) + end end diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index 9cfda38c6..e1cb4d115 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -4,7 +4,7 @@ describe 'People Search', type: :feature, js: true do before(:each) do - ENV['LAST_PTIME_API_REQUEST'] = DateTime.current.to_s # This is needed to activate the fallback and test for the skills people + ENV['LAST_PTIME_ERROR'] = DateTime.current.to_s # This is needed to activate the fallback and test for the skills people sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index 76946558d..9d4af9c7c 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -5,8 +5,8 @@ it 'should send request to ptime api' do allow(helper).to receive(:ptime_available?).and_return(true) - expected = skills_people = helper.fetch_ptime_or_skills_data - [ + skills_people = helper.fetch_ptime_or_skills_data + expected = [ ["Longmax Smith", "/people/new?ptime_employee_id=33"], ["Alice Mante", "/people/new?ptime_employee_id=21"], ["Charlie Ford", "/people/new?ptime_employee_id=45"] From 3a7997a42a7bf4d43edfb10e1d269a4f0e01b7ca Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Fri, 26 Jul 2024 12:26:28 +0200 Subject: [PATCH 71/79] improve readability by using more helper --- app/helpers/person_helper.rb | 7 +++---- spec/features/people_spec.rb | 2 +- spec/helpers/person_helper_spec.rb | 2 +- spec/rails_helper.rb | 2 +- spec/support/ptime_helpers.rb | 20 +++++++++++++++----- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 10661b7b2..ac25c245b 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -86,19 +86,18 @@ def fetch_ptime_or_skills_data return all_skills_people unless ptime_available? ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) - ptime_employee_ids = Person.pluck(:ptime_employee_id) - build_dropdown_data(ptime_employees, ptime_employee_ids) + build_dropdown_data(ptime_employees) rescue CustomExceptions::PTimeClientError ENV['LAST_PTIME_ERROR'] = DateTime.current.to_s all_skills_people end - def build_dropdown_data(ptime_employees, ptime_employee_ids) + def build_dropdown_data(ptime_employees) ptime_employees.map do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) person_id = Person.find_by(ptime_employee_id: ptime_employee[:id]) ptime_employee_id = ptime_employee[:id] - already_exists = ptime_employee_id.in?(ptime_employee_ids) + already_exists = ptime_employee_id.in?(Person.pluck(:ptime_employee_id)) path = new_person_path(ptime_employee_id: ptime_employee_id) path = person_path(person_id) if already_exists diff --git a/spec/features/people_spec.rb b/spec/features/people_spec.rb index e1cb4d115..77f7e4c6d 100644 --- a/spec/features/people_spec.rb +++ b/spec/features/people_spec.rb @@ -4,7 +4,7 @@ describe 'People Search', type: :feature, js: true do before(:each) do - ENV['LAST_PTIME_ERROR'] = DateTime.current.to_s # This is needed to activate the fallback and test for the skills people + use_skills_db sign_in auth_users(:user), scope: :auth_user end diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index 9d4af9c7c..d832ed96b 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -40,7 +40,7 @@ longmax.update!(ptime_employee_id: 33) alice.update!(ptime_employee_id: 21) - dropdown_data = build_dropdown_data(ptime_employees_data, Person.all.pluck(:ptime_employee_id)) + dropdown_data = build_dropdown_data(ptime_employees_data) expected = [ ["Longmax Smith", "/people/169654640"], ["Alice Mante", "/people/663665735"], diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 4e8d29fe8..196810e2f 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -63,7 +63,7 @@ config.infer_spec_type_from_file_location! config.before(:each) do - set_env_variables_and_stub_request + stub_env_variables_and_request end config.before { allow($stdout).to receive(:puts) } diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index ca40110a4..cc339ee3c 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -1,9 +1,8 @@ module PtimeHelpers - def set_env_variables_and_stub_request - ENV["PTIME_BASE_URL"] = "www.ptime.example.com" - ENV["PTIME_API_USERNAME"] = "test username" - ENV["PTIME_API_PASSWORD"] = "test password" - + def stub_env_variables_and_request + stub_env_var("PTIME_BASE_URL", "www.ptime.example.com") + stub_env_var("PTIME_API_USERNAME", "test username") + stub_env_var("PTIME_API_PASSWORD", "test password") stub_ptime_request(ptime_employees.to_json) end @@ -24,4 +23,15 @@ def stub_ptime_request(return_body, path =nil) .to_return(body: return_body, headers: { 'content-type': content_type }, status: 200) .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) end + + def use_skills_db + allow_any_instance_of(RestClient::Request) + .to receive(:execute) + .and_raise(RestClient::ExceptionWithResponse) + end + + def stub_env_var(name, value) + allow(ENV).to receive(:fetch).with(name).and_return(value) + stub_const('ENV', ENV.to_hash.merge(name => value)) + end end From d19bd8e06abac33fcd533a4e72286f5481af1baa Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Fri, 26 Jul 2024 12:44:56 +0200 Subject: [PATCH 72/79] clean up --- app/helpers/person_helper.rb | 4 ++-- spec/domain/ptime/client_spec.rb | 4 ++-- spec/rails_helper.rb | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index ac25c245b..3c6dde47b 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -95,11 +95,11 @@ def fetch_ptime_or_skills_data def build_dropdown_data(ptime_employees) ptime_employees.map do |ptime_employee| ptime_employee_name = append_ptime_employee_name(ptime_employee) - person_id = Person.find_by(ptime_employee_id: ptime_employee[:id]) + skills_person = Person.find_by(ptime_employee_id: ptime_employee[:id]) ptime_employee_id = ptime_employee[:id] already_exists = ptime_employee_id.in?(Person.pluck(:ptime_employee_id)) path = new_person_path(ptime_employee_id: ptime_employee_id) - path = person_path(person_id) if already_exists + path = person_path(skills_person) if already_exists [ptime_employee_name, path] end diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 2ac931ff7..166499d4f 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -7,13 +7,13 @@ end it 'should not raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do - ENV['LAST_PTIME_ERROR'] = 6.minutes.ago.to_s + stub_env_var("LAST_PTIME_ERROR", 6.minutes.ago.to_s) fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) expect(fetched_employees).to eq(ptime_employees_data) end it 'should raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do - ENV['LAST_PTIME_ERROR'] = 4.minutes.ago.to_s + stub_env_var("LAST_PTIME_ERROR", 4.minutes.ago.to_s) expect { Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) }.to raise_error(CustomExceptions::PTimeClientError) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 196810e2f..d57d07b37 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -66,7 +66,8 @@ stub_env_variables_and_request end - config.before { allow($stdout).to receive(:puts) } + show_logs = ENV.fetch('SHOW_LOGS', false) + config.before { allow($stdout).to receive(:puts) } unless show_logs # Controller helper config.include(JsonMacros, type: :controller) From 57ad58af26df975ec57c904db0f8ce97450ad944 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Mon, 29 Jul 2024 10:41:58 +0200 Subject: [PATCH 73/79] add client test --- spec/domain/ptime/client_spec.rb | 10 +++++++++- spec/support/ptime_helpers.rb | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/spec/domain/ptime/client_spec.rb b/spec/domain/ptime/client_spec.rb index 166499d4f..42d727b07 100644 --- a/spec/domain/ptime/client_spec.rb +++ b/spec/domain/ptime/client_spec.rb @@ -6,12 +6,20 @@ expect(fetched_employees).to eq(ptime_employees_data) end - it 'should not raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do + it 'should not raise PTimeClientError if LAST_PTIME_ERROR is more than 5 minutes ago' do stub_env_var("LAST_PTIME_ERROR", 6.minutes.ago.to_s) fetched_employees = Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) expect(fetched_employees).to eq(ptime_employees_data) end + it 'should raise PTimeClientError page is unreachable' do + stub_env_var("PTIME_BASE_URL", "irgend.oepp.is") + stub_ptime_request(ptime_employees.to_json, "employees?per_page=1000", 404) + expect { + Ptime::Client.new.request(:get, "employees", { per_page: 1000 }) + }.to raise_error(CustomExceptions::PTimeClientError) + end + it 'should raise PTimeClientError if LAST_PTIME_ERROR is less than 5 minutes ago' do stub_env_var("LAST_PTIME_ERROR", 4.minutes.ago.to_s) expect { diff --git a/spec/support/ptime_helpers.rb b/spec/support/ptime_helpers.rb index cc339ee3c..72da9c69b 100644 --- a/spec/support/ptime_helpers.rb +++ b/spec/support/ptime_helpers.rb @@ -14,13 +14,13 @@ def ptime_employees_data fixture_data("all_ptime_employees")[:data] end - def stub_ptime_request(return_body, path =nil) + def stub_ptime_request(return_body, path =nil, status = 200) path ||= "employees?per_page=1000" url = "http://#{ENV["PTIME_BASE_URL"]}/api/v1/#{path}" content_type = "application/vnd.api+json; charset=utf-8" stub_request(:get, url) - .to_return(body: return_body, headers: { 'content-type': content_type }, status: 200) + .to_return(body: return_body, headers: { 'content-type': content_type }, status: status) .with(basic_auth: [ENV["PTIME_API_USERNAME"], ENV["PTIME_API_PASSWORD"]]) end From af3def751cdd802b96605353575cbc7fc05ffdde Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Mon, 29 Jul 2024 14:28:54 +0200 Subject: [PATCH 74/79] =?UTF-8?q?ds=20mu=C3=A4s=20so?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/person_helper.rb | 2 +- config/application.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/helpers/person_helper.rb b/app/helpers/person_helper.rb index 3c6dde47b..a5916f540 100644 --- a/app/helpers/person_helper.rb +++ b/app/helpers/person_helper.rb @@ -83,7 +83,7 @@ def sorted_people def fetch_ptime_or_skills_data all_skills_people = Person.all.map { |p| [p.name, person_path(p)] } - return all_skills_people unless ptime_available? + return all_skills_people unless Skills.ptime_available? ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) build_dropdown_data(ptime_employees) diff --git a/config/application.rb b/config/application.rb index dee2a1781..d25c78c3a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -13,6 +13,10 @@ Bundler.require(*Rails.groups) module Skills + def self.ptime_available? + ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) + end + class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 From 2763d615bf13c1bea6eef7cb779ecec4911116e6 Mon Sep 17 00:00:00 2001 From: Yanick Minder Date: Mon, 29 Jul 2024 15:03:48 +0200 Subject: [PATCH 75/79] so its aber --- app/helpers/auth_helper.rb | 4 ---- spec/helpers/person_helper_spec.rb | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb index c5cfbcdfc..2d98e159f 100644 --- a/app/helpers/auth_helper.rb +++ b/app/helpers/auth_helper.rb @@ -21,8 +21,4 @@ def find_person_by_auth_user def devise? AuthConfig.keycloak? || Rails.env.test? end - - def ptime_available? - ActiveModel::Type::Boolean.new.cast(ENV.fetch('PTIME_API_ACCESSIBLE', true)) - end end diff --git a/spec/helpers/person_helper_spec.rb b/spec/helpers/person_helper_spec.rb index d832ed96b..d05ea3c89 100644 --- a/spec/helpers/person_helper_spec.rb +++ b/spec/helpers/person_helper_spec.rb @@ -4,7 +4,7 @@ describe '#fetch_ptime_or_skills_data' do it 'should send request to ptime api' do - allow(helper).to receive(:ptime_available?).and_return(true) + allow(Skills).to receive(:ptime_available?).and_return(true) skills_people = helper.fetch_ptime_or_skills_data expected = [ ["Longmax Smith", "/people/new?ptime_employee_id=33"], @@ -15,7 +15,7 @@ end it 'should return people from skills database if last request was right now' do - allow(helper).to receive(:ptime_available?).and_return(false) + allow(Skills).to receive(:ptime_available?).and_return(false) skills_people = helper.fetch_ptime_or_skills_data expected = [ From d272a03a271ccfcdb18e8002875c0a1c81a08e2b Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Mon, 29 Jul 2024 15:53:58 +0200 Subject: [PATCH 76/79] Resolve conversations --- app/domain/ptime/assign_employee_ids.rb | 28 +++++++++---------------- app/domain/ptime/client.rb | 4 ++-- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index b916ad6fc..316cef066 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -20,30 +20,23 @@ def run(should_map: false) def map_employees(should_map) puts 'Assigning employee IDs now...' if should_map - ambiguous_entries = [] unmatched_entries = [] mapped_people_count = 0 @ptime_employees.each do |ptime_employee| - ptime_employee_firstname = ptime_employee[:attributes][:firstname] - ptime_employee_lastname = ptime_employee[:attributes][:lastname] - ptime_employee_name = "#{ptime_employee_firstname} #{ptime_employee_lastname}" + ptime_employee_name = + "#{ptime_employee[:attributes][:lastname]} #{ptime_employee[:attributes][:firstname]}" ptime_employee_email = ptime_employee[:attributes][:email] - matched_skills_people = Person.where(ptime_employee_id: nil) - .where(name: ptime_employee_name) - .where(email: ptime_employee_email) + matched_person = Person.where(ptime_employee_id: nil).find_by(email: ptime_employee_email) - if matched_skills_people.empty? + if matched_person.nil? unmatched_entries << { name: ptime_employee_name, id: ptime_employee[:id] } - elsif matched_skills_people.one? + else if should_map - matched_skills_person = matched_skills_people.first - matched_skills_person.ptime_employee_id = ptime_employee[:id] - matched_skills_person.save! + matched_person.ptime_employee_id = ptime_employee[:id] + matched_person.save! end mapped_people_count += 1 - else - ambiguous_entries << { name: ptime_employee_name, id: ptime_employee[:id] } end end @@ -52,15 +45,14 @@ def map_employees(should_map) puts '--------------------------' puts "#{unmatched_entries.size} people didn't match" unmatched_entries.each { |entry| puts "- #{entry[:name]} with id #{entry[:id]}" } - puts '--------------------------' - puts "#{ambiguous_entries.size} people ambiguous matched" - ambiguous_entries.each { |entry| puts "- #{entry[:name]} with id #{entry[:id]}" } end # rubocop:enable Metrics + MAX_NUMBER_OF_FETCHED_EMPLOYEES = 1000 def fetch_data puts 'Fetching required data...' - @ptime_employees = Ptime::Client.new.request(:get, 'employees', { per_page: 1000 }) + @ptime_employees = Ptime::Client.new.request(:get, 'employees', + { per_page: MAX_NUMBER_OF_FETCHED_EMPLOYEES }) @skills_people = Person.all puts 'Successfully fetched data' end diff --git a/app/domain/ptime/client.rb b/app/domain/ptime/client.rb index 254305b17..00edffe95 100644 --- a/app/domain/ptime/client.rb +++ b/app/domain/ptime/client.rb @@ -10,10 +10,10 @@ def initialize end def request(method, endpoint, params = {}) - path = @base_url + endpoint + url = @base_url + endpoint if last_ptime_error_more_than_5_minutes_ago? - send_request_and_parse_response(method, path, params) + send_request_and_parse_response(method, url, params) else raise CustomExceptions::PTimeClientError, 'Error' end From 48fb6be79a26e887fa039bab5726872fe971eb7a Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 30 Jul 2024 07:57:57 +0200 Subject: [PATCH 77/79] Remove unneeded spec and fix spec that tests the not found case when mapping --- spec/domain/ptime/assign_employee_ids_spec.rb | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/spec/domain/ptime/assign_employee_ids_spec.rb b/spec/domain/ptime/assign_employee_ids_spec.rb index 3e8f01a6c..948927602 100644 --- a/spec/domain/ptime/assign_employee_ids_spec.rb +++ b/spec/domain/ptime/assign_employee_ids_spec.rb @@ -16,8 +16,8 @@ it 'should not map people that are not found' do parsed_employees_json = ptime_employees - parsed_employees_json[:data].first[:attributes][:firstname] = "Rochus" - parsed_employees_json[:data].second[:attributes][:firstname] = "Melchior" + parsed_employees_json[:data].first[:attributes][:email] = "somemailthatdoesnotexist@example.com" + parsed_employees_json[:data].second[:attributes][:email] = "thismailalsodoesntexist@example.com" stub_ptime_request(parsed_employees_json.to_json) @@ -33,22 +33,6 @@ expect(person_charlie.reload.ptime_employee_id).to eq(45) end - it 'should not map people that are ambiguous' do - person_longmax = people(:longmax) - person_alice = people(:alice) - person_charlie = people(:charlie) - - person_charlie.name = "Alice Mante" - person_charlie.email = "alice@example.com" - person_charlie.save! - - Ptime::AssignEmployeeIds.new.run(should_map: true) - - expect(person_longmax.reload.ptime_employee_id).to eq(33) - expect(person_alice.reload.ptime_employee_id).to be_nil - expect(person_charlie.reload.ptime_employee_id).to be_nil - end - it 'should not map people on dry run' do person_longmax = people(:longmax) person_alice = people(:alice) From a52ceaa257d74dfec53721a76cdcaa5edf9a2423 Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 30 Jul 2024 08:07:15 +0200 Subject: [PATCH 78/79] Fix order of name interpolation in id mapper script --- app/domain/ptime/assign_employee_ids.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 316cef066..741c88fec 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -25,7 +25,7 @@ def map_employees(should_map) @ptime_employees.each do |ptime_employee| ptime_employee_name = - "#{ptime_employee[:attributes][:lastname]} #{ptime_employee[:attributes][:firstname]}" + "#{ptime_employee[:attributes][:firstname]} #{ptime_employee[:attributes][:lastname]}" ptime_employee_email = ptime_employee[:attributes][:email] matched_person = Person.where(ptime_employee_id: nil).find_by(email: ptime_employee_email) From 65fb684ef7b0be16afa24f8e3b8f47877ec6131d Mon Sep 17 00:00:00 2001 From: Jannik Pulfer Date: Tue, 30 Jul 2024 08:22:16 +0200 Subject: [PATCH 79/79] Update json fixtures and use full_name instead of interpolating it --- app/domain/ptime/assign_employee_ids.rb | 3 +- .../files/json/all_ptime_employees.json | 70 +++++++++++-------- .../files/json/new_ptime_employee.json | 8 ++- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/app/domain/ptime/assign_employee_ids.rb b/app/domain/ptime/assign_employee_ids.rb index 741c88fec..346712c6a 100644 --- a/app/domain/ptime/assign_employee_ids.rb +++ b/app/domain/ptime/assign_employee_ids.rb @@ -24,8 +24,7 @@ def map_employees(should_map) mapped_people_count = 0 @ptime_employees.each do |ptime_employee| - ptime_employee_name = - "#{ptime_employee[:attributes][:firstname]} #{ptime_employee[:attributes][:lastname]}" + ptime_employee_name = ptime_employee[:attributes][:full_name] ptime_employee_email = ptime_employee[:attributes][:email] matched_person = Person.where(ptime_employee_id: nil).find_by(email: ptime_employee_email) diff --git a/spec/fixtures/files/json/all_ptime_employees.json b/spec/fixtures/files/json/all_ptime_employees.json index 685e11445..1cfef9ab6 100644 --- a/spec/fixtures/files/json/all_ptime_employees.json +++ b/spec/fixtures/files/json/all_ptime_employees.json @@ -4,49 +4,57 @@ "id" : 33, "type" : "employee", "attributes" : { - "shortname" : "LSM", - "firstname" : "Longmax", - "lastname" : "Smith", - "email" : "longmax@example.com", - "marital_status" : "single", - "nationalities" : ["ZW"], - "graduation" : "BSc in Architecture", - "department_shortname" : "SYS", - "employment_roles" : [] + "shortname" : "LSM", + "firstname" : "Longmax", + "lastname" : "Smith", + "full_name": "Longmax Smith", + "email" : "longmax@example.com", + "marital_status" : "single", + "nationalities" : ["ZW"], + "graduation" : "BSc in Architecture", + "department_shortname" : "SYS", + "employment_roles" : [], + "is_employed" : true, + "birthdate" : "05.05.1994", + "location" : "Bern" } }, { "id" : 21, "type" : "employee", "attributes" : { - "shortname" : "AMA", - "firstname" : "Alice", - "lastname" : "Mante", - "full_name" : "Alice Mante", - "email" : "alice@example.com", - "marital_status" : "single", - "nationalities" : ["AU"], - "graduation" : "MSc in writing", - "department_shortname" : "SYS", - "employment_roles" : [], - "is_employed" : false, - "birthdate" : "01.04.2001", - "location" : "Bern" + "shortname" : "AMA", + "firstname" : "Alice", + "lastname" : "Mante", + "full_name" : "Alice Mante", + "email" : "alice@example.com", + "marital_status" : "single", + "nationalities" : ["AU"], + "graduation" : "MSc in writing", + "department_shortname" : "SYS", + "employment_roles" : [], + "is_employed" : false, + "birthdate" : "01.04.2001", + "location" : "Bern" } }, { "id" : 45, "type" : "employee", "attributes" : { - "shortname" : "CFO", - "firstname" : "Charlie", - "lastname" : "Ford", - "email" : "charlie@example.com", - "marital_status" : "married", - "nationalities" : ["GB"], - "graduation" : "MSc in networking", - "department_shortname" : "SYS", - "employment_roles" : [] + "shortname" : "CFO", + "firstname" : "Charlie", + "lastname" : "Ford", + "full_name": "Charlie Ford", + "email" : "charlie@example.com", + "marital_status" : "married", + "nationalities" : ["GB"], + "graduation" : "MSc in networking", + "department_shortname" : "SYS", + "employment_roles" : [], + "is_employed" : true, + "birthdate" : "01.10.1980", + "location" : "Thun" } } ] diff --git a/spec/fixtures/files/json/new_ptime_employee.json b/spec/fixtures/files/json/new_ptime_employee.json index 308d4fcb4..0ff33280f 100644 --- a/spec/fixtures/files/json/new_ptime_employee.json +++ b/spec/fixtures/files/json/new_ptime_employee.json @@ -7,6 +7,7 @@ "shortname": "PFI", "firstname": "Peterson", "lastname": "Findus", + "full_name": "Peterson Findus", "email": "peterson@example.com", "marital_status": "single", "nationalities": [ @@ -14,8 +15,11 @@ ], "graduation": "Cat caretaker", "department_shortname": "CAT", - "employment_roles": [] + "employment_roles": [], + "is_employed" : true, + "birthdate" : "12.12.1958", + "location" : "Bern" } } ] - } \ No newline at end of file +} \ No newline at end of file