diff --git a/.gitignore b/.gitignore index 08fec66..2118049 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /tmp/* /coverage/* /artifacts/* +.cache/* /*.xml *.zip diff --git a/.rubocop.yml b/.rubocop.yml index c169d9a..87f4527 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -89,10 +89,15 @@ Style/Lambda: Style/SingleLineBlockParams: Enabled: false -# For now allowing my obsesive use of OpenStructs -Style/OpenStructUse: - Enabled: false - # Rubocop hates it, but Docker is forcing the issue... Style/HashSyntax: - Enabled: false \ No newline at end of file + Enabled: false + +# Let's relax on some of the spec cops...they're setup heavy +Metrics/MethodLength: + Exclude: + - 'spec/**/*' + +Metrics/AbcSize: + Exclude: + - 'spec/**/*' \ No newline at end of file diff --git a/README.md b/README.md index 9d34bd9..52c051b 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,27 @@ docker build -t alma-user-load . > rspec ``` +### Run the test suite via Docker: +```sh +# Run rspec: +> docker compose -f docker-compose.local.yml run --rm shell bundle exec rspec + +# Run a single spec file: +> docker compose -f docker-compose.local.yml run --rm shell bundle exec rspec spec/lib/ucpath_spec.rb + +# Run a specific test (by line number) +> docker compose -f docker-compose.local.yml run --rm shell bundle exec rspec spec/lib/helpers_spec.rb:34 +``` + +### For convenience, setup an alias: +```sh +# Add alias: +> alias drspec='docker compose -f docker-compose.local.yml run --rm shell bundle exec rspec' + +# Run via alias: +drspec spec/lib/ucpath_spec.rb:327 +``` + Note - to run the test suite you need to change the LDAP setting in your `.env` file > \# For testing: > LDAP_HOST=ldap.fake.edu @@ -134,7 +155,6 @@ Note - to run the test suite you need to change the LDAP setting in your `.env` ## Future Improvements: -- Replace fixtures w/some sort of factory (VCR) - DRY things up (UCPath vs. SIS --> phone, email, address, names, etc...) - SIS - add run by user id (similar to how I setup ucpath)...if possible - Move 'create_user_record' from user.rb to a separate class diff --git a/config/settings.yml b/config/settings.yml index 133f64f..01462f7 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -6,7 +6,7 @@ settings: upload_host: "upload.lib.berkeley.edu" upload_user: "ssullivan" last_alma_purge: "2023-06-30" - application_version: "1.6.6" + application_version: "1.6.8" # TODO - flesh this out # http://docopt.org/ diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..b58dfea --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,10 @@ +services: + shell: + build: + context: . + target: development + init: true + working_dir: /opt/app + volumes: + - ./:/opt/app + entrypoint: [] diff --git a/spec/data/ucpath/10000003_jobs.json b/spec/data/ucpath/10000003_jobs.json deleted file mode 100644 index 1b4457d..0000000 --- a/spec/data/ucpath/10000003_jobs.json +++ /dev/null @@ -1,269 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "dab25623-a725-4687-8b57-1e04d4701ff5", - "timeStamp": "2022-02-01", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10527060" - }, - { - "type": "campus-uid", - "id": "1628831" - }, - { - "type": "calnet-id", - "id": "derakhshan" - }, - { - "type": "campus-solutions-id", - "id": "3034389843" - }, - { - "type": "legacy-hr-employee-id", - "id": "013139999" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 1, - "type": { - "code": "14", - "description": "Academic: Contingent Worker" - }, - "classification": { - "code": "C", - "description": "Not Applicable/CWR" - }, - "position": { - "jobCode": { - "code": { - "code": "CWR011", - "description": "Staff Volunteer", - "active": true, - "fromDate": "2016-01-01" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": {} - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - } - }, - "organizationRelationship": { - "code": "CWR", - "description": "Contingent Worker" - }, - "flsaEligibilty": { - "code": "X", - "description": "No FLSA Required" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "N", - "description": "Not Applicable" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "10001", - "description": "Main Campus-Berkeley-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "I", - "description": "Inactive" - }, - "employmentStatus": { - "code": "I", - "description": "Inactive" - }, - "benefitsStatus": { - "code": "I", - "description": "Inactive" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": {}, - "grade": {}, - "step": { - "code": "0" - } - }, - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - }, - "hourly": 0, - "daily": 0, - "monthly": 0, - "annually": 0 - }, - "payGroup": { - "code": "CWR", - "description": "SYSTEMWIDE CONTINGENT WORKER" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - } - } - } - ] - }, - "actions": { - "lastAction": { - "code": "DTA", - "description": "Data Change", - "fromDate": "2021-10-19" - }, - "lastActionReason": { - "code": "PRI", - "description": "Update Job Indicator" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-10-18", - "lastHireDate": "2021-10-18", - "jobAssignedDate": "2021-10-18", - "expectedEndDate": "2021-11-17", - "endAutomatically": false - }, - "benefits": {}, - "fromDate": "2021-10-18" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/10000006_jobs.json b/spec/data/ucpath/10000006_jobs.json deleted file mode 100644 index e4a53bb..0000000 --- a/spec/data/ucpath/10000006_jobs.json +++ /dev/null @@ -1,706 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "dab25623-a725-4687-8b57-1e04d4701ff5", - "timeStamp": "2022-02-01", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10527060" - }, - { - "type": "campus-uid", - "id": "1628831" - }, - { - "type": "calnet-id", - "id": "derakhshan" - }, - { - "type": "campus-solutions-id", - "id": "3034389843" - }, - { - "type": "legacy-hr-employee-id", - "id": "013139999" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 1, - "type": { - "code": "14", - "description": "Academic: Contingent Worker" - }, - "classification": { - "code": "C", - "description": "Not Applicable/CWR" - }, - "position": { - "jobCode": { - "code": { - "code": "CWR011", - "description": "Staff Volunteer", - "active": true, - "fromDate": "2016-01-01" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": {} - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - } - }, - "organizationRelationship": { - "code": "CWR", - "description": "Contingent Worker" - }, - "flsaEligibilty": { - "code": "X", - "description": "No FLSA Required" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "N", - "description": "Not Applicable" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "10001", - "description": "Main Campus-Berkeley-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": {}, - "grade": {}, - "step": { - "code": "0" - } - }, - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - }, - "hourly": 0, - "daily": 0, - "monthly": 0, - "annually": 0 - }, - "payGroup": { - "code": "CWR", - "description": "SYSTEMWIDE CONTINGENT WORKER" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - } - } - } - ] - }, - "actions": { - "lastAction": { - "code": "DTA", - "description": "Data Change", - "fromDate": "2021-10-19" - }, - "lastActionReason": { - "code": "PRI", - "description": "Update Job Indicator" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-10-18", - "lastHireDate": "2021-10-18", - "jobAssignedDate": "2021-10-18", - "expectedEndDate": "2021-11-17", - "endAutomatically": false - }, - "benefits": {}, - "fromDate": "2021-10-18" - }, - { - "number": 1, - "sequence": 0, - "type": { - "code": "23", - "description": "Academic: Post Docs" - }, - "classification": { - "code": "A", - "description": "Academic" - }, - "position": { - "number": "40858087", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "POSTDOC-EMPLOYEE", - "pool": {}, - "percentOfFullTime": 1.000000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "003252", - "description": "POSTDOC-EMPLOYEE" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "flsaEligibilty": {}, - "representation": { - "union": { - "code": "PX", - "description": "Post Doctoral Scholars" - } - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 1, - "maximum": 1, - "status": { - "code": "F", - "description": "Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2021-10-01" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "E", - "description": "Exempt" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "11153", - "description": "Calvin Lab-F01-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": { - "code": "T023", - "description": "Post Doctoral (EE/FEL/PD)", - "active": true, - "fromDate": "1910-01-01" - }, - "grade": { - "code": "L0", - "description": "Post Doctoral Level 0", - "active": true, - "fromDate": "2021-11-29" - }, - "step": { - "code": "0" - } - }, - "rate": { - "base": 5833.333333, - "baseFrequency": { - "code": "UC_FY", - "description": "UC 12/12 - FY" - }, - "hourly": 33.524902, - "daily": 268.199, - "monthly": 5833.333, - "annually": 70000 - }, - "payGroup": { - "code": "1AC", - "description": "UCB Academic Exempt Monthly" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "code": "UCANNL", - "base": 70000, - "baseFrequency": { - "code": "A", - "description": "Annual", - "annualFactor": 1 - } - }, - "percent": 0 - } - ] - }, - "earningsDistribution": { - "distributions": [ - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "000776625", - "description": "User Account 000776625", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "62206", - "description": "NSF Nat-2023505-Peter L -08/25", - "active": true, - "fromDate": "2021-08-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHPXB", - "description": "Bartlett,Peter", - "active": true, - "fromDate": "2006-11-03" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": { - "code": "1017959", - "description": "Collaborative Research: Nation", - "active": true - }, - "pcProduct": { - "code": "GM100", - "description": "Grants Management 10000", - "active": true, - "fromDate": "1900-01-01" - }, - "pcClass": { - "code": "01", - "description": "ACTIVITY - 01", - "active": true, - "fromDate": "1900-01-01" - }, - "chartString": "10000-010000-62206-23797-44--EHPXB" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - }, - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "001147031", - "description": "User Account 001147031", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "48254", - "description": "Haghtalab's J.P. Morgan AI Res", - "active": true, - "fromDate": "2021-07-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHNXH", - "description": "Nika Haghtalab", - "active": true, - "fromDate": "2020-07-01" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": {}, - "pcProduct": {}, - "pcClass": {}, - "chartString": "10000-010000-48254-23797-44--EHNXH" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - } - ] - }, - "actions": { - "lastAction": { - "code": "HIR", - "description": "Hire", - "fromDate": "2021-11-05" - }, - "lastActionReason": { - "code": "WPR", - "description": "With Prior UC Affiliation" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-11-29", - "lastHireDate": "2021-11-29", - "jobAssignedDate": "2021-11-29", - "positionAssignedDate": "2021-11-29", - "expectedEndDate": "2022-12-31", - "endAutomatically": true - }, - "benefits": { - "compositeBenefitRates": [ - { - "earningsType": { - "code": "REG", - "description": "Regular Pay" - }, - "rate": 0.144 - } - ] - }, - "fromDate": "2021-11-29" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/10000007_jobs.json b/spec/data/ucpath/10000007_jobs.json deleted file mode 100644 index 9fcdee6..0000000 --- a/spec/data/ucpath/10000007_jobs.json +++ /dev/null @@ -1,412 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "b5ed8244-47fe-421b-b509-94ac016e69a4", - "timeStamp": "2022-02-07", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10160843" - }, - { - "type": "campus-uid", - "id": "112823" - }, - { - "type": "calnet-id", - "id": "jpatterson" - }, - { - "type": "campus-solutions-id", - "id": "3030582907" - }, - { - "type": "legacy-hr-employee-id", - "id": "011251010" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 0, - "type": { - "code": "4", - "description": "Staff: Limited" - }, - "classification": { - "code": "1", - "description": "Professional & Support Staff" - }, - "position": { - "number": "40144705", - "department": { - "code": "UGARS", - "description": "Undergraduate Admissions" - }, - "description": "ADMISSIONS EVALUATOR 3", - "pool": {}, - "percentOfFullTime": 0.500000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "004511", - "description": "ADMISSIONS EVALUATOR 3" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": { - "code": "J172", - "description": "Student Services" - }, - "function": { - "code": "118", - "description": "Admissions and Recruitment" - }, - "flsaEligibilty": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40196662" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 173, - "maximum": 180, - "status": { - "code": "P", - "description": "Partially Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2021-09-01" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "N", - "description": "Nonexempt" - }, - "percentOfFullTime": 0.500000, - "fullTimeStatus": { - "code": "V", - "description": "Variable" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "UGARS", - "description": "Undergraduate Admissions" - }, - "location": { - "code": "10270", - "description": "Sproul Hall-F01-94726" - }, - "reportsTo": { - "position": { - "number": "40196662", - "department": { - "code": "UGARS", - "description": "Undergraduate Admissions" - }, - "description": "ADMISSIONS RECRMT MGR 2", - "pool": {}, - "employeeRelationship": { - "code": "A", - "description": "Manager, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000303", - "description": "ADMISSIONS RECRMT MGR 2" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": { - "code": "J172", - "description": "Student Services" - }, - "function": { - "code": "118", - "description": "Admissions and Recruitment" - }, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40160283" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2020-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10260827" - }, - { - "type": "campus-uid", - "id": "1694900" - }, - { - "type": "calnet-id", - "id": "abjones" - }, - { - "type": "campus-solutions-id", - "id": "3035471418" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Jones", - "givenName": "Abby", - "middleName": "L", - "fromDate": "2019-09-30" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 20, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": { - "code": "BYA", - "description": "By Agreement Salary Plan", - "active": true, - "fromDate": "1910-01-01" - }, - "grade": { - "code": "BYA", - "description": "By Agreement Job Codes", - "active": true, - "fromDate": "2021-10-25" - }, - "step": { - "code": "0" - } - }, - "rate": { - "base": 24, - "baseFrequency": { - "code": "H", - "description": "Hourly" - }, - "hourly": 24, - "daily": 192, - "monthly": 4176, - "annually": 50112 - }, - "payGroup": { - "code": "1B7", - "description": "UCB 7/40 Non-Exempt Biweekly" - }, - "payType": { - "code": "H", - "description": "Hourly" - }, - "components": [ - { - "rate": { - "code": "UCHRLY", - "base": 24, - "baseFrequency": { - "code": "H", - "description": "Hourly", - "annualFactor": 2088 - } - }, - "percent": 0 - } - ] - }, - "earningsDistribution": { - "distributions": [ - { - "sequence": 1, - "department": { - "code": "UGARS", - "description": "Undergraduate Admissions", - "active": true, - "fromDate": "2021-11-01" - }, - "account": { - "code": "000096901", - "description": "TBD", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "68600", - "description": "Campus General Funds", - "active": true, - "fromDate": "2014-09-01" - }, - "department": { - "code": "17817", - "description": "UGARS Admissions & Reading", - "active": true, - "fromDate": "2021-11-01" - }, - "program": { - "code": "68", - "description": "Student Services", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": { - "code": "UGAPRD", - "description": "Application Readers", - "active": true, - "fromDate": "2018-07-01" - }, - "chartField2": { - "code": "UGRDF", - "description": "App Reading-Freshman", - "active": true, - "fromDate": "2001-07-01" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": { - "code": "UGAPRD", - "description": "Application Readers", - "active": true, - "fromDate": "2018-07-01" - }, - "pcProject": {}, - "pcProduct": {}, - "pcClass": {}, - "chartString": "10000-010000-68600-17817-68-UGAPRD-UGRDF" - } - }, - "earningsType": {}, - "percentage": 100.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-07-01" - } - ] - }, - "actions": { - "lastAction": { - "code": "REH", - "description": "Rehire", - "fromDate": "2021-10-23" - }, - "lastActionReason": { - "code": "REH", - "description": "Rehire, > or = 120 days break" - }, - "lastChangedBy": { - "id": "UC_BATCH" - }, - "initialHireDate": "2018-10-19", - "lastHireDate": "2021-10-25", - "jobAssignedDate": "2021-10-25", - "positionAssignedDate": "2021-10-25", - "expectedEndDate": "2500-02-11", - "endAutomatically": true - }, - "benefits": { - "compositeBenefitRates": [ - { - "earningsType": { - "code": "REG", - "description": "Regular Pay" - }, - "rate": 0.144 - } - ] - }, - "fromDate": "2021-10-25" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/10527060_jobs.json b/spec/data/ucpath/10527060_jobs.json deleted file mode 100644 index 142acd0..0000000 --- a/spec/data/ucpath/10527060_jobs.json +++ /dev/null @@ -1,706 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "dab25623-a725-4687-8b57-1e04d4701ff5", - "timeStamp": "2022-02-01", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10527060" - }, - { - "type": "campus-uid", - "id": "1628831" - }, - { - "type": "calnet-id", - "id": "derakhshan" - }, - { - "type": "campus-solutions-id", - "id": "3034389843" - }, - { - "type": "legacy-hr-employee-id", - "id": "013139999" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 1, - "type": { - "code": "14", - "description": "Academic: Contingent Worker" - }, - "classification": { - "code": "C", - "description": "Not Applicable/CWR" - }, - "position": { - "jobCode": { - "code": { - "code": "CWR011", - "description": "Staff Volunteer", - "active": true, - "fromDate": "2016-01-01" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": {} - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - } - }, - "organizationRelationship": { - "code": "CWR", - "description": "Contingent Worker" - }, - "flsaEligibilty": { - "code": "X", - "description": "No FLSA Required" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "N", - "description": "Not Applicable" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "10001", - "description": "Main Campus-Berkeley-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": {}, - "grade": {}, - "step": { - "code": "0" - } - }, - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - }, - "hourly": 0, - "daily": 0, - "monthly": 0, - "annually": 0 - }, - "payGroup": { - "code": "CWR", - "description": "SYSTEMWIDE CONTINGENT WORKER" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - } - } - } - ] - }, - "actions": { - "lastAction": { - "code": "DTA", - "description": "Data Change", - "fromDate": "2021-10-19" - }, - "lastActionReason": { - "code": "PRI", - "description": "Update Job Indicator" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-10-18", - "lastHireDate": "2021-10-18", - "jobAssignedDate": "2021-10-18", - "expectedEndDate": "2021-11-17", - "endAutomatically": false - }, - "benefits": {}, - "fromDate": "2021-10-18" - }, - { - "number": 1, - "sequence": 0, - "type": { - "code": "23", - "description": "Academic: Post Docs" - }, - "classification": { - "code": "A", - "description": "Academic" - }, - "position": { - "number": "40858087", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "POSTDOC-EMPLOYEE", - "pool": {}, - "percentOfFullTime": 1.000000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "003252", - "description": "POSTDOC-EMPLOYEE" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "flsaEligibilty": {}, - "representation": { - "union": { - "code": "PX", - "description": "Post Doctoral Scholars" - } - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 1, - "maximum": 1, - "status": { - "code": "F", - "description": "Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2021-10-01" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "E", - "description": "Exempt" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "11153", - "description": "Calvin Lab-F01-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": { - "code": "T023", - "description": "Post Doctoral (EE/FEL/PD)", - "active": true, - "fromDate": "1910-01-01" - }, - "grade": { - "code": "L0", - "description": "Post Doctoral Level 0", - "active": true, - "fromDate": "2021-11-29" - }, - "step": { - "code": "0" - } - }, - "rate": { - "base": 5833.333333, - "baseFrequency": { - "code": "UC_FY", - "description": "UC 12/12 - FY" - }, - "hourly": 33.524902, - "daily": 268.199, - "monthly": 5833.333, - "annually": 70000 - }, - "payGroup": { - "code": "1AC", - "description": "UCB Academic Exempt Monthly" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "code": "UCANNL", - "base": 70000, - "baseFrequency": { - "code": "A", - "description": "Annual", - "annualFactor": 1 - } - }, - "percent": 0 - } - ] - }, - "earningsDistribution": { - "distributions": [ - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "000776625", - "description": "User Account 000776625", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "62206", - "description": "NSF Nat-2023505-Peter L -08/25", - "active": true, - "fromDate": "2021-08-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHPXB", - "description": "Bartlett,Peter", - "active": true, - "fromDate": "2006-11-03" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": { - "code": "1017959", - "description": "Collaborative Research: Nation", - "active": true - }, - "pcProduct": { - "code": "GM100", - "description": "Grants Management 10000", - "active": true, - "fromDate": "1900-01-01" - }, - "pcClass": { - "code": "01", - "description": "ACTIVITY - 01", - "active": true, - "fromDate": "1900-01-01" - }, - "chartString": "10000-010000-62206-23797-44--EHPXB" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - }, - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "001147031", - "description": "User Account 001147031", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "48254", - "description": "Haghtalab's J.P. Morgan AI Res", - "active": true, - "fromDate": "2021-07-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHNXH", - "description": "Nika Haghtalab", - "active": true, - "fromDate": "2020-07-01" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": {}, - "pcProduct": {}, - "pcClass": {}, - "chartString": "10000-010000-48254-23797-44--EHNXH" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - } - ] - }, - "actions": { - "lastAction": { - "code": "HIR", - "description": "Hire", - "fromDate": "2021-11-05" - }, - "lastActionReason": { - "code": "WPR", - "description": "With Prior UC Affiliation" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-11-29", - "lastHireDate": "2021-11-29", - "jobAssignedDate": "2021-11-29", - "positionAssignedDate": "2021-11-29", - "expectedEndDate": "2500-12-31", - "endAutomatically": true - }, - "benefits": { - "compositeBenefitRates": [ - { - "earningsType": { - "code": "REG", - "description": "Regular Pay" - }, - "rate": 0.144 - } - ] - }, - "fromDate": "2021-11-29" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/10725309_jobs.json b/spec/data/ucpath/10725309_jobs.json deleted file mode 100644 index 07fd576..0000000 --- a/spec/data/ucpath/10725309_jobs.json +++ /dev/null @@ -1,144 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "8c37994b-3132-4f04-98b0-5ecdc96aec79", - "timeStamp": "2026-02-03", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10725309" - }, - { - "type": "campus-uid", - "id": "10725309" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 0, - "type": { - "code": "4", - "description": "Staff: Limited" - }, - "classification": { - "code": "1", - "description": "Professional & Support Staff" - }, - "position": { - "number": "41195443", - "department": { - "code": "KPADM", - "description": "Library Administration" - }, - "description": "LIBRARY AST 2", - "pool": { - }, - "percentOfFullTime": 1.000000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "006760", - "description": "LIBRARY AST 2" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": { - "code": "J092", - "description": "Library Services" - }, - "function": { - "code": "442", - "description": "Library" - }, - "flsaEligibilty": { - }, - "representation": { - "union": { - "code": "CX", - "description": "Clerical & Allied Services" - } - } - }, - "reportsTo": { - "position": { - "number": "40145569" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 1, - "maximum": 1, - "status": { - "code": "F", - "description": "Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2025-08-22" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "N", - "description": "Nonexempt" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "X", - "description": "Fixed" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "KPADM", - "description": "Library Administration" - }, - "location": { - "code": "10467", - "description": "Bancroft Lib (Doe Anx)-F03-94704" - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "fromDate": "2025-10-28" - } - ] - } - ] -} diff --git a/spec/data/ucpath/10725310_user.json b/spec/data/ucpath/10725310_user.json index a9ea906..aea8682 100644 --- a/spec/data/ucpath/10725310_user.json +++ b/spec/data/ucpath/10725310_user.json @@ -45,6 +45,16 @@ "givenName": "Givenname", "fromDate": "2024-03-26" } + ], + "emails": [ + { + "type": { + "code": "BUSN", + "description": "Business" + }, + "emailAddress": "fakeemail@berkeley.edu", + "primary": true + } ] } ] diff --git a/spec/data/ucpath/123454321_jobs.json b/spec/data/ucpath/123454321_jobs.json deleted file mode 100644 index 49b5a90..0000000 --- a/spec/data/ucpath/123454321_jobs.json +++ /dev/null @@ -1,706 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "dab25623-a725-4687-8b57-1e04d4701ff5", - "timeStamp": "2022-02-01", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "123454321" - }, - { - "type": "campus-uid", - "id": "1628831" - }, - { - "type": "calnet-id", - "id": "derakhshan" - }, - { - "type": "campus-solutions-id", - "id": "3034389843" - }, - { - "type": "legacy-hr-employee-id", - "id": "013139999" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 1, - "type": { - "code": "14", - "description": "Academic: Contingent Worker" - }, - "classification": { - "code": "C", - "description": "Not Applicable/CWR" - }, - "position": { - "jobCode": { - "code": { - "code": "CWR011", - "description": "Staff Volunteer", - "active": true, - "fromDate": "2016-01-01" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": {} - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - } - }, - "organizationRelationship": { - "code": "CWR", - "description": "Contingent Worker" - }, - "flsaEligibilty": { - "code": "X", - "description": "No FLSA Required" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "N", - "description": "Not Applicable" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "10001", - "description": "Main Campus-Berkeley-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "F", - "description": "FAKE" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": {}, - "grade": {}, - "step": { - "code": "0" - } - }, - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - }, - "hourly": 0, - "daily": 0, - "monthly": 0, - "annually": 0 - }, - "payGroup": { - "code": "CWR", - "description": "SYSTEMWIDE CONTINGENT WORKER" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - } - } - } - ] - }, - "actions": { - "lastAction": { - "code": "DTA", - "description": "Data Change", - "fromDate": "2021-10-19" - }, - "lastActionReason": { - "code": "PRI", - "description": "Update Job Indicator" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-10-18", - "lastHireDate": "2021-10-18", - "jobAssignedDate": "2021-10-18", - "expectedEndDate": "2021-11-17", - "endAutomatically": false - }, - "benefits": {}, - "fromDate": "2021-10-18" - }, - { - "number": 1, - "sequence": 0, - "type": { - "code": "23", - "description": "Academic: Post Docs" - }, - "classification": { - "code": "A", - "description": "Academic" - }, - "position": { - "number": "40858087", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "POSTDOC-EMPLOYEE", - "pool": {}, - "percentOfFullTime": 1.000000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "003252", - "description": "POSTDOC-EMPLOYEE" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "flsaEligibilty": {}, - "representation": { - "union": { - "code": "PX", - "description": "Post Doctoral Scholars" - } - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 1, - "maximum": 1, - "status": { - "code": "F", - "description": "Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2021-10-01" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "E", - "description": "Exempt" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "11153", - "description": "Calvin Lab-F01-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": { - "code": "T023", - "description": "Post Doctoral (EE/FEL/PD)", - "active": true, - "fromDate": "1910-01-01" - }, - "grade": { - "code": "L0", - "description": "Post Doctoral Level 0", - "active": true, - "fromDate": "2021-11-29" - }, - "step": { - "code": "0" - } - }, - "rate": { - "base": 5833.333333, - "baseFrequency": { - "code": "UC_FY", - "description": "UC 12/12 - FY" - }, - "hourly": 33.524902, - "daily": 268.199, - "monthly": 5833.333, - "annually": 70000 - }, - "payGroup": { - "code": "1AC", - "description": "UCB Academic Exempt Monthly" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "code": "UCANNL", - "base": 70000, - "baseFrequency": { - "code": "A", - "description": "Annual", - "annualFactor": 1 - } - }, - "percent": 0 - } - ] - }, - "earningsDistribution": { - "distributions": [ - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "000776625", - "description": "User Account 000776625", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "62206", - "description": "NSF Nat-2023505-Peter L -08/25", - "active": true, - "fromDate": "2021-08-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHPXB", - "description": "Bartlett,Peter", - "active": true, - "fromDate": "2006-11-03" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": { - "code": "1017959", - "description": "Collaborative Research: Nation", - "active": true - }, - "pcProduct": { - "code": "GM100", - "description": "Grants Management 10000", - "active": true, - "fromDate": "1900-01-01" - }, - "pcClass": { - "code": "01", - "description": "ACTIVITY - 01", - "active": true, - "fromDate": "1900-01-01" - }, - "chartString": "10000-010000-62206-23797-44--EHPXB" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - }, - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "001147031", - "description": "User Account 001147031", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "48254", - "description": "Haghtalab's J.P. Morgan AI Res", - "active": true, - "fromDate": "2021-07-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHNXH", - "description": "Nika Haghtalab", - "active": true, - "fromDate": "2020-07-01" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": {}, - "pcProduct": {}, - "pcClass": {}, - "chartString": "10000-010000-48254-23797-44--EHNXH" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - } - ] - }, - "actions": { - "lastAction": { - "code": "HIR", - "description": "Hire", - "fromDate": "2021-11-05" - }, - "lastActionReason": { - "code": "WPR", - "description": "With Prior UC Affiliation" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-11-29", - "lastHireDate": "2021-11-29", - "jobAssignedDate": "2021-11-29", - "positionAssignedDate": "2021-11-29", - "expectedEndDate": "2500-12-31", - "endAutomatically": true - }, - "benefits": { - "compositeBenefitRates": [ - { - "earningsType": { - "code": "REG", - "description": "Regular Pay" - }, - "rate": 0.144 - } - ] - }, - "fromDate": "2021-11-29" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/12345678_jobs.json b/spec/data/ucpath/12345678_jobs.json deleted file mode 100644 index 1d76e35..0000000 --- a/spec/data/ucpath/12345678_jobs.json +++ /dev/null @@ -1,706 +0,0 @@ -{ - "source": "UCB-HR-PATH-DB", - "correlationId": "dab25623-a725-4687-8b57-1e04d4701ff5", - "timeStamp": "2022-02-01", - "httpStatus": { - "code": "200", - "description": "OK" - }, - "response": [ - { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10527060" - }, - { - "type": "campus-uid", - "id": "1628831" - }, - { - "type": "calnet-id", - "id": "derakhshan" - }, - { - "type": "campus-solutions-id", - "id": "3034389843" - }, - { - "type": "legacy-hr-employee-id", - "id": "013139999" - } - ], - "jobs": [ - { - "number": 0, - "sequence": 1, - "type": { - "code": "14", - "description": "Academic: Contingent Worker" - }, - "classification": { - "code": "C", - "description": "Not Applicable/CWR" - }, - "position": { - "jobCode": { - "code": { - "code": "CWR011", - "description": "Staff Volunteer", - "active": true, - "fromDate": "2016-01-01" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": {} - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - } - }, - "organizationRelationship": { - "code": "CWR", - "description": "Contingent Worker" - }, - "flsaEligibilty": { - "code": "X", - "description": "No FLSA Required" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "N", - "description": "Not Applicable" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "10001", - "description": "Main Campus-Berkeley-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "F", - "description": "FAKE" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": {}, - "grade": {}, - "step": { - "code": "0" - } - }, - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - }, - "hourly": 0, - "daily": 0, - "monthly": 0, - "annually": 0 - }, - "payGroup": { - "code": "CWR", - "description": "SYSTEMWIDE CONTINGENT WORKER" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "base": 0, - "baseFrequency": { - "code": "M", - "description": "Monthly" - } - } - } - ] - }, - "actions": { - "lastAction": { - "code": "DTA", - "description": "Data Change", - "fromDate": "2021-10-19" - }, - "lastActionReason": { - "code": "PRI", - "description": "Update Job Indicator" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-10-18", - "lastHireDate": "2021-10-18", - "jobAssignedDate": "2021-10-18", - "expectedEndDate": "2021-11-17", - "endAutomatically": false - }, - "benefits": {}, - "fromDate": "2021-10-18" - }, - { - "number": 1, - "sequence": 0, - "type": { - "code": "23", - "description": "Academic: Post Docs" - }, - "classification": { - "code": "A", - "description": "Academic" - }, - "position": { - "number": "40858087", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "POSTDOC-EMPLOYEE", - "pool": {}, - "percentOfFullTime": 1.000000, - "employeeRelationship": { - "code": "E", - "description": "All Others, Not Confidential" - }, - "jobCode": { - "code": { - "code": "003252", - "description": "POSTDOC-EMPLOYEE" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "flsaEligibilty": {}, - "representation": { - "union": { - "code": "PX", - "description": "Post Doctoral Scholars" - } - } - }, - "reportsTo": { - "position": { - "number": "40147407" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "active": 1, - "maximum": 1, - "status": { - "code": "F", - "description": "Filled" - } - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2021-10-01" - }, - "organizationRelationship": { - "code": "EMP", - "description": "Employee" - }, - "flsaEligibilty": { - "code": "E", - "description": "Exempt" - }, - "percentOfFullTime": 1.000000, - "fullTimeStatus": { - "code": "F", - "description": "System Default - Select Value" - }, - "permanent": { - "code": "R", - "description": "Not Applicable" - }, - "primary": { - "code": "P", - "description": "Primary Job" - }, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "location": { - "code": "11153", - "description": "Calvin Lab-F01-94720" - }, - "reportsTo": { - "position": { - "number": "40147407", - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC" - }, - "description": "ASSOC DIRECTOR", - "pool": {}, - "employeeRelationship": { - "code": "C", - "description": "Supervisor, Not Confidential" - }, - "jobCode": { - "code": { - "code": "000910", - "description": "ASSOC DIRECTOR" - }, - "status": { - "code": "A", - "description": "Active" - }, - "family": {}, - "function": {}, - "representation": { - "union": { - "code": "99", - "description": "Non-Represented" - } - } - }, - "reportsTo": { - "position": { - "number": "40143436" - } - }, - "status": { - "code": "A", - "description": "Approved" - }, - "headCount": { - "maximum": 1 - }, - "active": { - "code": "A", - "description": "Active" - }, - "fromDate": "2018-07-01" - }, - "supervisor": { - "identifiers": [ - { - "type": "hr-employee-id", - "id": "10147257" - }, - { - "type": "campus-uid", - "id": "215062" - }, - { - "type": "calnet-id", - "id": "peter" - }, - { - "type": "campus-solutions-id", - "id": "3030848237" - }, - { - "type": "legacy-hr-employee-id", - "id": "011601893" - } - ], - "names": [ - { - "type": { - "code": "PRI", - "description": "Primary" - }, - "familyName": "Bartlett", - "givenName": "Peter", - "middleName": "Leslie", - "fromDate": "2021-07-01" - } - ] - } - }, - "status": { - "hrStatus": { - "code": "A", - "description": "Active" - }, - "employmentStatus": { - "code": "A", - "description": "Active" - }, - "benefitsStatus": { - "code": "A", - "description": "Active" - } - }, - "compensation": { - "standardHours": { - "hours": 40, - "frequency": { - "code": "W", - "description": "Weekly" - } - }, - "salary": { - "administrationPlan": { - "code": "T023", - "description": "Post Doctoral (EE/FEL/PD)", - "active": true, - "fromDate": "1910-01-01" - }, - "grade": { - "code": "L0", - "description": "Post Doctoral Level 0", - "active": true, - "fromDate": "2021-11-29" - }, - "step": { - "code": "0" - } - }, - "rate": { - "base": 5833.333333, - "baseFrequency": { - "code": "UC_FY", - "description": "UC 12/12 - FY" - }, - "hourly": 33.524902, - "daily": 268.199, - "monthly": 5833.333, - "annually": 70000 - }, - "payGroup": { - "code": "1AC", - "description": "UCB Academic Exempt Monthly" - }, - "payType": { - "code": "S", - "description": "Salaried" - }, - "components": [ - { - "rate": { - "code": "UCANNL", - "base": 70000, - "baseFrequency": { - "code": "A", - "description": "Annual", - "annualFactor": 1 - } - }, - "percent": 0 - } - ] - }, - "earningsDistribution": { - "distributions": [ - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "000776625", - "description": "User Account 000776625", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "62206", - "description": "NSF Nat-2023505-Peter L -08/25", - "active": true, - "fromDate": "2021-08-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHPXB", - "description": "Bartlett,Peter", - "active": true, - "fromDate": "2006-11-03" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": { - "code": "1017959", - "description": "Collaborative Research: Nation", - "active": true - }, - "pcProduct": { - "code": "GM100", - "description": "Grants Management 10000", - "active": true, - "fromDate": "1900-01-01" - }, - "pcClass": { - "code": "01", - "description": "ACTIVITY - 01", - "active": true, - "fromDate": "1900-01-01" - }, - "chartString": "10000-010000-62206-23797-44--EHPXB" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - }, - { - "sequence": 1, - "department": { - "code": "SMTOC", - "description": "Simons Institute TOC", - "active": true, - "fromDate": "1910-01-01" - }, - "account": { - "code": "001147031", - "description": "User Account 001147031", - "glAccount": { - "businessUnit": { - "code": "10000", - "description": "UC Berkeley", - "active": true, - "fromDate": "1900-01-01" - }, - "account": { - "code": "010000", - "description": "010000" - }, - "fund": { - "code": "48254", - "description": "Haghtalab's J.P. Morgan AI Res", - "active": true, - "fromDate": "2021-07-01" - }, - "department": { - "code": "23797", - "description": "EERES Computer Science", - "active": true, - "fromDate": "2018-09-01" - }, - "program": { - "code": "44", - "description": "Organized & Sponsored Research", - "active": true, - "fromDate": "1900-01-02" - }, - "chartField1": {}, - "chartField2": { - "code": "EHNXH", - "description": "Nika Haghtalab", - "active": true, - "fromDate": "2020-07-01" - }, - "chartField3": { - "code": "BKFIN", - "description": "Berkeley Financial", - "active": true, - "fromDate": "1901-01-01" - }, - "project": {}, - "pcProject": {}, - "pcProduct": {}, - "pcClass": {}, - "chartString": "10000-010000-48254-23797-44--EHNXH" - } - }, - "earningsType": {}, - "percentage": 50.000000, - "fiscalYear": "2022", - "effectiveSequence": 0, - "fromDate": "2021-11-29" - } - ] - }, - "actions": { - "lastAction": { - "code": "HIR", - "description": "Hire", - "fromDate": "2021-11-05" - }, - "lastActionReason": { - "code": "WPR", - "description": "With Prior UC Affiliation" - }, - "lastChangedBy": { - "id": "UC_E351_PRCS" - }, - "initialHireDate": "2021-11-29", - "lastHireDate": "2021-11-29", - "jobAssignedDate": "2021-11-29", - "positionAssignedDate": "2021-11-29", - "expectedEndDate": "2500-12-31", - "endAutomatically": true - }, - "benefits": { - "compositeBenefitRates": [ - { - "earningsType": { - "code": "REG", - "description": "Regular Pay" - }, - "rate": 0.144 - } - ] - }, - "fromDate": "2021-11-29" - } - ] - } - ] -} \ No newline at end of file diff --git a/spec/data/ucpath/10000004_jobs.json b/spec/data/ucpath/active_employee_jobs.json similarity index 100% rename from spec/data/ucpath/10000004_jobs.json rename to spec/data/ucpath/active_employee_jobs.json diff --git a/spec/data/ucpath/10000005_jobs.json b/spec/data/ucpath/active_employee_no_end_date_jobs.json similarity index 100% rename from spec/data/ucpath/10000005_jobs.json rename to spec/data/ucpath/active_employee_no_end_date_jobs.json diff --git a/spec/data/ucpath/10000008_jobs.json b/spec/data/ucpath/contingent_worker_jobs.json similarity index 100% rename from spec/data/ucpath/10000008_jobs.json rename to spec/data/ucpath/contingent_worker_jobs.json diff --git a/spec/data/ucpath/10145074_jobs.json b/spec/data/ucpath/multiple_ineligible_jobs.json similarity index 100% rename from spec/data/ucpath/10145074_jobs.json rename to spec/data/ucpath/multiple_ineligible_jobs.json diff --git a/spec/data/ucpath/10601882_jobs.json b/spec/data/ucpath/priority_job_selected_jobs.json similarity index 100% rename from spec/data/ucpath/10601882_jobs.json rename to spec/data/ucpath/priority_job_selected_jobs.json diff --git a/spec/data/ucpath/888888888_jobs.json b/spec/data/ucpath/terminated_before_purge_jobs.json similarity index 100% rename from spec/data/ucpath/888888888_jobs.json rename to spec/data/ucpath/terminated_before_purge_jobs.json diff --git a/spec/data/ucpath/generic_jobs_2.json b/spec/data/ucpath/user_group_base_jobs.json similarity index 100% rename from spec/data/ucpath/generic_jobs_2.json rename to spec/data/ucpath/user_group_base_jobs.json diff --git a/spec/data/ucpath/10725310_jobs.json b/spec/data/ucpath/zero_full_time_jobs.json similarity index 100% rename from spec/data/ucpath/10725310_jobs.json rename to spec/data/ucpath/zero_full_time_jobs.json diff --git a/spec/data/ucpath/999999999_jobs.json b/spec/data/ucpath/zero_jobs.json similarity index 100% rename from spec/data/ucpath/999999999_jobs.json rename to spec/data/ucpath/zero_jobs.json diff --git a/spec/ldap_helper.rb b/spec/ldap_helper.rb index 40f390f..99c9a39 100644 --- a/spec/ldap_helper.rb +++ b/spec/ldap_helper.rb @@ -34,3 +34,16 @@ def stub_ldap(id) ldap_rec end + +def stub_ldap_entries(ldap_id, entries) + ldap_stub = stub_ldap(ldap_id) + ldap_conn = ldap_stub['connection'] + + allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_conn) + expect(ldap_conn).to receive(:bind) + expect(ldap_conn).to receive(:search).with(ldap_stub['base']) do |_, &block| + entries.each { |entry| block.call(entry) } + end + + ldap_stub +end diff --git a/spec/lib/alma_spec.rb b/spec/lib/alma_spec.rb index 2dd4401..cb91010 100644 --- a/spec/lib/alma_spec.rb +++ b/spec/lib/alma_spec.rb @@ -62,7 +62,7 @@ it 'creates an Alma XMLBuilder Object' do ucpath_id = '10000004' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') # Mock LDAP fetch and return nil for this record.... ldap_id = '112823' @@ -72,7 +72,7 @@ ucpath_id = '10000007' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') # Mock fake LDAP rec to make sure we don't have an email/phone # for this record... diff --git a/spec/lib/ucpath_spec.rb b/spec/lib/ucpath_spec.rb index d30ff63..5dd4fc8 100644 --- a/spec/lib/ucpath_spec.rb +++ b/spec/lib/ucpath_spec.rb @@ -2,7 +2,7 @@ require 'stub_helper' require 'ldap_helper' -# rubocop :disable Lint/ConstantDefinitionInBlock, Style/MutableConstant, Metrics/BlockLength: +# rubocop:disable Lint/ConstantDefinitionInBlock, Style/MutableConstant, Metrics/BlockLength describe UCPath do it 'does not create a file if changelog returns zero records' do stub_empty_change_log('2022-04-10', '2022-04-13') @@ -15,21 +15,21 @@ UCPath.run_ucpath setup - expect(File.exist?(setup.zip_path)).to eq(false) - expect(File.exist?(setup.xml_path)).to eq(false) + expect(File.exist?(setup.zip_path)).to be(false) + expect(File.exist?(setup.xml_path)).to be(false) end end it 'runs ucpath' do stub_change_log('2022-04-10', '2022-04-13', 'change_log_1') stub_ucpath_user('10000003') - stub_ucpath_jobs('10000003') + stub_ucpath_jobs('10000003', fixture: 'active_employee_jobs.json') stub_ucpath_user('10000004') - stub_ucpath_jobs('10000004') + stub_ucpath_jobs('10000004', fixture: 'active_employee_jobs.json') # Mock LDAP - allow(LDAP::API).to receive('fetch_ldap_rec').with('112823').and_return(nil) - allow(LDAP::API).to receive('fetch_ldap_rec').with('1628831').and_return(nil) + allow(LDAP::API).to receive(:fetch_ldap_rec).with('112823').and_return(nil) + allow(LDAP::API).to receive(:fetch_ldap_rec).with('1628831').and_return(nil) Dir.mktmpdir do |dir| outpath = Pathname.new(dir) @@ -43,17 +43,17 @@ expected_file = File.read('spec/data/ucpath/expected_xml_1.xml') expected_file.gsub!(%r{2022-04-19}, "#{Date.today}") - expect(File.exist?(setup.zip_path)).to eq(true) + expect(File.exist?(setup.zip_path)).to be(true) end end it 'runs ucpath for a specific user' do id = '10000005' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'active_employee_jobs.json') # Mock LDAP - allow(LDAP::API).to receive('fetch_ldap_rec').with('112823').and_return(nil) + allow(LDAP::API).to receive(:fetch_ldap_rec).with('112823').and_return(nil) Dir.mktmpdir do |dir| outpath = Pathname.new(dir) @@ -62,11 +62,11 @@ setup = Helpers::Setup.new UCPath.run_ucpath setup - expect(File.exist?(setup.zip_path)).to eq(true) + expect(File.exist?(setup.zip_path)).to be(true) end end end -# rubocop :enable Lint/ConstantDefinitionInBlock, Style/MutableConstant, Metrics/BlockLength: +# rubocop:enable Lint/ConstantDefinitionInBlock, Style/MutableConstant, Metrics/BlockLength describe UCPath::API do it 'creates a change log' do @@ -90,13 +90,13 @@ stub_ucpath_user(id) stub_ucpath_jobs_rate(id) u = UCPath::User.new(id) - expect(u.jobs).to eq(nil) + expect(u.jobs).to be_nil end end # rubocop:disable Metrics/BlockLength describe UCPath::User do - before(:each) do + before do allow(Config.secrets.ldap).to receive(:pass).and_return('MISSING') end @@ -104,29 +104,23 @@ id = '10527060' ldap_id = '1628831' stub_ucpath_user(id) - stub_ucpath_jobs(id) - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) + stub_ucpath_jobs(id, fixture: 'active_employee_jobs.json') + allow(LDAP::API).to receive(:fetch_ldap_rec).with(ldap_id).and_return(nil) u = UCPath::User.new(id) expect(u).to be_kind_of(User) end - it 'weeds out student affliated users' do + it 'weeds out student affiliated users' do ucpath_id = '10527060' - - # Stub our LDAP ldap_id = '1628831' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'berkeleyeduaffiliations' => ['STUDENT-TYPE-REGISTERED'] } - ] stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]) + stub_ldap_entries(ldap_id, [ + { 'berkeleyeduaffiliations' => ['STUDENT-TYPE-REGISTERED'] } + ]) u = UCPath::User.new(ucpath_id) expect(u.eligible?).to be(false) @@ -134,20 +128,16 @@ it 'weeds out users without an email address' do ucpath_id = '123454321' + ldap_id = '1628831' + stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - # Stub LDAP - ldap_id = '1628831' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] }, - { 'berkeleyedualternateid' => [''] } # No email address - ] - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]).and_yield(entries[1]).and_yield(entries[2]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] }, + { 'berkeleyedualternateid' => [''] } # No email address + ]) u = UCPath::User.new(ucpath_id) expect(u.eligible?).to be(false) @@ -155,173 +145,120 @@ it 'uses names from ldap if missing names in ucpath record' do ucpath_id = '12345678' - stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub our LDAP - ldap_id = '1628831' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] - - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]).and_yield(entries[1]) - - u = UCPath::User.new(ucpath_id) - expect(u.rec.first_name).to eq('test_first_name') - expect(u.rec.last_name).to eq('test_last_name') - end - - # Collapse these into a single array driven test - it 'sets user group libstaff' do - ucpath_id = '10527060' - ldap_id = '1628831' - stub_ucpath_user(ucpath_id) - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => '000118' - }) - - u = UCPath::User.new(ucpath_id) - - expect(u.rec.user_group).to eq('LIBSTAFF') - end - - it 'sets user group UCBVISSCHOL' do - ucpath_id = '10527060' - stub_ucpath_user(ucpath_id) - - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => 'CWR003' - }) - - u = UCPath::User.new(ucpath_id) - - expect(u.rec.user_group).to eq('UCBVISSCHOL') - end - - it 'sets user group UCBAFFILI' do - ucpath_id = '10527060' - stub_ucpath_user(ucpath_id) - - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => 'CWR022' - }) - - u = UCPath::User.new(ucpath_id) - - expect(u.rec.user_group).to eq('UCBAFFILI') - end - - it 'sets user group UCEXT' do - ucpath_id = '10527060' - stub_ucpath_user(ucpath_id) - - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => 'dummycode', - 'dept_code' => 'EXADM', - 'classification_indc' => 'A' - }) - - u = UCPath::User.new(ucpath_id) - expect(u.rec.user_group).to eq('UCEXT') - end - - it 'sets user group FACULTY' do - ucpath_id = '10527060' - stub_ucpath_user(ucpath_id) - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => '001132' - }) - - u = UCPath::User.new(ucpath_id) - expect(u.rec.user_group).to eq('FACULTY') - end - it 'sets user group EXECUTIVE' do - ucpath_id = '10527060' stub_ucpath_user(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) - - override_jobs_stub(ucpath_id, - { - 'job_code' => 'dummycode', - 'dept_code' => 'dummycode', - 'classification_indc' => '2' - }) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) u = UCPath::User.new(ucpath_id) - expect(u.rec.user_group).to eq('EXECUTIVE') + expect(u.rec.first_name).to eq('test_first_name') + expect(u.rec.last_name).to eq('test_last_name') end - it 'sets user group NONACAD' do - ucpath_id = '10527060' - stub_ucpath_user(ucpath_id) - - ldap_id = '1628831' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) + describe 'user group assignment' do + let(:ucpath_id) { '10527060' } + let(:ldap_id) { '1628831' } - override_jobs_stub(ucpath_id, { - 'job_code' => 'dummycode', - 'dept_code' => 'dummycode', - 'classification_indc' => 'dummycode' - }) + before do + stub_ucpath_user(ucpath_id) + allow(LDAP::API).to receive(:fetch_ldap_rec).with(ldap_id).and_return(nil) + end - u = UCPath::User.new(ucpath_id) - expect(u.rec.user_group).to eq('NONACAD') + [ + { + description: 'LIBSTAFF', + overrides: { job_code: '000118' }, + expected_group: 'LIBSTAFF' + }, + { + description: 'UCB POST', + overrides: { job_code: '003252' }, + expected_group: 'UCB POST' + }, + { + description: 'UCBVISSCHOL', + overrides: { job_code: 'CWR003' }, + expected_group: 'UCBVISSCHOL' + }, + { + description: 'UCBAFFILI', + overrides: { job_code: 'CWR022' }, + expected_group: 'UCBAFFILI' + }, + { + description: 'UCEXT', + overrides: { + job_code: 'dummycode', + dept_code: 'EXADM', + classification_indc: 'A' + }, + expected_group: 'UCEXT' + }, + { + description: 'FACULTY', + overrides: { job_code: '001132' }, + expected_group: 'FACULTY' + }, + { + description: 'EXECUTIVE', + overrides: { + job_code: 'dummycode', + dept_code: 'dummycode', + classification_indc: '2' + }, + expected_group: 'EXECUTIVE' + }, + { + description: 'NONACAD', + overrides: { + job_code: 'dummycode', + dept_code: 'dummycode', + classification_indc: 'dummycode' + }, + expected_group: 'NONACAD' + } + ].each do |row| + it "sets user group #{row[:description]}" do + stub_ucpath_jobs( + ucpath_id, + fixture: 'user_group_base_jobs.json', + overrides: row[:overrides] + ) + + u = UCPath::User.new(ucpath_id) + + expect(u.rec.user_group).to eq(row[:expected_group]) + end + end end it 'uses the ldap phone number' do ucpath_id = '12345678' ldap_id = '1628831' + stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap(ldap_id) - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] }, - { 'telephonenumber' => ['925-555-1234'] }, - { 'berkeleyedualternateid' => ['fake@email.edu'] } - ] + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]).and_yield(entries[2]).and_yield(entries[3]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] }, + { 'telephonenumber' => ['925-555-1234'] }, + { 'berkeleyedualternateid' => ['fake@email.edu'] } + ]) u = UCPath::User.new(ucpath_id) expect(u.rec.contact_info.phones.phone_number).to eq('925-555-1234') end it 'handles all known mangled telephone formats' do + ucpath_id = '12345678' + ldap_id = '1628831' + known_phone_formats = [ '510 645-1234', '5106451234', @@ -330,25 +267,14 @@ ] known_phone_formats.each do |number| - ucpath_id = '12345678' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap('1628831') - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] }, - { 'telephonenumber' => [number.to_s] } - ] - - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]).and_yield(entries[2]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] }, + { 'telephonenumber' => [number] } + ]) u = UCPath::User.new(ucpath_id) expect(u.rec.contact_info.phones.phone_number).to eq('510-645-1234') @@ -359,22 +285,12 @@ ucpath_id = '10000004' ldap_id = '112823' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap(ldap_id) - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] - - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) u = UCPath::User.new(ucpath_id) expect(u.rec.contact_info.phones.preferred).to eq('false') @@ -383,23 +299,14 @@ it 'handles primary phone number preferred attribute' do ucpath_id = '10000005' ldap_id = '112823' - stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap(ldap_id) - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] + stub_ucpath_user(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) u = UCPath::User.new(ucpath_id) expect(u.rec.contact_info.phones.preferred).to eq('true') @@ -409,22 +316,12 @@ ucpath_id = '10000005' ldap_id = '112823' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap(ldap_id) - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] - - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_no_end_date_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) current_year = Date.today.year expiration_year = current_year + 1 @@ -439,22 +336,12 @@ ucpath_id = '10000005' ldap_id = '112823' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) - - # Stub LDAP - ldap_stub = stub_ldap(ldap_id) - ldap_params = ldap_stub['params'] - ldap_conn = ldap_stub['connection'] - ldap_base = ldap_stub['base'] - - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_no_end_date_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_params).and_return(ldap_conn) - expect(ldap_conn).to receive(:bind) - expect(ldap_conn).to receive(:search).with(ldap_base).and_yield(entries[0]).and_yield(entries[1]) + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) current_year = Date.today.year expiration_year = current_year + 2 @@ -467,20 +354,15 @@ it 'logs an error if the ucpath record is missing a required field' do id = '10000006' - stub_ucpath_user(id) - stub_ucpath_jobs(id) - - # Stub our LDAP ldap_id = '1628831' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]).and_yield(entries[1]) + stub_ucpath_user(id) + stub_ucpath_jobs(id, fixture: 'active_employee_jobs.json') + + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) u = UCPath::User.new(id) expect(u.errors).to include("#{id} - Missing required field: ucpath_employee_id") @@ -496,7 +378,7 @@ it 'LDAP::API returns nil if fetch encounters an error' do ucpath_id = '10527060' stub_ucpath_user(ucpath_id) - stub_ucpath_jobs(ucpath_id) + stub_ucpath_jobs(ucpath_id, fixture: 'active_employee_jobs.json') allow(Net::LDAP).to receive(:new).and_raise(StandardError.new('error')) u = UCPath::User.new(ucpath_id) expect(u.ldap).to be_nil @@ -504,20 +386,15 @@ it 'returns the first job if no eligible jobs are found' do id = '10145074' - stub_ucpath_user(id) - stub_ucpath_jobs(id) - - # Stub our LDAP ldap_id = '7165' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'sn' => ['test_last_name'] }, - { 'givenname' => ['test_first_name'] } - ] - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]).and_yield(entries[1]) + stub_ucpath_user(id) + stub_ucpath_jobs(id, fixture: 'multiple_ineligible_jobs.json') + + stub_ldap_entries(ldap_id, [ + { 'sn' => ['test_last_name'] }, + { 'givenname' => ['test_first_name'] } + ]) u = UCPath::User.new(id) expect(u.rec.job_description).to eq('FIRST_JOB_DESCRIPTION') @@ -526,7 +403,7 @@ it 'skips a user if no jobs are found' do id = '999999999' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'zero_jobs.json') u = UCPath::User.new(id) @@ -536,7 +413,7 @@ it 'skips users that have a termination date before the last Alma purge date' do id = '888888888' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'terminated_before_purge_jobs.json') u = UCPath::User.new(id) @@ -546,11 +423,11 @@ it 'skips users with a contingent worker job code' do id = '10000008' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'contingent_worker_jobs.json') # Mock LDAP ldap_id = '112823' - allow(LDAP::API).to receive('fetch_ldap_rec').with(ldap_id).and_return(nil) + allow(LDAP::API).to receive(:fetch_ldap_rec).with(ldap_id).and_return(nil) u = UCPath::User.new(id) expect(u.eligible?).to be(false) @@ -558,30 +435,23 @@ it 'eligibility should be true for priority jobs even if the user has a student affiliation' do id = '10601882' - - # Stub our LDAP ldap_id = '1772216' - ldap_stub = stub_ldap(ldap_id) - entries = [ - { 'berkeleyeduaffiliations' => ['STUDENT-TYPE-REGISTERED'] } - ] stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'priority_job_selected_jobs.json') - allow(Net::LDAP).to receive(:new).with(ldap_stub['params']).and_return(ldap_stub['connection']) - expect(ldap_stub['connection']).to receive(:bind) - expect(ldap_stub['connection']).to receive(:search).with(ldap_stub['base']).and_yield(entries[0]) + stub_ldap_entries(ldap_id, [ + { 'berkeleyeduaffiliations' => ['STUDENT-TYPE-REGISTERED'] } + ]) u = UCPath::User.new(id) - expect(u.eligible?).to be(true) end it 'skips with VOID in first and last name fields' do id = '10725309' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'active_employee_jobs.json') u = UCPath::User.new(id) expect(u.eligible?).to be(false) @@ -590,7 +460,7 @@ it 'skips with zero Percentage of FullTime' do id = '10725310' stub_ucpath_user(id) - stub_ucpath_jobs(id) + stub_ucpath_jobs(id, fixture: 'zero_full_time_jobs.json') u = UCPath::User.new(id) expect(u.eligible?).to be(false) diff --git a/spec/stub_helper.rb b/spec/stub_helper.rb index bffa98d..a31f154 100644 --- a/spec/stub_helper.rb +++ b/spec/stub_helper.rb @@ -3,114 +3,107 @@ require 'json' require 'webmock' -# TODO: see if I can set this up to allow for overrides -# e.g., stub_ucpath_user(id, {'name' => 'Rickey Bobby'}) -def stub_ucpath_user(id) - user_api_url = "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}?id-type=hr-employee-id" +def fixture_path(*parts) + File.join('spec', 'data', *parts) +end - stub_request(:get, user_api_url).to_return( - status: 200, - body: File.new("spec/data/ucpath/#{id}_user.json") - ) +def fixture_body(*parts) + File.read(fixture_path(*parts)) end -def stub_ucpath_missing_user(id) - user_api_url = "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}?id-type=hr-employee-id" +def fixture_json(*parts) + JSON.parse(fixture_body(*parts)) +end - stub_request(:get, user_api_url).to_return( - status: 400 - ) +def ucpath_user_url(id) + "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}?id-type=hr-employee-id" end -def stub_ucpath_jobs(id) - user_api_url = "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}/jobs?id-type=hr-employee-id" +def ucpath_jobs_url(id) + "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}/jobs?id-type=hr-employee-id" +end - stub_request(:get, user_api_url).to_return( - status: 200, - body: File.new("spec/data/ucpath/#{id}_jobs.json") - ) +def ucpath_change_log_url(start_date, end_date) + "https://gateway.api.berkeley.edu/hr/v3/employees?change-from=#{start_date}&change-to=#{end_date}&page-number=1&page-size=200" end -def stub_ucpath_jobs_rate(id) - user_api_url = "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}/jobs?id-type=hr-employee-id" +def sis_data_url(term_id, page_num) + "https://gateway.api.berkeley.edu/sis/v2/students?affiliation-status=ALL&inc-acad=true&inc-cntc=true&inc-regs=true&page-number=#{page_num}&page-size=50&term-id=#{term_id}" +end + +def sis_past_data_url(term_id, as_of_date, page_num) + "https://gateway.api.berkeley.edu/sis/v2/students?as-of-date=#{as_of_date}&affiliation-status=ALL&inc-acad=true&inc-cntc=true&inc-regs=true&page-number=#{page_num}&page-size=50&term-id=#{term_id}" +end - stub_request(:get, user_api_url).to_return( - status: 429 +def stub_get(url, status: 200, body: nil) + stub_request(:get, url).to_return( + status: status, + body: body ) end -# Recieves ID and "overrides" where we can set certain fields in the -# fixture at runtime so I don't have to create separate fixtures. -# rubocop:disable Metrics/MethodLength, Metrics/AbcSize -def override_jobs_stub(id, *overrides) - user_api_url = "https://gateway.api.berkeley.edu/hr/v3/employees/#{id}/jobs?id-type=hr-employee-id" - - body = File.read('spec/data/ucpath/generic_jobs_2.json') - json_body = JSON.parse(body) - - if overrides && overrides[0] - overrides[0].each_key do |key| - case key - when 'job_code' - # jpath: '$.position.jobCode.code.code' - json_body['response'][0]['jobs'][0]['position']['jobCode']['code']['code'] = overrides[0]['job_code'] - when 'dept_code' - # jpath: '$.department.code' - json_body['response'][0]['jobs'][0]['department']['code'] = overrides[0]['dept_code'] - when 'classification_indc' - # jpath: '$.classification.code' - json_body['response'][0]['jobs'][0]['classification']['code'] = overrides[0]['classification_indc'] - end - end +def stub_ucpath_user(id) + stub_get(ucpath_user_url(id), status: 200, body: fixture_body('ucpath', "#{id}_user.json")) +end + +# Stubs the UCPath jobs endpoint. +# By default it uses the per-user jobs fixture, but a different fixture +# and field overrides can be supplied for scenario-based tests. +def stub_ucpath_jobs(id, fixture: nil, overrides: nil) + fixture ||= "#{id}_jobs.json" + + if overrides + json_body = fixture_json('ucpath', fixture) + apply_job_overrides!(json_body, overrides) + body = json_body.to_json + else + body = fixture_body('ucpath', fixture) end - # rubocop:enable Metrics/MethodLength, Metrics/AbcSize - new_body = json_body.to_json + stub_get(ucpath_jobs_url(id), status: 200, body: body) +end - stub_request(:get, user_api_url).to_return( - status: 200, - body: new_body - ) +def apply_job_overrides!(json_body, overrides) + job = json_body['response'][0]['jobs'][0] + + overrides.each do |key, value| + case key + when :job_code + job['position']['jobCode']['code']['code'] = value + when :dept_code + job['department']['code'] = value + when :classification_indc + job['classification']['code'] = value + else + raise ArgumentError, "Unknown job override key: #{key}" + end + end end -def stub_change_log(start_date, end_date, body) - change_log_url = "https://gateway.api.berkeley.edu/hr/v3/employees?change-from=#{start_date}&change-to=#{end_date}&page-number=1&page-size=200" +def stub_ucpath_missing_user(id) + stub_get(ucpath_user_url(id), status: 400) +end - stub_request(:get, change_log_url).to_return( - status: 200, - body: File.new("spec/data/ucpath/#{body}.json") - ) +def stub_ucpath_jobs_rate(id) + stub_get(ucpath_jobs_url(id), status: 429) end -def stub_empty_change_log(start_date, end_date) - change_log_url = "https://gateway.api.berkeley.edu/hr/v3/employees?change-from=#{start_date}&change-to=#{end_date}&page-number=1&page-size=200" +def stub_change_log(start_date, end_date, fixture_name) + stub_get(ucpath_change_log_url(start_date, end_date), status: 200, body: fixture_body('ucpath', "#{fixture_name}.json")) +end - stub_request(:get, change_log_url).to_return( - status: 200, - body: nil - ) +def stub_empty_change_log(start_date, end_date) + stub_get(ucpath_change_log_url(start_date, end_date), status: 200, body: nil) end def stub_past_sis_data(term_id, as_of_date, page_num) - sis_fetch_url = "https://gateway.api.berkeley.edu/sis/v2/students?as-of-date=#{as_of_date}&affiliation-status=ALL&inc-acad=true&inc-cntc=true&inc-regs=true&page-number=#{page_num}&page-size=50&term-id=#{term_id}" - stub_request(:get, sis_fetch_url).to_return( - status: 200, - body: File.new("spec/data/sis/past_#{term_id}_#{page_num}.json") - ) + stub_get(sis_past_data_url(term_id, as_of_date, page_num), status: 200, body: fixture_body('sis', "past_#{term_id}_#{page_num}.json")) end def stub_sis_data(term_id, page_num) - sis_fetch_url = "https://gateway.api.berkeley.edu/sis/v2/students?affiliation-status=ALL&inc-acad=true&inc-cntc=true&inc-regs=true&page-number=#{page_num}&page-size=50&term-id=#{term_id}" - stub_request(:get, sis_fetch_url).to_return( - status: 200, - body: File.new("spec/data/sis/term_#{term_id}_#{page_num}.json") - ) + stub_get(sis_data_url(term_id, page_num), status: 200, body: fixture_body('sis', "term_#{term_id}_#{page_num}.json")) end def stub_missing_sis_data(term_id, page_num) - sis_fetch_url = "https://gateway.api.berkeley.edu/sis/v2/students?affiliation-status=ALL&inc-acad=true&inc-cntc=true&inc-regs=true&page-number=#{page_num}&page-size=50&term-id=#{term_id}" - stub_request(:get, sis_fetch_url).to_return( - status: 200, - body: File.new("spec/data/sis/missing_reg_#{term_id}_#{page_num}.json") - ) + stub_get(sis_data_url(term_id, page_num), status: 200, body: fixture_body('sis', "missing_reg_#{term_id}_#{page_num}.json")) end