bohui-vue 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/README.md +121 -0
  2. package/bin/create-vue-template.js +565 -0
  3. package/package.json +28 -0
  4. package/templates/vue-project/.browserslistrc +3 -0
  5. package/templates/vue-project/.editorconfig +28 -0
  6. package/templates/vue-project/.env.development +2 -0
  7. package/templates/vue-project/.env.production +2 -0
  8. package/templates/vue-project/.eslintrc.cjs +76 -0
  9. package/templates/vue-project/.keep +0 -0
  10. package/templates/vue-project/.node-version +1 -0
  11. package/templates/vue-project/.prettierignore +13 -0
  12. package/templates/vue-project/.prettierrc +20 -0
  13. package/templates/vue-project/.prettierrc.txt +130 -0
  14. package/templates/vue-project/.stylelintrc.json +94 -0
  15. package/templates/vue-project/README.md +24 -0
  16. package/templates/vue-project/babel.config.js +5 -0
  17. package/templates/vue-project/index.html +34 -0
  18. package/templates/vue-project/package.json +75 -0
  19. package/templates/vue-project/public/favicon.ico +0 -0
  20. package/templates/vue-project/public/static/img/ai-default.jpg +0 -0
  21. package/templates/vue-project/public/static/img/image.png +0 -0
  22. package/templates/vue-project/public/static/img/ppt1.png +0 -0
  23. package/templates/vue-project/public/static/img/ppt2.png +0 -0
  24. package/templates/vue-project/public/static/img/ppt3.png +0 -0
  25. package/templates/vue-project/public/static/js/config.js +11 -0
  26. package/templates/vue-project/public/static/js/dataConfig.js +1143 -0
  27. package/templates/vue-project/src/App.vue +10 -0
  28. package/templates/vue-project/src/api/error-handler.ts +60 -0
  29. package/templates/vue-project/src/api/http.ts +254 -0
  30. package/templates/vue-project/src/api/services/aicebd.ts +47 -0
  31. package/templates/vue-project/src/api/services/base.ts +18 -0
  32. package/templates/vue-project/src/api/services/umse.ts +17 -0
  33. package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Medium.otf +0 -0
  34. package/templates/vue-project/src/assets/font/Alibaba-PuHuiTi-Regular.otf +0 -0
  35. package/templates/vue-project/src/assets/font/DOUYINSANSBOLD.OTF +0 -0
  36. package/templates/vue-project/src/assets/font/Pangmen-Title.TTF +0 -0
  37. package/templates/vue-project/src/assets/font/font.css +25 -0
  38. package/templates/vue-project/src/assets/iconfont/iconfont.css +402 -0
  39. package/templates/vue-project/src/assets/iconfont/iconfont.js +66 -0
  40. package/templates/vue-project/src/assets/iconfont/iconfont.json +688 -0
  41. package/templates/vue-project/src/assets/iconfont/iconfont.ttf +0 -0
  42. package/templates/vue-project/src/assets/iconfont/iconfont.woff +0 -0
  43. package/templates/vue-project/src/assets/iconfont/iconfont.woff2 +0 -0
  44. package/templates/vue-project/src/assets/images/Click-tap.png +0 -0
  45. package/templates/vue-project/src/assets/images/Effects.png +0 -0
  46. package/templates/vue-project/src/assets/images/bg.png +0 -0
  47. package/templates/vue-project/src/assets/images/erCode.png +0 -0
  48. package/templates/vue-project/src/assets/images/header-bg.png +0 -0
  49. package/templates/vue-project/src/assets/images/logo.png +0 -0
  50. package/templates/vue-project/src/assets/scss/common.scss +530 -0
  51. package/templates/vue-project/src/assets/styles/element-overrides.css +53 -0
  52. package/templates/vue-project/src/assets/styles/reset.css +186 -0
  53. package/templates/vue-project/src/assets/styles/theme.css +100 -0
  54. package/templates/vue-project/src/components/BarChart.vue +238 -0
  55. package/templates/vue-project/src/components/echarts/EChart.vue +140 -0
  56. package/templates/vue-project/src/composables/useTheme.ts +84 -0
  57. package/templates/vue-project/src/main.ts +111 -0
  58. package/templates/vue-project/src/mocks/base.ts +37 -0
  59. package/templates/vue-project/src/mocks/umse.ts +31 -0
  60. package/templates/vue-project/src/router/index.ts +32 -0
  61. package/templates/vue-project/src/shims-vue.d.ts +19 -0
  62. package/templates/vue-project/src/store/index.ts +18 -0
  63. package/templates/vue-project/src/store/modules/user.ts +85 -0
  64. package/templates/vue-project/src/types/DTO/aicebd.d.ts +60 -0
  65. package/templates/vue-project/src/types/DTO/base.d.ts +26 -0
  66. package/templates/vue-project/src/types/DTO/global.d.ts +48 -0
  67. package/templates/vue-project/src/types/VO/teachingLog.d.ts +15 -0
  68. package/templates/vue-project/src/types/auto-imports.d.ts +73 -0
  69. package/templates/vue-project/src/types/components.d.ts +17 -0
  70. package/templates/vue-project/src/types/element-plus.d.ts +15 -0
  71. package/templates/vue-project/src/types/js-cookie.d.ts +1 -0
  72. package/templates/vue-project/src/types/unocss.d.ts +2 -0
  73. package/templates/vue-project/src/types/vite-plugins.d.ts +3 -0
  74. package/templates/vue-project/src/types/vue-router.d.ts +1 -0
  75. package/templates/vue-project/src/types/window-config.d.ts +12 -0
  76. package/templates/vue-project/src/utils/com-methods.ts +307 -0
  77. package/templates/vue-project/src/utils/echarts.ts +111 -0
  78. package/templates/vue-project/src/utils/number.ts +99 -0
  79. package/templates/vue-project/src/utils/rem.ts +82 -0
  80. package/templates/vue-project/src/utils/responsive.ts +103 -0
  81. package/templates/vue-project/src/utils/time.ts +314 -0
  82. package/templates/vue-project/src/utils/tracker.ts +527 -0
  83. package/templates/vue-project/src/utils/validators.ts +85 -0
  84. package/templates/vue-project/src/utils/window.ts +132 -0
  85. package/templates/vue-project/src/views/home/Home.vue +60 -0
  86. package/templates/vue-project/src/views/home/composables/useUserAuth.ts +13 -0
  87. package/templates/vue-project/src/views/teachingLog/TeachingLog.vue +40 -0
  88. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingEffect.test.ts +96 -0
  89. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingHighlight.test.ts +66 -0
  90. package/templates/vue-project/src/views/teachingLog/__tests__/TeachingLog.test.ts +34 -0
  91. package/templates/vue-project/src/views/teachingLog/components/TeachingEffect.vue +458 -0
  92. package/templates/vue-project/src/views/teachingLog/components/TeachingHighlight.vue +181 -0
  93. package/templates/vue-project/src/views/teachingLog/composables/useEffectTooltip.ts +88 -0
  94. package/templates/vue-project/src/views/teachingLog/composables/useEffectTrendChart.ts +160 -0
  95. package/templates/vue-project/tests/setup.ts +27 -0
  96. package/templates/vue-project/tsconfig.json +24 -0
  97. package/templates/vue-project/tsconfig.node.json +41 -0
  98. package/templates/vue-project/uno.config.ts +84 -0
  99. package/templates/vue-project/vite.config.ts +216 -0
  100. package/templates/vue-project/vue3_ai_prompt.md +652 -0
  101. package/templates/vue-project/vue3_ai_prompt_basic.md +722 -0
  102. package/templates/vue-project/vue3_ai_prompt_full.md +1021 -0
  103. package/templates/vue-project/vue3_ai_prompt_unocss.md +768 -0
  104. package/templates/vue-project//345/267/245/347/250/213/345/214/226/346/250/241/346/235/277/344/273/213/347/273/215.md +463 -0
