Merge pull request #2007 from pateljannat/issues-174

fix: misc issues
This commit is contained in:
Jannat Patel
2026-01-22 13:59:54 +05:30
committed by GitHub
55 changed files with 78 additions and 212 deletions
+3
View File
@@ -71,6 +71,9 @@ jobs:
- name: setup requirements
working-directory: /home/runner/frappe-bench
run: bench setup requirements --dev
- name: block endpoints
working-directory: /home/runner/frappe-bench
run: bench --site frappe.local set-config block_endpoints 1
- name: allow tests
working-directory: /home/runner/frappe-bench
run: bench --site frappe.local set-config allow_tests true
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-152
View File
@@ -1,152 +0,0 @@
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 100;
font-display: swap;
src: url("Inter-Thin.woff2?v=3.12") format("woff2"),
url("Inter-Thin.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 100;
font-display: swap;
src: url("Inter-ThinItalic.woff2?v=3.12") format("woff2"),
url("Inter-ThinItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 200;
font-display: swap;
src: url("Inter-ExtraLight.woff2?v=3.12") format("woff2"),
url("Inter-ExtraLight.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 200;
font-display: swap;
src: url("Inter-ExtraLightItalic.woff2?v=3.12") format("woff2"),
url("Inter-ExtraLightItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url("Inter-Light.woff2?v=3.12") format("woff2"),
url("Inter-Light.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 300;
font-display: swap;
src: url("Inter-LightItalic.woff2?v=3.12") format("woff2"),
url("Inter-LightItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url("Inter-Regular.woff2?v=3.12") format("woff2"),
url("Inter-Regular.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url("Inter-Italic.woff2?v=3.12") format("woff2"),
url("Inter-Italic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url("Inter-Medium.woff2?v=3.12") format("woff2"),
url("Inter-Medium.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 500;
font-display: swap;
src: url("Inter-MediumItalic.woff2?v=3.12") format("woff2"),
url("Inter-MediumItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url("Inter-SemiBold.woff2?v=3.12") format("woff2"),
url("Inter-SemiBold.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 600;
font-display: swap;
src: url("Inter-SemiBoldItalic.woff2?v=3.12") format("woff2"),
url("Inter-SemiBoldItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("Inter-Bold.woff2?v=3.12") format("woff2"),
url("Inter-Bold.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 700;
font-display: swap;
src: url("Inter-BoldItalic.woff2?v=3.12") format("woff2"),
url("Inter-BoldItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 800;
font-display: swap;
src: url("Inter-ExtraBold.woff2?v=3.12") format("woff2"),
url("Inter-ExtraBold.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 800;
font-display: swap;
src: url("Inter-ExtraBoldItalic.woff2?v=3.12") format("woff2"),
url("Inter-ExtraBoldItalic.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 900;
font-display: swap;
src: url("Inter-Black.woff2?v=3.12") format("woff2"),
url("Inter-Black.woff?v=3.12") format("woff");
}
@font-face {
font-family: 'Inter';
font-style: italic;
font-weight: 900;
font-display: swap;
src: url("Inter-BlackItalic.woff2?v=3.12") format("woff2"),
url("Inter-BlackItalic.woff?v=3.12") format("woff");
}
+3 -3
View File
@@ -43,7 +43,7 @@
<ListRow
:row="row"
v-for="row in students.data"
class="group cursor-pointer"
class="group cursor-pointer hover:bg-surface-gray-2 rounded"
@click="openStudentProgressModal(row)"
>
<template #default="{ column, item }">
@@ -88,7 +88,7 @@
</div>
</template>
</ListSelectBanner>
<div class="mt-4" v-if="students.hasNextPage">
<div class="mt-4 flex justify-center" v-if="students.hasNextPage">
<Button @click="students.next()">
{{ __('Load More') }}
</Button>
@@ -170,7 +170,7 @@ const studentColumns = [
{
label: 'Full Name',
key: 'full_name',
width: '20rem',
width: '25rem',
icon: 'user',
},
{
@@ -90,7 +90,7 @@
<FormControl
v-model="profile.open_to"
type="select"
:options="[' ', 'Opportunities', 'Hiring']"
:options="[' ', 'Work', 'Hiring']"
:label="__('Open to')"
:placeholder="__('Looking for new work or hiring talent?')"
/>
+2 -2
View File
@@ -7,8 +7,8 @@
:size="size"
v-bind="$attrs"
>
<template v-if="user.open_to === 'Opportunities'" #indicator>
<Tooltip :text="__('Open to Opportunities')" placement="right">
<template v-if="user.open_to === 'Work'" #indicator>
<Tooltip :text="__('Open to Work')" placement="right">
<div class="rounded-full bg-surface-green-3 w-fit">
<BadgeCheckIcon :class="'text-ink-white ' + checkSize" />
</div>
-1
View File
@@ -1,3 +1,2 @@
@import './assets/Inter/inter.css';
@import 'frappe-ui/style.css';
@import './styles/codemirror.css';
+7 -7
View File
@@ -42,8 +42,8 @@
</div>
<div class="flex items-center space-x-4">
<FormControl
v-model="openToOpportunities"
:label="__('Open to Opportunities')"
v-model="openToWork"
:label="__('Open to Work')"
type="checkbox"
@change="updateParticipants()"
/>
@@ -140,7 +140,7 @@ import UserAvatar from '@/components/UserAvatar.vue'
const filters = ref({})
const currentCategory = ref('')
const nameFilter = ref('')
const openToOpportunities = ref(false)
const openToWork = ref(false)
const hiring = ref(false)
const { brand } = sessionStore()
const memberCount = ref(0)
@@ -197,8 +197,8 @@ const updateFilters = () => {
...(nameFilter.value && {
member_name: ['like', `%${nameFilter.value}%`],
}),
...(openToOpportunities.value && {
open_to_opportunities: true,
...(openToWork.value && {
open_to_work: true,
}),
...(hiring.value && {
hiring: true,
@@ -211,7 +211,7 @@ const setQueryParams = () => {
let filterKeys = {
category: currentCategory.value,
name: nameFilter.value,
'open-to-opportunities': openToOpportunities.value,
'open-to-work': openToWork.value,
hiring: hiring.value,
}
@@ -240,7 +240,7 @@ const setFiltersFromQuery = () => {
let queries = new URLSearchParams(location.search)
nameFilter.value = queries.get('name') || ''
currentCategory.value = queries.get('category') || ''
openToOpportunities.value = queries.get('open-to-opportunities') === 'true'
openToWork.value = queries.get('open-to-opportunities') === 'true'
hiring.value = queries.get('hiring') === 'true'
}
+3 -3
View File
@@ -65,8 +65,8 @@
<Tooltip
v-if="profile.data.open_to"
:text="
profile.data.open_to === 'Opportunities'
? __('Open to Opportunities')
profile.data.open_to === 'Work'
? __('Open to Work')
: __('Hiring')
"
placement="right"
@@ -77,7 +77,7 @@
<div
class="rounded-full w-fit"
:class="
profile.data.open_to === 'Opportunities'
profile.data.open_to === 'Work'
? 'bg-surface-green-3'
: 'bg-purple-500'
"
+24 -14
View File
@@ -116,20 +116,30 @@ const debouncedSaveProgress = (scormDetails) => {
}
const saveDataToLMS = (key, value) => {
if (key === 'cmi.core.lesson_status') {
if (value === 'passed') {
isSuccessfullyCompleted.value = true
saveProgress({
is_complete: isSuccessfullyCompleted.value,
scorm_content: '',
})
} else if (value === 'failed' && courseRestartOnFailure) {
saveProgress({
is_complete: isSuccessfullyCompleted.value,
scorm_content: '',
})
}
} else if (key === 'cmi.suspend_data' && !isSuccessfullyCompleted.value) {
const isLessonStatus = key === 'cmi.core.lesson_status' && value === 'passed'
const isCompletionStatus =
key === 'cmi.completion_status' && value === 'completed'
const shouldRestart =
(key === 'cmi.core.lesson_status' && value === 'failed') ||
(key === 'cmi.completion_status' && value === 'incomplete')
if (isLessonStatus || isCompletionStatus) {
isSuccessfullyCompleted.value = true
}
if (
isLessonStatus ||
isCompletionStatus ||
(shouldRestart && courseRestartOnFailure)
) {
saveProgress({
is_complete: isSuccessfullyCompleted.value,
scorm_content: '',
})
return
}
if (key === 'cmi.suspend_data' && !isSuccessfullyCompleted.value) {
debouncedSaveProgress({
is_complete: false,
scorm_content: value,
+1 -1
View File
@@ -21,5 +21,5 @@ export default {
},
},
},
plugins: [require('@tailwindcss/line-clamp')],
plugins: [],
}
+2 -2
View File
@@ -257,12 +257,12 @@
"length": 0,
"link_filters": null,
"mandatory_depends_on": null,
"modified": "2025-12-24 12:56:32.110405",
"modified": "2025-12-24 12:56:32.110406",
"module": null,
"name": "User-open_to",
"no_copy": 0,
"non_negative": 0,
"options": "\nOpportunities\nHiring",
"options": "\nWork\nHiring",
"permlevel": 0,
"precision": "",
"print_hide": 0,
+2 -2
View File
@@ -331,8 +331,8 @@ def get_certification_query(filters):
)
if field == "member_name":
query = query.where(Certificate.member_name.like(value[1]))
if field == "open_to_opportunities":
query = query.where(User.open_to == "Opportunities")
if field == "open_to_work":
query = query.where(User.open_to == "Work")
if field == "hiring":
query = query.where(User.open_to == "Hiring")
return query
+7 -7
View File
@@ -277,14 +277,14 @@ class TestUtils(UnitTestCase):
certified_participants_no_match = get_certified_participants(filters=filters)
self.assertEqual(len(certified_participants_no_match), 0)
def test_certified_participants_with_open_to_opportunities(self):
filters = {"open_to_opportunities": 1}
certified_participants_open_to_oppo = get_certified_participants(filters=filters)
self.assertEqual(len(certified_participants_open_to_oppo), 0)
def test_certified_participants_with_open_to_work(self):
filters = {"open_to_work": 1}
certified_participants_open_to_work = get_certified_participants(filters=filters)
self.assertEqual(len(certified_participants_open_to_work), 0)
frappe.db.set_value("User", self.student1.email, "open_to", "Opportunities")
certified_participants_open_to_oppo = get_certified_participants(filters=filters)
self.assertEqual(len(certified_participants_open_to_oppo), 1)
frappe.db.set_value("User", self.student1.email, "open_to", "Work")
certified_participants_open_to_work = get_certified_participants(filters=filters)
self.assertEqual(len(certified_participants_open_to_work), 1)
frappe.db.set_value("User", self.student1.email, "open_to", "")
def test_certified_participants_with_open_to_hiring(self):
+2 -1
View File
@@ -114,4 +114,5 @@ lms.patches.v2_0.count_in_program
lms.patches.v2_0.fix_scorm_lesson_reference_idx #02-09-2025
lms.patches.v2_0.certified_members_to_certifications #05-10-2025
lms.patches.v2_0.fix_job_application_resume_urls
lms.patches.v2_0.open_to_opportunities
lms.patches.v2_0.open_to_opportunities
lms.patches.v2_0.open_to_work
+12
View File
@@ -0,0 +1,12 @@
import frappe
def execute():
open_to_field_exists = frappe.db.exists("Custom Field", {"dt": "User", "fieldname": "open_to"})
if not open_to_field_exists:
return
open_to_opportunities = frappe.get_all("User", {"open_to": "Opportunities"}, ["name"])
for user in open_to_opportunities:
frappe.db.set_value("User", user.name, "open_to", "Work")
+9 -16
View File
@@ -1,6 +1,7 @@
import frappe
from frappe.tests.test_api import FrappeAPITestCase
from lms.auth import authenticate
from lms.lms.test_utils import TestUtils
@@ -11,24 +12,16 @@ class TestAuth(FrappeAPITestCase):
)
def test_allowed_path(self):
site_url = frappe.utils.get_site_url(frappe.local.site)
headers = {"Authorization": "Bearer set_test_example_user"}
url = site_url + "/api/method/lms.lms.utils.get_courses"
response = self.get(
url,
headers=headers,
)
self.assertNotEqual(response.json.get("exc_type"), "PermissionError")
frappe.form_dict.cmd = "ping"
frappe.session.user = self.normal_user.name
authenticate()
frappe.session.user = "Administrator"
def test_not_allowed_path(self):
site_url = frappe.utils.get_site_url(frappe.local.site)
headers = {"Authorization": "Bearer set_test_example_user"}
url = site_url + "/api/method/frappe.auth.get_logged_user"
response = self.get(
url,
headers=headers,
)
self.assertEqual(response.json.get("exc_type"), "PermissionError")
frappe.form_dict.cmd = "frappe.auth.get_logged_user"
frappe.session.user = self.normal_user.name
self.assertRaises(frappe.PermissionError, authenticate)
frappe.session.user = "Administrator"
def tearDown(self):
frappe.delete_doc("User", self.normal_user.name)