From 640f929d4335c8a48aa9a2a2881cd327815da147 Mon Sep 17 00:00:00 2001 From: Fang Lin Date: Fri, 7 Mar 2025 09:48:46 -0800 Subject: [PATCH] Feat/muwm 5381 (#3196) Resolve MUWM-5381 --- docker/prod-values.yml | 14 +-- myuw/dao/affiliation.py | 2 +- myuw/dao/idcard_elig.py | 13 +++ myuw/dao/student_profile.py | 1 + myuw/dao/upass.py | 2 +- .../full.json | 11 ++- .../file/identity/v2/person/jeos/full.json | 6 +- .../api/person/v1/eligibility/bill | 1 + .../api/person/v1/eligibility/billbot | 1 + .../api/person/v1/eligibility/billgrad | 1 + .../api/person/v1/eligibility/billpce | 1 + .../api/person/v1/eligibility/billsea | 1 + .../api/person/v1/eligibility/billtac | 1 + .../api/person/v1/eligibility/botgrad | 1 + .../api/person/v1/eligibility/eight | 1 + .../api/person/v1/eligibility/javg001 | 1 + .../api/person/v1/eligibility/javg002 | 1 + .../api/person/v1/eligibility/javg003 | 1 + .../api/person/v1/eligibility/javg004 | 1 + .../api/person/v1/eligibility/jbothell | 1 + .../api/person/v1/eligibility/jeos | 1 + .../api/person/v1/eligibility/jinter | 1 + .../api/person/v1/eligibility/jnew | 1 + .../api/person/v1/eligibility/jpce | 1 + .../api/person/v1/eligibility/retirestaff | 1 + .../api/person/v1/eligibility/seagrad | 1 + .../api/person/v1/eligibility/tacgrad | 1 + myuw/templates/accounts.html | 2 + .../restclients/customform/upass/index.html | 25 ++++- .../supporttools/custom_sidebar_links.html | 4 +- myuw/test/__init__.py | 2 +- myuw/test/api/__init__.py | 2 +- myuw/test/api/test_idcard_elig.py | 31 ++++++ myuw/test/api/test_upass.py | 4 +- myuw/test/dao/test_affiliation.py | 6 ++ myuw/test/dao/test_idcard.py | 29 ++++++ myuw/test/dao/test_pws.py | 5 + myuw/test/dao/test_upass.py | 4 +- myuw/test/views/test_errors.py | 4 +- myuw/test/views/test_rest_search.py | 15 +++ myuw/urls.py | 4 + myuw/views/api/idcard_elig.py | 26 +++++ myuw/views/rest_search.py | 9 +- myuw_vue/accounts.js | 4 + myuw_vue/components/_common/hr-payroll.vue | 5 +- myuw_vue/components/accounts/husky.vue | 2 +- myuw_vue/components/accounts/idcard.vue | 96 +++++++++++++++++++ .../home/former_employee/retiree.vue | 3 +- myuw_vue/tests/hr-payroll.test.js | 1 + myuw_vue/tests/husky.test.js | 2 +- myuw_vue/tests/idcard.test.js | 59 ++++++++++++ myuw_vue/tests/retiree.test.js | 1 + myuw_vue/vuex/store/idcard-elig.js | 9 ++ setup.py | 2 +- 54 files changed, 390 insertions(+), 35 deletions(-) create mode 100644 myuw/dao/idcard_elig.py create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/bill create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billbot create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billgrad create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billpce create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billsea create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billtac create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/botgrad create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/eight create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg001 create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg002 create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg003 create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg004 create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jbothell create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jeos create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jinter create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jnew create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jpce create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/retirestaff create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/seagrad create mode 100644 myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/tacgrad create mode 100644 myuw/test/api/test_idcard_elig.py create mode 100644 myuw/test/dao/test_idcard.py create mode 100644 myuw/views/api/idcard_elig.py create mode 100644 myuw_vue/components/accounts/idcard.vue create mode 100644 myuw_vue/tests/idcard.test.js create mode 100644 myuw_vue/vuex/store/idcard-elig.js diff --git a/docker/prod-values.yml b/docker/prod-values.yml index 438f9e845a..ba1e52c7b3 100644 --- a/docker/prod-values.yml +++ b/docker/prod-values.yml @@ -280,7 +280,7 @@ environmentVariables: - name: IASYSTEM_UW_TIMEOUT value: "10" - name: IASYSTEM_UW_POOL_SIZE - value: "20" + value: "25" - name: IASYSTEM_UWB_ENV value: PROD @@ -315,14 +315,14 @@ environmentVariables: - name: LIBCURRICS_POOL_SIZE value: "30" - name: LIBCURRICS_TIMEOUT - value: "7" + value: "5" - name: LIBRARIES_ENV value: PROD - name: LIBRARIES_POOL_SIZE value: "30" - name: LIBRARIES_TIMEOUT - value: "7" + value: "5" - name: MAILMAN_ENV value: PROD @@ -343,7 +343,7 @@ environmentVariables: - name: PWS_ENV value: PROD - name: PWS_TIMEOUT - value: "10" + value: "7" - name: PWS_POOL_SIZE value: "50" @@ -352,7 +352,7 @@ environmentVariables: - name: SDBMYUW_POOL_SIZE value: "30" - name: SDBMYUW_TIMEOUT - value: "10" + value: "5" - name: SWS_ENV value: PROD @@ -369,14 +369,14 @@ environmentVariables: - name: UPASS_TIMEOUT value: "10" - name: UPASS_POOL_SIZE - value: "20" + value: "30" - name: UWNETID_ENV value: PROD - name: UWNETID_POOL_SIZE value: "40" - name: UWNETID_TIMEOUT - value: "10" + value: "7" - name: UWIDP_ENV value: PROD diff --git a/myuw/dao/affiliation.py b/myuw/dao/affiliation.py index a27f05e02c..1e4992c1e5 100644 --- a/myuw/dao/affiliation.py +++ b/myuw/dao/affiliation.py @@ -111,7 +111,7 @@ def get_all_affiliations(request): "hxt_viewer": is_hxt_viewer, "alum_asso": is_alum_asso(request), "alumni": is_alumni(request) and not_major_affi, - "retiree": is_retiree(request) and not_major_affi, + "retiree": is_retiree(request), "past_employee": is_prior_employee(request) and not_major_affi, "past_stud": is_prior_student(request) and not_major_affi, "no_1st_class_affi": not_major_affi, diff --git a/myuw/dao/idcard_elig.py b/myuw/dao/idcard_elig.py new file mode 100644 index 0000000000..5803e535fd --- /dev/null +++ b/myuw/dao/idcard_elig.py @@ -0,0 +1,13 @@ +# Copyright 2025 UW-IT, University of Washington +# SPDX-License-Identifier: Apache-2.0 + +""" +This class interactes with the idcard eligibility web service. +""" + +from uw_admin_systems.idcard import get_idcard_elig +from myuw.dao import get_netid_of_current_user + + +def get_idcard_eli(request): + return get_idcard_elig(get_netid_of_current_user(request)).json_data() diff --git a/myuw/dao/student_profile.py b/myuw/dao/student_profile.py index ea3ed74dc3..fdf5d01693 100644 --- a/myuw/dao/student_profile.py +++ b/myuw/dao/student_profile.py @@ -169,6 +169,7 @@ def _has_only_dropped_degrees(first, second): has_added = len(set(second) - set(first)) > 0 return has_dropped and not has_added + def _get_residency_change(terms, enrollments, current_resident_code): # MUWM-5352 for term in terms: diff --git a/myuw/dao/upass.py b/myuw/dao/upass.py index 8e67ba4f00..acd56e5363 100644 --- a/myuw/dao/upass.py +++ b/myuw/dao/upass.py @@ -6,7 +6,7 @@ """ from datetime import timedelta -from uw_upass import get_upass_status +from uw_admin_systems.upass import get_upass_status from myuw.dao import get_netid_of_current_user from myuw.dao.gws import is_student from myuw.dao.term import ( diff --git a/myuw/resources/pws/file/identity/v2/person/55555333366711D5BE060004AC494FFE/full.json b/myuw/resources/pws/file/identity/v2/person/55555333366711D5BE060004AC494FFE/full.json index 551c6c5bee..ed3a348754 100644 --- a/myuw/resources/pws/file/identity/v2/person/55555333366711D5BE060004AC494FFE/full.json +++ b/myuw/resources/pws/file/identity/v2/person/55555333366711D5BE060004AC494FFE/full.json @@ -30,10 +30,13 @@ "+1 425 555-1236"], "Pagers":[], "Name" : "Eos, James", - "Positions":[{ - "EWPDept":"", - "EWPTitle":"", - "Primary":true}], + "Positions": [ + { + "EWPDept": "University of Washington", + "EWPTitle": "Retiree", + "Primary": true + } + ], "PublishInDirectory": false, "TouchDials":[], "VoiceMails":[]}, diff --git a/myuw/resources/pws/file/identity/v2/person/jeos/full.json b/myuw/resources/pws/file/identity/v2/person/jeos/full.json index 551c6c5bee..c01ea4a8dd 100644 --- a/myuw/resources/pws/file/identity/v2/person/jeos/full.json +++ b/myuw/resources/pws/file/identity/v2/person/jeos/full.json @@ -31,9 +31,9 @@ "Pagers":[], "Name" : "Eos, James", "Positions":[{ - "EWPDept":"", - "EWPTitle":"", - "Primary":true}], + "EWPDept": "University of Washington", + "EWPTitle": "Retiree", + "Primary": true}], "PublishInDirectory": false, "TouchDials":[], "VoiceMails":[]}, diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/bill b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/bill new file mode 100644 index 0000000000..a9ce27f299 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/bill @@ -0,0 +1 @@ +{"uwId":"bill","empCardElig":"Y","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billbot b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billbot new file mode 100644 index 0000000000..14f9693ec6 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billbot @@ -0,0 +1 @@ +{"uwId":"billbot","empCardElig":"Y","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billgrad b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billgrad new file mode 100644 index 0000000000..a586d3f69e --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billgrad @@ -0,0 +1 @@ +{"uwId":"billgrad","empCardElig":"Y","stdtCardElig":"Y"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billpce b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billpce new file mode 100644 index 0000000000..8c833f8009 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billpce @@ -0,0 +1 @@ +{"uwId":"billpce","empCardElig":"Y","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billsea b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billsea new file mode 100644 index 0000000000..b97327f8e7 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billsea @@ -0,0 +1 @@ +{"uwId":"billsea","empCardElig":"Y","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billtac b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billtac new file mode 100644 index 0000000000..49e7f46bd1 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/billtac @@ -0,0 +1 @@ +{"uwId":"billtac","empCardElig":"Y","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/botgrad b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/botgrad new file mode 100644 index 0000000000..3d325fc0d3 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/botgrad @@ -0,0 +1 @@ +{"uwId":"botgrad","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/eight b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/eight new file mode 100644 index 0000000000..0c85824b6d --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/eight @@ -0,0 +1 @@ +{"uwId":"eight","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg001 b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg001 new file mode 100644 index 0000000000..2babe41025 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg001 @@ -0,0 +1 @@ +{"uwId":"javg001","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg002 b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg002 new file mode 100644 index 0000000000..548753a125 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg002 @@ -0,0 +1 @@ +{"uwId":"javg002","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg003 b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg003 new file mode 100644 index 0000000000..86f3487543 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg003 @@ -0,0 +1 @@ +{"uwId":"javg003","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg004 b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg004 new file mode 100644 index 0000000000..43b8afb00a --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/javg004 @@ -0,0 +1 @@ +{"uwId":"javg004","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jbothell b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jbothell new file mode 100644 index 0000000000..0c85824b6d --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jbothell @@ -0,0 +1 @@ +{"uwId":"eight","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jeos b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jeos new file mode 100644 index 0000000000..aa20f91e6a --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jeos @@ -0,0 +1 @@ +{"uwId":"jeos","empCardElig":"R","stdtCardElig":"Y"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jinter b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jinter new file mode 100644 index 0000000000..faa45832d8 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jinter @@ -0,0 +1 @@ +{"uwId":"jinter","empCardElig":"N","stdtCardElig":"N"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jnew b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jnew new file mode 100644 index 0000000000..727d1738a4 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jnew @@ -0,0 +1 @@ +{"uwId":"jnew","empCardElig":"N","stdtCardElig":"N"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jpce b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jpce new file mode 100644 index 0000000000..5ca8ae3822 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/jpce @@ -0,0 +1 @@ +{"uwId":"jpce","empCardElig":"N","stdtCardElig":"N"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/retirestaff b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/retirestaff new file mode 100644 index 0000000000..ae5ebdc11f --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/retirestaff @@ -0,0 +1 @@ +{"uwId":"retirestaff","empCardElig":"R","stdtCardElig":"N"} diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/seagrad b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/seagrad new file mode 100644 index 0000000000..dc59f4c995 --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/seagrad @@ -0,0 +1 @@ +{"uwId":"seagrad","empCardElig":"N","stdtCardElig":"Y"} \ No newline at end of file diff --git a/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/tacgrad b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/tacgrad new file mode 100644 index 0000000000..ed8446592b --- /dev/null +++ b/myuw/resources/upass/file/idcarddataws/api/person/v1/eligibility/tacgrad @@ -0,0 +1 @@ +{"uwId":"tacgrad","empCardElig":"N","stdtCardElig":"N"} \ No newline at end of file diff --git a/myuw/templates/accounts.html b/myuw/templates/accounts.html index d1323dd622..3171043997 100644 --- a/myuw/templates/accounts.html +++ b/myuw/templates/accounts.html @@ -13,6 +13,7 @@ + @@ -27,6 +28,7 @@ + diff --git a/myuw/templates/restclients/customform/upass/index.html b/myuw/templates/restclients/customform/upass/index.html index 21f2050723..7d3cff3822 100644 --- a/myuw/templates/restclients/customform/upass/index.html +++ b/myuw/templates/restclients/customform/upass/index.html @@ -1,2 +1,23 @@ -

UPASS

-{% include "restclients/customform/_common/netid.html" %} +

Husky Card

+
+ {% csrf_token %} +

+ + +

+

Find any of the following:

+
+
+ + +
+
+ + +
+
+
+

+ +

+
diff --git a/myuw/templates/supporttools/custom_sidebar_links.html b/myuw/templates/supporttools/custom_sidebar_links.html index a4e89a8716..0590e5bfe5 100644 --- a/myuw/templates/supporttools/custom_sidebar_links.html +++ b/myuw/templates/supporttools/custom_sidebar_links.html @@ -61,6 +61,8 @@

Web Services

{% endif %} + {% url 'myuw_rest_search' 'idcard_elig' 'index.html' as idcard_elig_url %} + {% url 'myuw_rest_search' 'book' 'iacourse.html' as iacourse_url %} {% if iacourse_url %}
  • @@ -127,7 +129,7 @@

    Web Services

    {% url 'myuw_rest_search' 'upass' 'index.html' as upass_url %} {% if upass_url %}
  • - UPASS + ID Card
  • {% endif %}
    diff --git a/myuw/test/__init__.py b/myuw/test/__init__.py index cc6c845230..17adcd8aa0 100644 --- a/myuw/test/__init__.py +++ b/myuw/test/__init__.py @@ -17,7 +17,7 @@ from uw_bookstore.util import fdao_bookstore_override from uw_canvas.utilities import fdao_canvas_override from uw_mailman.util import fdao_mailman_override -from uw_upass.util import fdao_upass_override +from uw_admin_systems.util import fdao_uw_admin_sys_override from uw_hfs.util import fdao_hfs_override from restclients_core.util.decorators import use_mock diff --git a/myuw/test/api/__init__.py b/myuw/test/api/__init__.py index eb3c736218..f541d1349d 100644 --- a/myuw/test/api/__init__.py +++ b/myuw/test/api/__init__.py @@ -15,7 +15,7 @@ fdao_hfs_override, fdao_gws_override, fdao_pws_override, fdao_grad_override, fdao_bookstore_override, fdao_canvas_override, - fdao_mailman_override, fdao_upass_override) + fdao_mailman_override, fdao_uw_admin_sys_override) from django.urls import NoReverseMatch VALIDATE = "myuw.authorization.validate_netid" diff --git a/myuw/test/api/test_idcard_elig.py b/myuw/test/api/test_idcard_elig.py new file mode 100644 index 0000000000..9d9d6f044a --- /dev/null +++ b/myuw/test/api/test_idcard_elig.py @@ -0,0 +1,31 @@ +# Copyright 2025 UW-IT, University of Washington +# SPDX-License-Identifier: Apache-2.0 + +from datetime import datetime +import json +from myuw.test.api import ( + MyuwApiTest, require_url, fdao_uw_admin_sys_override) + + +@fdao_uw_admin_sys_override +@require_url("myuw_idcard_elig_api") +class TestIDcardApi(MyuwApiTest): + + def test_normal(self): + self.set_user('javerage') + response = self.get_response_by_reverse('myuw_idcard_elig_api') + self.assertEqual(response.status_code, 200) + self.assertEqual( + json.loads(response.content.decode("UTF-8")), + { + "not_eligible": False, + "employee_eligible": True, + "student_eligible": True, + "retiree_eligible": False, + }, + ) + + def test_error_404(self): + self.set_user('noexist') + response = self.get_response_by_reverse('myuw_idcard_elig_api') + self.assertEqual(response.status_code, 404) diff --git a/myuw/test/api/test_upass.py b/myuw/test/api/test_upass.py index d007b060b4..6036dadd1d 100644 --- a/myuw/test/api/test_upass.py +++ b/myuw/test/api/test_upass.py @@ -4,11 +4,11 @@ from datetime import datetime import json from myuw.test.api import ( - MyuwApiTest, require_url, fdao_upass_override, + MyuwApiTest, require_url, fdao_uw_admin_sys_override, fdao_sws_override, fdao_gws_override) -@fdao_upass_override +@fdao_uw_admin_sys_override @fdao_sws_override @fdao_gws_override @require_url('myuw_upass_api') diff --git a/myuw/test/dao/test_affiliation.py b/myuw/test/dao/test_affiliation.py index 2fa2afcfc3..2ac934efab 100644 --- a/myuw/test/dao/test_affiliation.py +++ b/myuw/test/dao/test_affiliation.py @@ -78,6 +78,12 @@ def test_is_retiree(self): self.assertTrue(affiliations["past_stud"]) self.assertTrue(affiliations["no_1st_class_affi"]) + now_request = get_request_with_user("jeos") + affiliations = get_all_affiliations(now_request) + self.assertTrue(affiliations["retiree"]) + self.assertTrue(affiliations["student"]) + self.assertFalse(affiliations["employee"]) + def test_is_pce_stud(self): now_request = get_request_with_user('jpce') affiliations = get_all_affiliations(now_request) diff --git a/myuw/test/dao/test_idcard.py b/myuw/test/dao/test_idcard.py new file mode 100644 index 0000000000..9370b55410 --- /dev/null +++ b/myuw/test/dao/test_idcard.py @@ -0,0 +1,29 @@ +# Copyright 2025 UW-IT, University of Washington +# SPDX-License-Identifier: Apache-2.0 + +from django.test import TestCase +from restclients_core.exceptions import DataFailureException +from myuw.dao.idcard_elig import get_idcard_eli +from myuw.test import ( + fdao_uw_admin_sys_override, get_request_with_user) + + +@fdao_uw_admin_sys_override +class TestIDcardDao(TestCase): + + def test_get_idcard_eli(self): + req = get_request_with_user("javerage") + status = get_idcard_eli(req) + self.assertEqual(status, { + "not_eligible": False, + "employee_eligible": True, + "student_eligible": True, + "retiree_eligible": False}) + + req = get_request_with_user("jpce") + status = get_idcard_eli(req) + self.assertEqual(status, { + "not_eligible": True, + "employee_eligible": False, + "student_eligible": False, + "retiree_eligible": False}) diff --git a/myuw/test/dao/test_pws.py b/myuw/test/dao/test_pws.py index 7fa0d2b1f7..f01223f281 100644 --- a/myuw/test/dao/test_pws.py +++ b/myuw/test/dao/test_pws.py @@ -68,6 +68,11 @@ def test_is_retiree(self): self.assertTrue(is_alumni(req)) self.assertTrue(is_prior_student(req)) + req = get_request_with_user("jeos") + self.assertTrue(is_retiree(req)) + self.assertTrue(is_alumni(req)) + self.assertTrue(is_student(req)) + def test_is_prior_employee(self): req = get_request_with_user('jpce') self.assertTrue(is_prior_employee(req)) diff --git a/myuw/test/dao/test_upass.py b/myuw/test/dao/test_upass.py index 2297d620c1..e07ed17f06 100644 --- a/myuw/test/dao/test_upass.py +++ b/myuw/test/dao/test_upass.py @@ -5,11 +5,11 @@ from restclients_core.exceptions import DataFailureException from myuw.dao.upass import get_upass, in_summer_display_window from myuw.test import ( - fdao_upass_override, get_request_with_user, + fdao_uw_admin_sys_override, get_request_with_user, get_request_with_date, fdao_sws_override, fdao_gws_override) -@fdao_upass_override +@fdao_uw_admin_sys_override @fdao_sws_override @fdao_gws_override class TestUPassDao(TestCase): diff --git a/myuw/test/views/test_errors.py b/myuw/test/views/test_errors.py index fb21361879..3d79bce3b1 100644 --- a/myuw/test/views/test_errors.py +++ b/myuw/test/views/test_errors.py @@ -41,8 +41,8 @@ def test_no_access(self): self.assertEqual( response.content, ( - b"

    This is a test environment of MyUW, " - b"its access is limited to specific people. To request access, " + b"

    This is a test environment of MyUW, its access " + b"is limited to specific people. To request access, " b'please contact the UW-IT Service Center.

    ' ), diff --git a/myuw/test/views/test_rest_search.py b/myuw/test/views/test_rest_search.py index d00a1fe38c..96483578c8 100644 --- a/myuw/test/views/test_rest_search.py +++ b/myuw/test/views/test_rest_search.py @@ -241,9 +241,24 @@ def test_post(self): url = reverse("myuw_rest_search", args=["upass", "index"]) response = self.client.post(url, { "uwnetid": "bill", + "res": "upass", "csrfmiddlewaretoken": "0000000"}) self.assertEqual(response.status_code, 302) self.assertEqual( response.url, "/restclients/view/upass/upassdataws/" + "api/person/v1/membershipstatus/bill") + + # idcard + url = reverse("myuw_rest_search", args=["upass", "index"]) + response = self.client.post( + url, {"uwnetid": "bill", + "res": "idcard", + "csrfmiddlewaretoken": "0000000"} + ) + self.assertEqual(response.status_code, 302) + self.assertEqual( + response.url, + "/restclients/view/upass/idcarddataws/" + + "api/person/v1/eligibility/bill", + ) diff --git a/myuw/urls.py b/myuw/urls.py index f1df4c4b47..a5deaea26e 100644 --- a/myuw/urls.py +++ b/myuw/urls.py @@ -59,6 +59,7 @@ from myuw.views.api.calendar import DepartmentalCalendar from myuw.views.search import search_res from myuw.views.api.upass import UPass +from myuw.views.api.idcard_elig import IDcardElig from myuw.views.api.link import ManageLinks from myuw.views.api.directory import MyDirectoryInfo from myuw.views.lti.photo_list import LTIPhotoList @@ -202,6 +203,9 @@ re_path(r'api/v1/link/?$', ManageLinks.as_view(), name='myuw_manage_links'), + re_path(r'^api/v1/idcard-elig/$', + IDcardElig.as_view(), + name="myuw_idcard_elig_api"), re_path(r'^api/v1/upass/$', UPass.as_view(), name="myuw_upass_api"), diff --git a/myuw/views/api/idcard_elig.py b/myuw/views/api/idcard_elig.py new file mode 100644 index 0000000000..3da4802f63 --- /dev/null +++ b/myuw/views/api/idcard_elig.py @@ -0,0 +1,26 @@ +# Copyright 2025 UW-IT, University of Washington +# SPDX-License-Identifier: Apache-2.0 + +import logging +import traceback +from myuw.logger.timer import Timer +from myuw.logger.logresp import log_api_call +from myuw.dao.idcard_elig import get_idcard_eli +from myuw.views.api import ProtectedAPI +from myuw.views.error import handle_exception + +logger = logging.getLogger(__name__) + + +class IDcardElig(ProtectedAPI): + """ + Performs actions on /api/v1/idcard-elig + """ + def get(self, request, *args, **kwargs): + timer = Timer() + try: + status_json = get_idcard_eli(request) + log_api_call(timer, request, "Get IDcard Eligibility") + return self.json_response(status_json) + except Exception: + return handle_exception(logger, timer, traceback) diff --git a/myuw/views/rest_search.py b/myuw/views/rest_search.py index 0caad17314..988940ae87 100644 --- a/myuw/views/rest_search.py +++ b/myuw/views/rest_search.py @@ -103,8 +103,13 @@ def get_proxy_url(self, request, service, url): url = f"student/v5/person/{regid}.json" elif service == "upass": - url = "upassdataws/api/person/v1/membershipstatus/{}".format( - get_input_value(request.POST, "uwnetid")) + res = get_input_value(request.POST, "res") + netid = get_input_value(request.POST, "uwnetid") + if "idcard" == res: + url = f"idcarddataws/api/person/v1/eligibility/{netid}" + elif "upass" == res: + url = f"upassdataws/api/person/v1/membershipstatus/{netid}" + elif service == "uwnetid": if "password" == url: url = "nws/v1/uwnetid/{}/password".format( diff --git a/myuw_vue/accounts.js b/myuw_vue/accounts.js index 6b6e566408..ba35c209a6 100644 --- a/myuw_vue/accounts.js +++ b/myuw_vue/accounts.js @@ -10,6 +10,7 @@ import HRPayroll from './components/_common/hr-payroll.vue'; // accounts components import HfsSea from './components/accounts/hfs-sea.vue'; import HuskyCard from './components/accounts/husky.vue'; +import IDCard from './components/accounts/idcard.vue'; import MedicineAccount from './components/accounts/medicine-account.vue'; import UpassCard from './components/accounts/upass.vue'; import LibraryCard from './components/accounts/library.vue'; @@ -17,6 +18,7 @@ import TuitionFees from './components/accounts/tuition-fees.vue'; // stores import hfs from './vuex/store/hfs'; +import idcardelig from './vuex/store/idcard-elig'; import library from './vuex/store/library'; import profile from './vuex/store/profile'; import upass from './vuex/store/upass'; @@ -25,6 +27,7 @@ import notices from './vuex/store/notices'; import iac from './vuex/store/iacourse-digital-material'; vueConf.store.registerModule('hfs', hfs); +vueConf.store.registerModule('idcardelig', idcardelig); vueConf.store.registerModule('library', library); vueConf.store.registerModule('profile', profile); vueConf.store.registerModule('upass', upass); @@ -42,6 +45,7 @@ vueConf.store.commit('addVarToState', { Vue.component('myuw-boilerplate', Boilerplate); Vue.component('myuw-hfs-sea', HfsSea); +Vue.component('myuw-idcard', IDCard); Vue.component('myuw-husky', HuskyCard); Vue.component('myuw-uwnetid', UWNetID); Vue.component('myuw-hr-payroll', HRPayroll); diff --git a/myuw_vue/components/_common/hr-payroll.vue b/myuw_vue/components/_common/hr-payroll.vue index 98a0812e72..55d217fabe 100644 --- a/myuw_vue/components/_common/hr-payroll.vue +++ b/myuw_vue/components/_common/hr-payroll.vue @@ -115,17 +115,18 @@ export default { instructor: (state) => state.user.affiliations.instructor, retiree: (state) => state.user.affiliations.retiree, pastEmployee: (state) => state.user.affiliations.past_employee, + no_1st_class_affi: (state) => state.user.affiliations.no_1st_class_affi, staticUrl: (state) => state.staticUrl, }), showCard () { if (this.isHomePage) { - return this.retiree || this.pastEmployee || + return this.retiree && this.no_1st_class_affi || this.pastEmployee || this.employee && !this.student && !this.instructor; } return this.studEmployee || this.instructor; }, truncateView () { - return this.retiree || this.pastEmployee; + return this.retiree && this.no_1st_class_affi || this.pastEmployee; }, }, }; diff --git a/myuw_vue/components/accounts/husky.vue b/myuw_vue/components/accounts/husky.vue index efa6725638..2ecf399196 100644 --- a/myuw_vue/components/accounts/husky.vue +++ b/myuw_vue/components/accounts/husky.vue @@ -1,7 +1,7 @@