From f0be296f6d56a8640c7cb43911e4763fc6fc3727 Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Thu, 5 Dec 2024 13:09:57 -0500 Subject: [PATCH 1/9] filter rules based on the prompt --- .../components/evidence/configureRules/rules.tsx | 16 ++++++++-------- .../evidence/configureRules/rulesIndexRouter.tsx | 10 +++++----- .../semanticRules/semanticLabelsIndex.tsx | 10 +++++----- .../Staff/helpers/evidence/promptHelpers.tsx | 2 +- .../Staff/helpers/evidence/ruleHelpers.tsx | 1 + 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx index 79e9d7bdc4c..c67eadd4947 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx @@ -8,7 +8,7 @@ import RuleViewForm from './ruleViewForm'; import { BECAUSE, BUT, SO, blankRule, ruleApiOrder } from '../../../../../constants/evidence'; import { DataTable, Error, Modal, Spinner } from '../../../../Shared/index'; import { getPromptsIcons } from '../../../helpers/evidence/promptHelpers'; -import { getConceptName, getPromptIdString } from '../../../helpers/evidence/ruleHelpers'; +import { getConceptName, } from '../../../helpers/evidence/ruleHelpers'; import { PromptInterface, RuleInterface } from '../../../interfaces/evidenceInterfaces'; import { fetchActivity } from '../../../utils/evidence/activityAPIs'; import { fetchConcepts, } from '../../../utils/evidence/conceptAPIs'; @@ -21,16 +21,15 @@ function sortByRuleApiOrder(ruleOneRuleType: string, ruleTwoRuleType: string) { interface RulesProps { activityId: string, history: any, - prompt: PromptInterface + prompt?: PromptInterface } const Rules = ({ activityId, history, prompt }: RulesProps) => { - const promptIdsForApi = prompt ? getPromptIdString(prompt) : ''; const [showAddRuleModal, setShowAddRuleModal] = React.useState(false); const [showEditRuleModal, setShowEditRuleModal] = React.useState(false); const [ruleToEdit, setRuleToEdit] = React.useState(null); const [errors, setErrors] = React.useState([]); - const [sortedRules, setSortedRules] = React.useState<[]>(null); + const [sortedAndFilteredRules, setSortedAndFilteredRules] = React.useState<[]>(null); const queryClient = useQueryClient() @@ -42,7 +41,7 @@ const Rules = ({ activityId, history, prompt }: RulesProps) => { // cache rules data for updates const { data: rulesData } = useQuery({ - queryKey: [`rules-${activityId}`, activityId, promptIdsForApi], + queryKey: [`rules-${activityId}`, activityId], queryFn: fetchRules }); @@ -59,11 +58,12 @@ const Rules = ({ activityId, history, prompt }: RulesProps) => { .thenBy('prompt_ids') .thenBy('suborder') ); - setSortedRules(multiSortRules); + const filteredRules = prompt ? multiSortRules.filter(rule => rule.prompt_ids.includes(prompt.id)) : multiSortRules + setSortedAndFilteredRules(filteredRules); } - }, [rulesData]); + }, [rulesData, prompt]); - const formattedRows = sortedRules && sortedRules.map((rule: RuleInterface, i: number) => { + const formattedRows = sortedAndFilteredRules && sortedAndFilteredRules.map((rule: RuleInterface, i: number) => { const { name, id, rule_type, prompt_ids, feedbacks, concept_uid, universal } = rule; const viewRuleLink = (

{name}

); /* eslint-disable-next-line react/jsx-no-bind, jsx-a11y/anchor-is-valid */ diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rulesIndexRouter.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rulesIndexRouter.tsx index b37b603466f..d0e2e44e8c0 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rulesIndexRouter.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rulesIndexRouter.tsx @@ -6,7 +6,7 @@ import Rules from './rules'; import { ALL, BECAUSE, BUT, SO } from '../../../../../constants/evidence'; import { Error, Spinner } from '../../../../Shared/index'; -import { getPromptForComponent } from '../../../helpers/evidence/promptHelpers'; +import { getPromptArrayForComponent } from '../../../helpers/evidence/promptHelpers'; import { renderHeader } from '../../../helpers/evidence/renderHelpers'; import { fetchActivity } from '../../../utils/evidence/activityAPIs'; @@ -64,13 +64,13 @@ const RulesIndexRouter = ({ history, match }) => { {/* eslint-disable-next-line react/jsx-no-bind */} - } /> + } /> {/* eslint-disable-next-line react/jsx-no-bind */} - } /> + } /> {/* eslint-disable-next-line react/jsx-no-bind */} - } /> + } /> {/* eslint-disable-next-line react/jsx-no-bind */} - } /> + } /> ); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/semanticRules/semanticLabelsIndex.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/semanticRules/semanticLabelsIndex.tsx index e00d9212329..50a13e19c01 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/semanticRules/semanticLabelsIndex.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/semanticRules/semanticLabelsIndex.tsx @@ -11,7 +11,7 @@ import SemanticRulesCheatSheet from './semanticRulesCheatSheet'; import { ALL, BECAUSE, BUT, SO } from '../../../../../constants/evidence'; import { Error, Spinner } from '../../../../Shared/index'; -import { getPromptConjunction, getPromptForComponent } from '../../../helpers/evidence/promptHelpers'; +import { getPromptConjunction, getPromptArrayForComponent } from '../../../helpers/evidence/promptHelpers'; import { renderHeader } from '../../../helpers/evidence/renderHelpers'; import { RuleInterface } from '../../../interfaces/evidenceInterfaces'; import { fetchActivity } from '../../../utils/evidence/activityAPIs'; @@ -87,10 +87,10 @@ const SemanticLabelsIndex = ({ location, history, match }) => { {/* eslint-disable react/jsx-no-bind */} - } path='/activities/:activityId/semantic-labels/all' /> - } path='/activities/:activityId/semantic-labels/because' /> - } path='/activities/:activityId/semantic-labels/but' /> - } path='/activities/:activityId/semantic-labels/so' /> + } path='/activities/:activityId/semantic-labels/all' /> + } path='/activities/:activityId/semantic-labels/because' /> + } path='/activities/:activityId/semantic-labels/but' /> + } path='/activities/:activityId/semantic-labels/so' /> diff --git a/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/promptHelpers.tsx b/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/promptHelpers.tsx index 9d96e24de2e..44fd442a5a4 100644 --- a/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/promptHelpers.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/promptHelpers.tsx @@ -60,7 +60,7 @@ export const formatPrompts = ({ activityData, rule, setRulePrompts }) => { setRulePrompts(formatted); } -export function getPromptForComponent(activityData: any, key: string) { +export function getPromptArrayForComponent(activityData: any, key: string): PromptInterface[] { if(!activityData || activityData && !activityData.activity) { return null; } diff --git a/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/ruleHelpers.tsx b/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/ruleHelpers.tsx index bb5a7c19606..dc27fa4bd6c 100644 --- a/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/ruleHelpers.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/helpers/evidence/ruleHelpers.tsx @@ -527,6 +527,7 @@ export function getConceptName(conceptsData, conceptUID) { if(!conceptsData.concepts) { return 'loading...' } const { concepts } = conceptsData; + const concept = concepts.filter(concept => concept.uid === conceptUID)[0]; if(!concept) { return 'N/A' } const splitConcepts = concept.name.split('|'); From 88205325bcf2b113b4472aaf1d2f60d3c907fbe9 Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Fri, 6 Dec 2024 10:38:33 -0500 Subject: [PATCH 2/9] hide automl confidence column for non-automl activities --- .../evidence/activityStats/activityStats.tsx | 18 +++++++++--------- .../evidence/rulesAnalysis/rulesAnalysis.tsx | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/activityStats.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/activityStats.tsx index a55ab453242..c19b9e434be 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/activityStats.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/activityStats.tsx @@ -4,7 +4,7 @@ import { useQuery } from 'react-query'; import { RouteComponentProps } from 'react-router-dom'; ; -import { ACTIVITY_STATS } from '../../../../../constants/evidence'; +import { ACTIVITY_STATS, AUTO_ML_AI_TYPE, } from '../../../../../constants/evidence'; import { ReactTable, Spinner, } from '../../../../Shared/index'; import { getVersionOptions, handlePageFilterClick } from '../../../helpers/evidence/miscHelpers'; import { renderHeader } from '../../../helpers/evidence/renderHelpers'; @@ -89,7 +89,7 @@ const ActivityStats: React.FC> = ({ hist }); } - const formattedRows = promptHealth && promptHealth.prompts && Object.values(promptHealth.prompts).map((prompt: PromptHealthInterface) => { + const formattedRows = activityData?.activity && promptHealth?.prompts && Object.values(promptHealth.prompts).map((prompt: PromptHealthInterface) => { const { session_count, total_responses, @@ -128,6 +128,10 @@ const ActivityStats: React.FC> = ({ hist } }) + if (!formattedRows) { + return + } + const dataTableFields = [ { Header: '', @@ -159,12 +163,12 @@ const ActivityStats: React.FC> = ({ hist key: "averageAttempts", width: 120, }, - { + activityData.activity.ai_type === AUTO_ML_AI_TYPE ? { Header: 'AutoML Confidence', accessor: "averageAutoMLConfidence", key: "averageAutoMLConfidence", width: 120, - }, + } : null, { Header: 'Rule Repeated: Consecutive Attempt', accessor: "ruleRepeatedConsecutiveData", @@ -189,11 +193,7 @@ const ActivityStats: React.FC> = ({ hist key: "averageTimeSpent", width: 160, } - ]; - - if (!formattedRows) { - return - } + ].filter(Boolean); const activityHealth = (
diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx index 08efecf148a..05a38d41ed6 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx @@ -5,7 +5,7 @@ import { useQuery } from 'react-query'; import { RouteComponentProps } from 'react-router-dom'; import { firstBy } from "thenby"; -import { RULES_ANALYSIS } from '../../../../../constants/evidence'; +import { RULES_ANALYSIS, AUTO_ML_AI_TYPE, } from '../../../../../constants/evidence'; import { DropdownInput, ReactTable, Spinner } from '../../../../Shared/index'; import { getVersionOptions, handlePageFilterClick } from "../../../helpers/evidence/miscHelpers"; import { renderHeader } from "../../../helpers/evidence/renderHelpers"; @@ -309,7 +309,7 @@ const RulesAnalysis: React.FC> = ({ hist Aggregated: (row) => (), Cell: ({ row }) => (), }, - { + activityData?.activity?.ai_type === AUTO_ML_AI_TYPE ? { Header: "AutoML Confidence", accessor: "avgConfidence", key: "avgConfidence", @@ -323,7 +323,7 @@ const RulesAnalysis: React.FC> = ({ hist const { avgConfidence } = row.original return (avgConfidence && {avgConfidence}%) } - }, + } : null, { Header: "Total Responses", accessor: "totalResponses", @@ -451,7 +451,7 @@ const RulesAnalysis: React.FC> = ({ hist return () }, }, - ]; + ].filter(Boolean); const promptOptions = activityData && activityData.activity.prompts.map(p => { const promptOption: PromptOption = { ...p } From d723f53c54a27708ccae3199afa189c827e56198 Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Fri, 6 Dec 2024 12:12:56 -0500 Subject: [PATCH 3/9] tests --- .../__snapshots__/activityStats.test.tsx.snap | 68 - .../__snapshots__/rulesAnalysis.test.jsx.snap | 68 - .../evidence/__tests__/activityStats.test.tsx | 37 - .../evidence/__tests__/rulesAnalysis.test.jsx | 45 - .../__snapshots__/activityStats.test.tsx.snap | 2569 ++++++++++++++ .../__tests__/activityStats.test.tsx | 135 + .../__snapshots__/ruleAnalysis.test.tsx.snap | 0 .../__snapshots__/rulesAnalysis.test.tsx.snap | 3050 +++++++++++++++++ .../__tests__/ruleAnalysis.test.tsx | 4 +- .../__tests__/rulesAnalysis.test.tsx | 134 + .../evidence/rulesAnalysis/rulesAnalysis.tsx | 4 +- 11 files changed, 5892 insertions(+), 222 deletions(-) delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/activityStats.test.tsx.snap delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rulesAnalysis.test.jsx.snap delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/activityStats.test.tsx delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rulesAnalysis.test.jsx create mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/__snapshots__/activityStats.test.tsx.snap create mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/activityStats.test.tsx rename services/QuillLMS/client/app/bundles/Staff/components/evidence/{ => rulesAnalysis}/__tests__/__snapshots__/ruleAnalysis.test.tsx.snap (100%) create mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap rename services/QuillLMS/client/app/bundles/Staff/components/evidence/{ => rulesAnalysis}/__tests__/ruleAnalysis.test.tsx (86%) create mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/rulesAnalysis.test.tsx diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/activityStats.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/activityStats.test.tsx.snap deleted file mode 100644 index ea8e4929131..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/activityStats.test.tsx.snap +++ /dev/null @@ -1,68 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ActivityStats component should render ActivityStats 1`] = ` - - - - - -`; diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rulesAnalysis.test.jsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rulesAnalysis.test.jsx.snap deleted file mode 100644 index 434bea9b1b8..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rulesAnalysis.test.jsx.snap +++ /dev/null @@ -1,68 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`RulesAnalysis component should render RulesAnalysis 1`] = ` - - - - - -`; diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/activityStats.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/activityStats.test.tsx deleted file mode 100644 index bcacae7a811..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/activityStats.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { shallow } from 'enzyme'; -import { createMemoryHistory } from 'history'; -import * as React from 'react'; -import { QueryClientProvider } from 'react-query'; -import 'whatwg-fetch'; - -import { DefaultReactQueryClient } from '../../../../Shared/index'; -import ActivityStats from '../activityStats/activityStats'; - -const queryClient = new DefaultReactQueryClient(); - -const history = createMemoryHistory() - -const mockProps = { - match: { - params: { - activityId: '1' - }, - isExact: true, - path: '', - url:'' - }, - history, - location: history.location, -} - -describe('ActivityStats component', () => { - const container = shallow( - - - - ); - - it('should render ActivityStats', () => { - expect(container).toMatchSnapshot(); - }); -}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rulesAnalysis.test.jsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rulesAnalysis.test.jsx deleted file mode 100644 index 0513066fb19..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rulesAnalysis.test.jsx +++ /dev/null @@ -1,45 +0,0 @@ -import { shallow } from 'enzyme'; -import { createMemoryHistory } from 'history'; -import * as React from 'react'; -import { QueryClientProvider } from 'react-query'; -import 'whatwg-fetch'; - -import { DefaultReactQueryClient } from '../../../../Shared'; -import RulesAnalysis from '../rulesAnalysis/rulesAnalysis'; - -jest.mock('qs', () => ({ - default: { - parse: jest.fn(() => ({})) - } -}) -) - -const history = createMemoryHistory() - -const mockProps = { - match: { - params: { - activityId: '1' - }, - isExact: true, - path: '', - url:'' - }, - history, - location: history.location -} - - -const queryClient = new DefaultReactQueryClient(); - -describe('RulesAnalysis component', () => { - const container = shallow( - - - - ); - - it('should render RulesAnalysis', () => { - expect(container).toMatchSnapshot(); - }); -}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/__snapshots__/activityStats.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/__snapshots__/activityStats.test.tsx.snap new file mode 100644 index 00000000000..a94bb7a67d2 --- /dev/null +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/__snapshots__/activityStats.test.tsx.snap @@ -0,0 +1,2569 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ActivityStats Component matches snapshot when ai_type is AUTO_ML_AI_TYPE 1`] = ` +
+
+
+ Header +
+
+
+ +
+

+ Start Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2022 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 27 + + 28 + + 29 + + 30 + + 1 + + 2 + + 3 +
+ 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 +
+ 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 +
+ 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 +
+ 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 +
+ 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 +
+ 19:00 +
+
+
+
+
+
+

+ End Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2023 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 26 + + 27 + + 28 + + 29 + + 30 + + 1 + + 2 +
+ 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 +
+ 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 +
+ 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 +
+ 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 +
+ 31 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 +
+ 19:00 +
+
+
+
+
+
+ +
+
+

+ + Average Time Spent: + + 5 minutes +

+

+ + Average Completion Rate: + + + 75% Completed +

+
+
+ + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +
+
+
+
+
+ Total Responses +
+
+
+
+ Sessions +
+
+
+
+ Final Attempt: Optimal | Sub-Optimal +
+
+
+
+ Average Attempts +
+
+
+
+ AutoML Confidence +
+
+
+
+ Rule Repeated: Consecutive Attempt +
+
+
+
+ Rule Repeated: Non-consecutive Attempt +
+
+
+
+ First Attempt: Optimal | Sub-Optimal +
+
+
+
+ Time Spent +
+
+
+ + Sample Prompt + + + 50 + + 10 + + 70% (7) | 30% (3) + + 1.2 + + 85% + + 20% (2) + + 10% (1) + + 60% (6) | 40% (4) + + 3 minutes +
+
+
+
+`; + +exports[`ActivityStats Component matches snapshot when ai_type is not AUTO_ML_AI_TYPE 1`] = ` +
+
+
+ Header +
+
+
+ +
+

+ Start Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2022 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 27 + + 28 + + 29 + + 30 + + 1 + + 2 + + 3 +
+ 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 +
+ 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 +
+ 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 +
+ 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 +
+ 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 +
+ 19:00 +
+
+
+
+
+
+

+ End Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2023 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 26 + + 27 + + 28 + + 29 + + 30 + + 1 + + 2 +
+ 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 +
+ 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 +
+ 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 +
+ 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 +
+ 31 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 +
+ 19:00 +
+
+
+
+
+
+ +
+
+

+ + Average Time Spent: + + 5 minutes +

+

+ + Average Completion Rate: + + + 75% Completed +

+
+
+ + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + +
+
+
+
+
+ Total Responses +
+
+
+
+ Sessions +
+
+
+
+ Final Attempt: Optimal | Sub-Optimal +
+
+
+
+ Average Attempts +
+
+
+
+ Rule Repeated: Consecutive Attempt +
+
+
+
+ Rule Repeated: Non-consecutive Attempt +
+
+
+
+ First Attempt: Optimal | Sub-Optimal +
+
+
+
+ Time Spent +
+
+
+ + Sample Prompt + + + 50 + + 10 + + 70% (7) | 30% (3) + + 1.2 + + 20% (2) + + 10% (1) + + 60% (6) | 40% (4) + + 3 minutes +
+
+
+
+`; diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/activityStats.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/activityStats.test.tsx new file mode 100644 index 00000000000..bd67ae048f8 --- /dev/null +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/activityStats/__tests__/activityStats.test.tsx @@ -0,0 +1,135 @@ +import * as React from 'react'; +import { render, waitFor, } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { MemoryRouter, Route } from 'react-router-dom'; +import ActivityStats from '../activityStats'; +import { AUTO_ML_AI_TYPE, GEN_AI_AI_TYPE } from '../../../../../../constants/evidence'; + +// Mocking dependencies +jest.mock('../../../../utils/evidence/activityAPIs', () => ({ + fetchActivity: jest.fn(), + fetchActivityVersions: jest.fn(), +})); +jest.mock('../../../../utils/evidence/ruleFeedbackHistoryAPIs', () => ({ + fetchActivityHealth: jest.fn(), + fetchPromptHealth: jest.fn(), +})); +jest.mock('../../../../helpers/evidence/renderHelpers', () => ({ + renderHeader: jest.fn(() =>
Header
), +})); + +const queryClient = new QueryClient(); + +describe('ActivityStats Component', () => { + const mockActivityId = '1'; + + const populateQueryData = (aiType: string | null) => { + queryClient.setQueryData([`activity-${mockActivityId}`, mockActivityId], { + activity: { + ai_type: aiType, + prompts: [ + { + id: 1, + display_name: 'Sample Prompt', + }, + ], + }, + }); + + queryClient.setQueryData( + [`activity-health-by-activity-${mockActivityId}`, mockActivityId], + { + activity: { + average_time_spent: '5 minutes', + average_completion_rate: 75, + }, + } + ); + + queryClient.setQueryData( + [`prompt-health-by-activity-${mockActivityId}`, mockActivityId, '', ''], + { + prompts: { + 1: { + session_count: 10, + total_responses: 50, + display_name: 'Sample Prompt', + num_final_attempt_optimal: 7, + num_final_attempt_not_optimal: 3, + avg_attempts: 1.2, + num_sessions_with_consecutive_repeated_rule: 2, + num_sessions_with_non_consecutive_repeated_rule: 1, + num_first_attempt_optimal: 6, + num_first_attempt_not_optimal: 4, + avg_time_spent: '3 minutes', + avg_confidence: 85, + }, + }, + } + ); + + queryClient.setQueryData( + [`change-logs-for-activity-versions-${mockActivityId}`, mockActivityId], + { + changeLogs: [ + { + id: 1, + state: 'active', + start_date: '2023-01-01', + end_date: '2023-12-31', + }, + ], + } + ); + }; + + const renderComponent = (aiType: string | null) => { + populateQueryData(aiType); + + return render( + + + + + + + + ); + }; + + it('matches snapshot when ai_type is AUTO_ML_AI_TYPE', async () => { + const { container } = renderComponent(AUTO_ML_AI_TYPE); + await waitFor(() => { + expect(container).toMatchSnapshot(); + }) + }); + + it('matches snapshot when ai_type is not AUTO_ML_AI_TYPE', async () => { + const { container } = renderComponent(GEN_AI_AI_TYPE); + await waitFor(() => { + expect(container).toMatchSnapshot(); + }) + }); + + it('shows AutoML Confidence column when ai_type is AUTO_ML_AI_TYPE', async () => { + const { queryByText } = renderComponent(AUTO_ML_AI_TYPE); + await waitFor(() => { + expect(queryByText('AutoML Confidence')).toBeInTheDocument(); + }) + }); + + it('does not show AutoML Confidence column when ai_type is not AUTO_ML_AI_TYPE', async () => { + const { queryByText } = renderComponent(GEN_AI_AI_TYPE); + await waitFor(() => { + expect(queryByText('AutoML Confidence')).not.toBeInTheDocument(); + }) + }); +}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/ruleAnalysis.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/ruleAnalysis.test.tsx.snap similarity index 100% rename from services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/ruleAnalysis.test.tsx.snap rename to services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/ruleAnalysis.test.tsx.snap diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap new file mode 100644 index 00000000000..1e033669f04 --- /dev/null +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap @@ -0,0 +1,3050 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RulesAnalysis Component matches snapshot when ai_type is AUTO_ML_AI_TYPE 1`] = ` +
+
+
+ Header +
+ +
+
+ +
+

+ Start Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2022 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 27 + + 28 + + 29 + + 30 + + 1 + + 2 + + 3 +
+ 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 +
+ 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 +
+ 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 +
+ 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 +
+ 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 +
+ 19:00 +
+
+
+
+
+
+

+ End Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2023 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 26 + + 27 + + 28 + + 29 + + 30 + + 1 + + 2 +
+ 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 +
+ 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 +
+ 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 +
+ 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 +
+ 31 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 +
+ 19:00 +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + +
+
+ API Name +
+
+
+
+
+
+
+ Rule Order +
+
+
+
+ Rule +
+
+
+
+ AutoML Confidence +
+
+
+
+ Total Responses +
+
+
+
+ Rule Repeated: Consecutive +
+
+
+
+ Rule Repeated: Non-Consecutive +
+
+
+
+ Scored Responses +
+
+
+
+ % Strong +
+
+
+
+ % Weak +
+
+
+ + + • + + rules-based-1 + + + ( + 1 + ) + + + + + + + + + + 85 + % + + + + 100.00 + % + + ( + 100 + ) + + + + + 10 + % ( + 10 + ) + + + + 5 + % ( + 5 + ) + + + + 70 + % ( + 70 + ) + + + + + 71.4 + % + + ( + 50 + ) + + + + + 28.6 + % + + ( + 20 + ) + +
+
+
+
+`; + +exports[`RulesAnalysis Component matches snapshot when ai_type is not AUTO_ML_AI_TYPE 1`] = ` +
+
+
+ Header +
+ +
+
+ +
+

+ Start Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2022 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 27 + + 28 + + 29 + + 30 + + 1 + + 2 + + 3 +
+ 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 +
+ 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 +
+ 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 +
+ 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 +
+ 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 +
+ 19:00 +
+
+
+
+
+
+

+ End Date: +

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + ‹ + + + December 2023 + + + › + +
+ Su + + Mo + + Tu + + We + + Th + + Fr + + Sa +
+ 26 + + 27 + + 28 + + 29 + + 30 + + 1 + + 2 +
+ 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 +
+ 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 +
+ 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 +
+ 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 +
+ 31 + + 1 + + 2 + + 3 + + 4 + + 5 + + 6 +
+ 19:00 +
+
+
+
+
+
+ +
+
+ + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + +
+
+ API Name +
+
+
+
+
+
+
+ Rule Order +
+
+
+
+ Rule +
+
+
+
+ Total Responses +
+
+
+
+ Rule Repeated: Consecutive +
+
+
+
+ Rule Repeated: Non-Consecutive +
+
+
+
+ Scored Responses +
+
+
+
+ % Strong +
+
+
+
+ % Weak +
+
+
+ + + • + + rules-based-1 + + + ( + 1 + ) + + + + + + + + + + 100.00 + % + + ( + 100 + ) + + + + + 10 + % ( + 10 + ) + + + + 5 + % ( + 5 + ) + + + + 70 + % ( + 70 + ) + + + + + 71.4 + % + + ( + 50 + ) + + + + + 28.6 + % + + ( + 20 + ) + +
+
+
+
+`; diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/ruleAnalysis.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/ruleAnalysis.test.tsx similarity index 86% rename from services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/ruleAnalysis.test.tsx rename to services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/ruleAnalysis.test.tsx index de3dc9d8131..6e4d1adfa3f 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/ruleAnalysis.test.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/ruleAnalysis.test.tsx @@ -4,8 +4,8 @@ import * as React from 'react'; import { QueryClientProvider } from 'react-query'; import 'whatwg-fetch'; -import { DefaultReactQueryClient } from '../../../../Shared'; -import RuleAnalysis from '../rulesAnalysis/ruleAnalysis'; +import { DefaultReactQueryClient } from '../../../../../Shared'; +import RuleAnalysis from '../ruleAnalysis'; const history = createMemoryHistory() diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/rulesAnalysis.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/rulesAnalysis.test.tsx new file mode 100644 index 00000000000..fbadc77e1c2 --- /dev/null +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/rulesAnalysis.test.tsx @@ -0,0 +1,134 @@ +import * as React from 'react'; +import { render, waitFor, } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { MemoryRouter, Route, } from 'react-router-dom'; + +import { AUTO_ML_AI_TYPE, GEN_AI_AI_TYPE, BECAUSE, } from '../../../../../../constants/evidence' +import RulesAnalysis from '../rulesAnalysis'; + +jest.mock('../../../../utils/evidence/activityAPIs', () => ({ + fetchActivity: jest.fn(), + fetchActivityVersions: jest.fn(), +})); + +jest.mock('../../../../utils/evidence/ruleFeedbackHistoryAPIs', () => ({ + fetchRuleFeedbackHistories: jest.fn(), +})); + +jest.mock('../../../../helpers/evidence/renderHelpers', () => ({ + renderHeader: jest.fn(() =>
Header
), +})); + +const queryClient = new QueryClient(); + +describe('RulesAnalysis Component', () => { + const mockActivityId = '1'; + const mockConjunction = BECAUSE; + + const populateQueryData = (aiType: string | null) => { + queryClient.setQueryData([`activity-${mockActivityId}`, mockActivityId], { + activity: { + ai_type: aiType, + prompts: [ + { + id: 1, + conjunction: mockConjunction, + text: 'Sample Prompt', + }, + ], + }, + }); + + queryClient.setQueryData( + [`change-logs-for-activity-versions-${mockActivityId}`, mockActivityId, { ignoreCount: true }], + { + changeLogs: [{ id: 1, state: 'active', start_date: '2023-01-01', end_date: '2023-12-31' }], + } + ); + + queryClient.setQueryData( + [`rule-feedback-history-by-conjunction-${mockConjunction}-and-activity-${mockActivityId}`, mockActivityId, mockConjunction, '', ''], + { + ruleFeedbackHistories: [ + { + api_name: 'rules-based-1', + rule_name: 'Sample Rule', + rule_uid: 'rule-1', + rule_suborder: 1, + note: 'Test note', + total_responses: 100, + strong_responses: 50, + weak_responses: 20, + repeated_consecutive_responses: 10, + repeated_non_consecutive_responses: 5, + avg_confidence: 85, + }, + ], + } + ); + + queryClient.setQueryData( + [`rule-feedback-history-for-total-response-count`, mockActivityId, mockConjunction, '', ''], + { + ruleFeedbackHistories: [ + { + total_responses: 100, + }, + ], + } + ); + }; + + const renderComponent = (aiType: string | null) => { + populateQueryData(aiType); + + return render( + + + + + + + + ); + }; + + it('matches snapshot when ai_type is AUTO_ML_AI_TYPE', async () => { + const { container } = renderComponent(AUTO_ML_AI_TYPE); + await waitFor(() => { + expect(container).toMatchSnapshot(); + }) + }); + + it('matches snapshot when ai_type is not AUTO_ML_AI_TYPE', async () => { + const { container } = renderComponent(GEN_AI_AI_TYPE); + await waitFor(() => { + expect(container).toMatchSnapshot(); + }) + }); + + it('shows AutoML Confidence column when ai_type is AUTO_ML_AI_TYPE', async () => { + const { queryByText } = renderComponent(AUTO_ML_AI_TYPE); + await waitFor(() => { + expect(queryByText('AutoML Confidence')).toBeInTheDocument(); + }) + }); + + it('does not show AutoML Confidence column when ai_type is not AUTO_ML_AI_TYPE', async () => { + const { queryByText } = renderComponent(null); + await waitFor(() => { + expect(queryByText('AutoML Confidence')).not.toBeInTheDocument(); + }) + }); +}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx index 05a38d41ed6..b2c9faec591 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/rulesAnalysis.tsx @@ -169,7 +169,7 @@ const RulesAnalysis: React.FC> = ({ hist }, [dataForTotalResponseCount, startDate, endDate, startDateForQuery, endDateForQuery]); React.useEffect(() => { - if (selectedPrompt && ruleFeedbackHistory && ruleFeedbackHistory.ruleFeedbackHistories && ruleFeedbackHistory.ruleFeedbackHistories) { + if (selectedPrompt && ruleFeedbackHistory?.ruleFeedbackHistories) { const formattedRows = ruleFeedbackHistory.ruleFeedbackHistories.filter(rule => { return selectedRuleType.value === DEFAULT_RULE_TYPE || rule.api_name === selectedRuleType.value }).map(rule => { @@ -198,7 +198,7 @@ const RulesAnalysis: React.FC> = ({ hist }).sort(firstBy('apiOrder').thenBy('ruleOrder')); setFormattedRows(formattedRows); } - }, [ruleFeedbackHistory, selectedRuleType]) + }, [ruleFeedbackHistory, selectedRuleType, selectedPrompt]) function handleVersionSelection(versionOption: DropdownObjectInterface) { setVersionOption(versionOption); From 0d28aa1c6207307a4f6a37186c670653a71bd41d Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Fri, 6 Dec 2024 14:46:27 -0500 Subject: [PATCH 4/9] tests --- .../__snapshots__/rules.test.tsx.snap | 80 --------------- .../evidence/__tests__/rules.test.tsx | 40 -------- .../configureRules/__tests__/rules.test.tsx | 97 +++++++++++++++++++ .../evidence/configureRules/rules.tsx | 3 +- 4 files changed, 99 insertions(+), 121 deletions(-) delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rules.test.tsx.snap delete mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rules.test.tsx create mode 100644 services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rules.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rules.test.tsx.snap deleted file mode 100644 index 61469eb48b3..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/__snapshots__/rules.test.tsx.snap +++ /dev/null @@ -1,80 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Rules component should render Rules 1`] = ` - - - - - -`; diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rules.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rules.test.tsx deleted file mode 100644 index 16268593a6f..00000000000 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/__tests__/rules.test.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { shallow } from 'enzyme'; -import { createMemoryHistory } from 'history'; -import * as React from 'react'; -import { QueryClientProvider } from 'react-query'; - -import 'whatwg-fetch'; -import { DefaultReactQueryClient } from '../../../../Shared'; -import Rules from '../configureRules/rules'; - -const history = createMemoryHistory() - -const mockProps = { - activityId: '17', - prompt: [{id: 1, conjunction: 'because', text: 'test', max_attempts: 5, max_attempts_feedback: 'good try!'}], - match: { - params: { - activityId: '1' - }, - isExact: true, - path: '', - url:'' - }, - history, - location: history.location, -} - - -const queryClient = new DefaultReactQueryClient(); - -describe('Rules component', () => { - const container = shallow( - - - - ); - - it('should render Rules', () => { - expect(container).toMatchSnapshot(); - }); -}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx new file mode 100644 index 00000000000..4b5c22d5762 --- /dev/null +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx @@ -0,0 +1,97 @@ +import * as React from 'react'; +import { render, waitFor } from '@testing-library/react'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { MemoryRouter } from 'react-router-dom'; +import Rules from '../rules'; + +// Mock dependencies +jest.mock('../../../../utils/evidence/activityAPIs', () => ({ + fetchActivity: jest.fn(), +})); +jest.mock('../../../../utils/evidence/ruleAPIs', () => ({ + fetchRules: jest.fn(), +})); +jest.mock('../../../../utils/evidence/conceptAPIs', () => ({ + fetchConcepts: jest.fn(), +})); +jest.mock('../../../../helpers/evidence/promptHelpers', () => ({ + getPromptsIcons: jest.fn(() => ({ + because: 'icon-because', + but: 'icon-but', + so: 'icon-so', + })), +})); +jest.mock('../../../../helpers/evidence/ruleHelpers', () => ({ + getConceptName: jest.fn(() => 'Sample Concept'), +})); + +const queryClient = new QueryClient(); + +describe('Rules Component', () => { + const mockActivityId = '1'; + const mockPrompt = { id: '101', name: 'Mock Prompt' }; + + const mockRuleOne = { id: '1', name: 'Rule 1', rule_type: 'type1', prompt_ids: [mockPrompt.id], feedbacks: [], concept_uid: null, universal: false } + const mockRuleTwo = { id: '2', name: 'Rule 2', rule_type: 'type2', prompt_ids: ['102'], feedbacks: [], concept_uid: null, universal: false } + const mockRuleThree = { id: '3', name: 'Rule 3', rule_type: 'type1', prompt_ids: [mockPrompt.id, '102'], feedbacks: [], concept_uid: null, universal: false } + + const mockRules = [ + mockRuleOne, + mockRuleTwo, + mockRuleThree + ]; + + const populateQueryData = () => { + queryClient.setQueryData([`activity-${mockActivityId}`, mockActivityId], { + activity: { id: mockActivityId, name: 'Activity 1' }, + }); + + queryClient.setQueryData([`rules-${mockActivityId}`, mockActivityId], { + rules: mockRules, + }); + + queryClient.setQueryData(['concepts', mockActivityId], { + concepts: [{ uid: '1', name: 'Concept 1' }], + }); + }; + + const renderComponent = (prompt = null) => { + populateQueryData(); + + return render( + + + + + + ); + }; + + it('filters rules based on the provided prompt', async () => { + const { queryByText, queryByAltText } = renderComponent(mockPrompt); + + await waitFor(() => { + expect(queryByAltText('Loading spinner')).not.toBeInTheDocument(); + }); + + await waitFor(() => { + expect(queryByText(mockRuleOne.name)).toBeInTheDocument(); + expect(queryByText(mockRuleTwo.name)).not.toBeInTheDocument(); + expect(queryByText(mockRuleThree.name)).toBeInTheDocument(); + }); + }); + + it('shows all rules when no prompt is provided', async () => { + const { queryByText, queryByAltText } = renderComponent(); + + await waitFor(() => { + expect(queryByAltText('Loading spinner')).not.toBeInTheDocument(); + }); + + await waitFor(() => { + expect(queryByText(mockRuleOne.name)).toBeInTheDocument(); + expect(queryByText(mockRuleTwo.name)).toBeInTheDocument(); + expect(queryByText(mockRuleThree.name)).toBeInTheDocument(); + }); + }); +}); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx index c67eadd4947..3c8c9f9ddf9 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/rules.tsx @@ -42,7 +42,8 @@ const Rules = ({ activityId, history, prompt }: RulesProps) => { // cache rules data for updates const { data: rulesData } = useQuery({ queryKey: [`rules-${activityId}`, activityId], - queryFn: fetchRules + queryFn: fetchRules, + staleTime: Infinity, }); const { data: conceptsData } = useQuery({ From 9358ae0cf184efaa7e424f778fcc1b81cb43edd6 Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Mon, 9 Dec 2024 11:35:56 -0500 Subject: [PATCH 5/9] lint/test fix --- .../configureRules/__tests__/rules.test.tsx | 2 +- .../__snapshots__/rulesAnalysis.test.tsx.snap | 16 ++++++++-------- .../__tests__/rulesAnalysis.test.tsx | 11 ++++++++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx index 4b5c22d5762..f0d2094ad25 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/configureRules/__tests__/rules.test.tsx @@ -61,7 +61,7 @@ describe('Rules Component', () => { return render( - + ); diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap index 1e033669f04..1de242c73e3 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap @@ -731,7 +731,7 @@ exports[`RulesAnalysis Component matches snapshot when ai_type is AUTO_ML_AI_TYP
({ const queryClient = new QueryClient(); describe('RulesAnalysis Component', () => { + beforeEach(() => { + jest.useFakeTimers('modern'); + jest.setSystemTime(new Date('2023-12-25')); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + const mockActivityId = '1'; const mockConjunction = BECAUSE; @@ -42,7 +51,7 @@ describe('RulesAnalysis Component', () => { queryClient.setQueryData( [`change-logs-for-activity-versions-${mockActivityId}`, mockActivityId, { ignoreCount: true }], { - changeLogs: [{ id: 1, state: 'active', start_date: '2023-01-01', end_date: '2023-12-31' }], + changeLogs: [{ id: 1, state: 'active', start_date: '2023-01-01', end_date: '2023-12-20' }], } ); From 21d0a9d9033ef556933713cfbc320bb45566a930 Mon Sep 17 00:00:00 2001 From: Emilia Friedberg Date: Mon, 9 Dec 2024 11:45:06 -0500 Subject: [PATCH 6/9] additional test update --- .../__snapshots__/rulesAnalysis.test.tsx.snap | 264 +++++++++--------- .../__tests__/rulesAnalysis.test.tsx | 2 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap index 1de242c73e3..7942f585312 100644 --- a/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap +++ b/services/QuillLMS/client/app/bundles/Staff/components/evidence/rulesAnalysis/__tests__/__snapshots__/rulesAnalysis.test.tsx.snap @@ -216,7 +216,7 @@ exports[`RulesAnalysis Component matches snapshot when ai_type is AUTO_ML_AI_TYP