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