@@ -0,0 +1,132 @@
1
+ /**
2
+ * 解析 URL 中的所有字段(同时支持 query 与 hash 中的 query)
3
+ * @param url 需要解析的浏览器访问地址字符串
4
+ * @returns 字段键值对对象,若不存在返回空对象
5
+ * @example
6
+ * getAllFieldsFromUrl('http://host/app?token=abc#/#/course?name=math&token=xyz')
7
+ * // { token: 'xyz', name: 'math' } // hash 中的同名字段覆盖主 query
8
+ */
9
+ export function getAllFieldsFromUrl(url: string): Record<string, string> {
10
+ const result: Record<string, string> = {};
11
+ const parseParams = (query: string) => {
12
+ const params = new URLSearchParams(query);
13
+ params.forEach((value, key) => {
14
+ result[key] = value;
15
+ });
16
+ };
17
+ let u: URL | null = null;
18
+ try {
19
+ u = new URL(url);
20
+ } catch {
21
+ try {
22
+ u = new URL(url, window.location.origin);
23
+ } catch {
24
+ u = null;
25
+ }
26
+ }
27
+ if (u) {
28
+ if (u.search) parseParams(u.search);
29
+ if (u.hash) {
30
+ const hash = u.hash.startsWith("#") ? u.hash.slice(1) : u.hash;
31
+ const idx = hash.indexOf("?");
32
+ if (idx !== -1) parseParams(hash.slice(idx));
33
+ }
34
+ return result;
35
+ }
36
+ const qIdx = url.indexOf("?");
37
+ const hIdx = url.indexOf("#");
38
+ if (qIdx !== -1) {
39
+ const end = hIdx !== -1 ? hIdx : url.length;
40
+ parseParams(url.slice(qIdx, end));
41
+ }
42
+ if (hIdx !== -1) {
43
+ const hash = url.slice(hIdx + 1);
44
+ const idx = hash.indexOf("?");
45
+ if (idx !== -1) parseParams(hash.slice(idx));
46
+ }
47
+ return result;
48
+ }
49
+
50
+ /**
51
+ * 从 URL 中获取指定字段的值
52
+ * @param url 浏览器访问地址字符串
53
+ * @param key 需要获取的字段名
54
+ * @returns 字段值,若不存在返回 null
55
+ */
56
+ export function getFieldFromUrl(url: string, key: string): string | null {
57
+ const all = getAllFieldsFromUrl(url);
58
+ return key in all ? all[key] : null;
59
+ }
60
+
61
+ /**
62
+ * 从 URL 中移除指定字段(支持从主 query 与 hash query 中移除)并返回新的地址
63
+ * @param url 原始地址字符串
64
+ * @param keys 需要移除的字段名(字符串或字符串数组)
65
+ * @returns 处理后的新地址字符串
66
+ * @example
67
+ * removeFieldsFromUrl('http://host/app?token=abc#/#/course?name=math&token=xyz', ['token'])
68
+ * // 'http://host/app#/#/course?name=math'
69
+ */
70
+ export function removeFieldsFromUrl(url: string, keys: string | string[]): string {
71
+ const toDelete = Array.isArray(keys) ? keys : [keys];
72
+ let u: URL | null = null;
73
+ try {
74
+ u = new URL(url);
75
+ } catch {
76
+ try {
77
+ u = new URL(url, window.location.origin);
78
+ } catch {
79
+ u = null;
80
+ }
81
+ }
82
+ if (u) {
83
+ toDelete.forEach((k) => u!.searchParams.delete(k));
84
+ const hash = u.hash ? u.hash.slice(1) : "";
85
+ if (hash) {
86
+ const qIdx = hash.indexOf("?");
87
+ if (qIdx !== -1) {
88
+ const base = hash.slice(0, qIdx);
89
+ const q = hash.slice(qIdx + 1);
90
+ const params = new URLSearchParams(q);
91
+ toDelete.forEach((k) => params.delete(k));
92
+ const qs = params.toString();
93
+ u.hash = qs ? `#${base}?${qs}` : `#${base}`;
94
+ }
95
+ }
96
+ const qs = u.searchParams.toString();
97
+ u.search = qs ? `?${qs}` : "";
98
+ return u.toString();
99
+ }
100
+ const qIdx = url.indexOf("?");
101
+ const hIdx = url.indexOf("#");
102
+ let base = url;
103
+ let query = "";
104
+ let hash = "";
105
+ if (qIdx !== -1) {
106
+ base = url.slice(0, qIdx);
107
+ const end = hIdx !== -1 ? hIdx : url.length;
108
+ query = url.slice(qIdx + 1, end);
109
+ }
110
+ if (hIdx !== -1) {
111
+ hash = url.slice(hIdx + 1);
112
+ }
113
+ if (query) {
114
+ const params = new URLSearchParams(query);
115
+ toDelete.forEach((k) => params.delete(k));
116
+ query = params.toString();
117
+ }
118
+ if (hash) {
119
+ const idx = hash.indexOf("?");
120
+ if (idx !== -1) {
121
+ const hBase = hash.slice(0, idx);
122
+ const hQuery = hash.slice(idx + 1);
123
+ const hParams = new URLSearchParams(hQuery);
124
+ toDelete.forEach((k) => hParams.delete(k));
125
+ const hQs = hParams.toString();
126
+ hash = hQs ? `${hBase}?${hQs}` : hBase;
127
+ }
128
+ }
129
+ const qs = query ? `?${query}` : "";
130
+ const hs = hash ? `#${hash}` : "";
131
+ return `${base}${qs}${hs}`;
132
+ }
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <div id="HomePage">
3
+ <div class="home-page-content">
4
+ <div @click="logout">退出登录</div>
5
+ <el-input
6
+ ref="inputRef"
7
+ v-model="searchText"
8
+ placeholder="请输入搜索内容"
9
+ />
10
+ <div @click="focusInput">聚焦输入框</div>
11
+ <BarChart :bar-chart-data="BarChartTestData" />
12
+ <router-view />
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import { useUserAuth } from "@/views/home/composables/useUserAuth";
19
+ import BarChart from "@/components/BarChart.vue";
20
+
21
+ // 柱状图测试数据
22
+ const BarChartTestData = {
23
+ title: "这个是图表的标题",
24
+ categories: ["出勤率", "前排就座率", "学习专注度", "课堂活跃度"],
25
+ barWidth: 20,
26
+ series: [
27
+ { name: "最新课堂", color: "#22C798", values: [80, 15, 65, 15] },
28
+ { name: "本班平均", color: "#8979FF", values: [64, 76, 70, 37] },
29
+ ],
30
+ };
31
+
32
+ /**
33
+ * 用户登入退出
34
+ */
35
+ const { logout } = useUserAuth();
36
+
37
+ /**
38
+ * 搜索内容
39
+ */
40
+ const searchText = ref("");
41
+ const inputRef = ref<ElementPlus.InputInstanceType | null>(null);
42
+
43
+ function focusInput() {
44
+ inputRef.value?.focus?.();
45
+ }
46
+ </script>
47
+
48
+ <style scoped lang="scss">
49
+ #HomePage {
50
+ width: 100%;
51
+ height: 100%;
52
+ background: url("@/assets/images/bg.png") no-repeat center center;
53
+ background-size: cover;
54
+ }
55
+
56
+ .home-page-content {
57
+ width: 100%;
58
+ height: 100%;
59
+ }
60
+ </style>
@@ -0,0 +1,13 @@
1
+ import { useUserStore } from "@/store";
2
+
3
+ export type UseUserAuthReturn = {
4
+ logout: () => void;
5
+ fetchUserInfo: () => void;
6
+ };
7
+
8
+ export const useUserAuth = (): UseUserAuthReturn => {
9
+ const store = useUserStore();
10
+ const logout = () => store.logout();
11
+ const fetchUserInfo = () => store.setUserInfo();
12
+ return { logout, fetchUserInfo };
13
+ };
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div class="teaching-log-page">
3
+ <TeachingEffect :lesson-code="lessonCode" />
4
+ <TeachingHighlight :lesson-code="lessonCode" />
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import TeachingEffect from "./components/TeachingEffect.vue";
10
+ import TeachingHighlight from "./components/TeachingHighlight.vue";
11
+
12
+ const lessonCode = window.DataConfig?.lessonCode || "";
13
+ </script>
14
+
15
+ <style scoped lang="scss">
16
+ .teaching-log-page {
17
+ background-color: #101012;
18
+ height: 100%;
19
+ padding: 4rem 4rem;
20
+ overflow: auto;
21
+ scrollbar-color: #2b2f36 #0f1114;
22
+ scrollbar-width: none;
23
+ }
24
+ @media screen and (max-width: 640px) {
25
+ .teaching-log-page {
26
+ padding: 0;
27
+ }
28
+ }
29
+ /* WebKit */
30
+ :global(::-webkit-scrollbar-track) {
31
+ background-color: #0f1114;
32
+ }
33
+ :global(::-webkit-scrollbar-thumb) {
34
+ background-color: #2b2f36;
35
+ border-radius: 6px;
36
+ }
37
+ :global(::-webkit-scrollbar-thumb:hover) {
38
+ background-color: #434953;
39
+ }
40
+ </style>
@@ -0,0 +1,96 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { nextTick } from "vue";
3
+ import { describe, expect, it, vi } from "vitest";
4
+
5
+ type InitTrendChart = (el: HTMLElement, trend: Array<[number, number]>) => { dispose: () => void };
6
+ const initTrendChartMock = vi.fn<InitTrendChart>(() => ({ dispose: vi.fn() }));
7
+ vi.mock("../composables/useEffectTrendChart", () => {
8
+ return {
9
+ useEffectTrendChart: () => ({
10
+ initTrendChart: initTrendChartMock,
11
+ }),
12
+ };
13
+ });
14
+
15
+ function setDataConfig(data: unknown) {
16
+ (window as unknown as { DataConfig?: unknown }).DataConfig = data;
17
+ }
18
+
19
+ describe("TeachingEffect", () => {
20
+ it("renders stats, trend call args, and tooltip", async () => {
21
+ setDataConfig({
22
+ teachingEffect: {
23
+ attendanceData: {
24
+ attendanceStudentNum: 40,
25
+ attendanceStudentRate: 0.8,
26
+ frontRowSeats: 10,
27
+ frontStudentNum: 12,
28
+ frontStudentRate: 0.3,
29
+ lateNum: 0,
30
+ leaveEarlyNum: 0,
31
+ lessonCode: "",
32
+ shouldStudentNum: 50,
33
+ totalStudentSeats: 50,
34
+ },
35
+ overviewData: {
36
+ attendanceNum: 40,
37
+ attendanceRate: 0.8,
38
+ focusAvg: 0.4567,
39
+ heighFocus: 0,
40
+ heighPerformanceTeachingTimeRangePercentage: 0,
41
+ lowFocus: 0,
42
+ lowPerformanceTeachingTimeRangePercentage: 0,
43
+ },
44
+ focusTrendData: [
45
+ {
46
+ order: 2,
47
+ focusAvg: 0.2,
48
+ speechSpeed: 0,
49
+ teachingContent: "",
50
+ teachingSession: "",
51
+ },
52
+ {
53
+ order: 1,
54
+ focusAvg: 0.1,
55
+ speechSpeed: 0,
56
+ teachingContent: "",
57
+ teachingSession: "",
58
+ },
59
+ ],
60
+ focusDecrease: [
61
+ { time: "00:03:00", focus: 10, description: "下降点说明", image: "x" },
62
+ ],
63
+ },
64
+ });
65
+
66
+ vi.resetModules();
67
+ const { default: TeachingEffect } = await import("../components/TeachingEffect.vue");
68
+
69
+ const wrapper = mount(TeachingEffect, { props: { lessonCode: "" } });
70
+ await nextTick();
71
+ await nextTick();
72
+
73
+ expect(wrapper.text()).toContain("教学效果");
74
+ expect(wrapper.text()).toContain("学生出勤率");
75
+ expect(wrapper.text()).toContain("80.00%");
76
+ expect(wrapper.text()).toContain("前排就座率");
77
+ expect(wrapper.text()).toContain("30.00%");
78
+ expect(wrapper.text()).toContain("平均专注度");
79
+ expect(wrapper.text()).toContain("45.67%");
80
+
81
+ expect(initTrendChartMock).toHaveBeenCalledTimes(1);
82
+ const trendArg = initTrendChartMock.mock.calls[0][1];
83
+ expect(trendArg).toEqual([
84
+ [60, 10],
85
+ [120, 20],
86
+ ]);
87
+
88
+ const declineImage = wrapper.find(".timeline-image");
89
+ expect(declineImage.exists()).toBe(true);
90
+ await declineImage.trigger("mouseenter");
91
+ await nextTick();
92
+
93
+ expect(wrapper.find(".tooltip-popup").exists()).toBe(true);
94
+ expect(wrapper.find(".tooltip-content").text()).toContain("下降点说明");
95
+ });
96
+ });
@@ -0,0 +1,66 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { nextTick } from "vue";
3
+ import { describe, expect, it, vi } from "vitest";
4
+
5
+ function setDataConfig(data: unknown) {
6
+ (window as unknown as { DataConfig?: unknown }).DataConfig = data;
7
+ }
8
+
9
+ describe("TeachingHighlight", () => {
10
+ it("renders time chips and switches active item", async () => {
11
+ setDataConfig({
12
+ performanceAnalyzeData: {
13
+ upReasonAnalyze: [
14
+ {
15
+ id: 1,
16
+ lessonCode: "",
17
+ createTime: Date.now(),
18
+ startTime: 60_000,
19
+ endTime: 120_000,
20
+ startOrder: 1,
21
+ endOrder: 2,
22
+ startFocus: 0.1234,
23
+ endFocus: 0.5678,
24
+ trendReason: "第一段原因",
25
+ },
26
+ {
27
+ id: 2,
28
+ lessonCode: "",
29
+ createTime: Date.now(),
30
+ startTime: 180_000,
31
+ endTime: 240_000,
32
+ startOrder: 3,
33
+ endOrder: 4,
34
+ startFocus: 0.2,
35
+ endFocus: 0.9,
36
+ trendReason: "第二段原因",
37
+ },
38
+ ],
39
+ },
40
+ });
41
+
42
+ vi.resetModules();
43
+ const { default: TeachingHighlight } = await import("../components/TeachingHighlight.vue");
44
+
45
+ const wrapper = mount(TeachingHighlight, { props: { lessonCode: "" } });
46
+ await nextTick();
47
+
48
+ const chips = wrapper.findAll(".time-chip");
49
+ expect(chips.length).toBe(2);
50
+ expect(chips[0].classes()).toContain("active");
51
+
52
+ expect(wrapper.text()).toContain("专注度从");
53
+ expect(wrapper.text()).toContain("12.34%");
54
+ expect(wrapper.text()).toContain("56.78%");
55
+ expect(wrapper.text()).toContain("第一段原因");
56
+
57
+ await chips[1].trigger("click");
58
+ await nextTick();
59
+
60
+ expect(chips[1].classes()).toContain("active");
61
+ expect(wrapper.text()).toContain("20%");
62
+ expect(wrapper.text()).toContain("90%");
63
+ expect(wrapper.text()).toContain("第二段原因");
64
+ });
65
+ });
66
+
@@ -0,0 +1,34 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, expect, it, vi } from "vitest";
3
+
4
+ function setDataConfig(data: unknown) {
5
+ (window as unknown as { DataConfig?: unknown }).DataConfig = data;
6
+ }
7
+
8
+ describe("TeachingLog page", () => {
9
+ it("passes lessonCode from window.DataConfig to child components", async () => {
10
+ setDataConfig({ lessonCode: "LESSON_001" });
11
+
12
+ vi.resetModules();
13
+ const { default: TeachingLog } = await import("../TeachingLog.vue");
14
+
15
+ const wrapper = mount(TeachingLog, {
16
+ global: {
17
+ stubs: {
18
+ TeachingEffect: {
19
+ props: ["lessonCode"],
20
+ template: '<div data-test="effect">{{ lessonCode }}</div>',
21
+ },
22
+ TeachingHighlight: {
23
+ props: ["lessonCode"],
24
+ template: '<div data-test="highlight">{{ lessonCode }}</div>',
25
+ },
26
+ },
27
+ },
28
+ });
29
+
30
+ expect(wrapper.find('[data-test="effect"]').text()).toBe("LESSON_001");
31
+ expect(wrapper.find('[data-test="highlight"]').text()).toBe("LESSON_001");
32
+ });
33
+ });
34
+