Merge remote-tracking branch 'origin/dev' into chore/login
# Conflicts: # backend/.env.example # backend/package.json # backend/src/app.ts # backend/src/routes/login.ts # backend/src/routes/student.ts # docker-compose.yml # frontend/src/App.vue # frontend/src/views/HomePage.vue # frontend/src/views/LoginPage.vue # package-lock.json
This commit is contained in:
		
						commit
						de0199de96
					
				
					 109 changed files with 3789 additions and 1727 deletions
				
			
		|  | @ -1,8 +1,8 @@ | |||
| import { test, expect } from '@playwright/test'; | ||||
| import { test, expect } from "@playwright/test"; | ||||
| 
 | ||||
| // See here how to get started:
 | ||||
| // https://playwright.dev/docs/intro
 | ||||
| test('visits the app root url', async ({ page }) => { | ||||
|     await page.goto('/'); | ||||
|     await expect(page.locator('h1')).toHaveText('You did it!'); | ||||
| test("visits the app root url", async ({ page }) => { | ||||
|     await page.goto("/"); | ||||
|     await expect(page.locator("h1")).toHaveText("You did it!"); | ||||
| }); | ||||
|  |  | |||
|  | @ -1,12 +1,9 @@ | |||
| import pluginVue from 'eslint-plugin-vue'; | ||||
| import { | ||||
|     defineConfigWithVueTs, | ||||
|     vueTsConfigs, | ||||
| } from '@vue/eslint-config-typescript'; | ||||
| import pluginVitest from '@vitest/eslint-plugin'; | ||||
| import pluginPlaywright from 'eslint-plugin-playwright'; | ||||
| import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'; | ||||
| import rootConfig from '../eslint.config'; | ||||
| import pluginVue from "eslint-plugin-vue"; | ||||
| import { defineConfigWithVueTs, vueTsConfigs } from "@vue/eslint-config-typescript"; | ||||
| import pluginVitest from "@vitest/eslint-plugin"; | ||||
| import pluginPlaywright from "eslint-plugin-playwright"; | ||||
| import skipFormatting from "@vue/eslint-config-prettier/skip-formatting"; | ||||
| import rootConfig from "../eslint.config"; | ||||
| 
 | ||||
| // To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
 | ||||
| // Import { configureVueProject } from '@vue/eslint-config-typescript'
 | ||||
|  | @ -15,31 +12,31 @@ import rootConfig from '../eslint.config'; | |||
| 
 | ||||
| const vueConfig = defineConfigWithVueTs( | ||||
|     { | ||||
|         name: 'app/files-to-lint', | ||||
|         files: ['**/*.{ts,mts,tsx,vue}'], | ||||
|         name: "app/files-to-lint", | ||||
|         files: ["**/*.{ts,mts,tsx,vue}"], | ||||
|         rules: { | ||||
|             "no-useless-assignment": "off", // Depend on `no-unused-vars` to catch this
 | ||||
|         }, | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|         name: 'app/files-to-ignore', | ||||
|         ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'], | ||||
|         name: "app/files-to-ignore", | ||||
|         ignores: ["**/dist/**", "**/dist-ssr/**", "**/coverage/**"], | ||||
|     }, | ||||
| 
 | ||||
|     pluginVue.configs['flat/essential'], | ||||
|     pluginVue.configs["flat/essential"], | ||||
|     vueTsConfigs.recommended, | ||||
| 
 | ||||
|     { | ||||
|         ...pluginVitest.configs.recommended, | ||||
|         files: ['src/**/__tests__/*'], | ||||
|         files: ["src/**/__tests__/*"], | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|         ...pluginPlaywright.configs['flat/recommended'], | ||||
|         files: ['e2e/**/*.{test,spec}.{js,ts,jsx,tsx}'], | ||||
|         ...pluginPlaywright.configs["flat/recommended"], | ||||
|         files: ["e2e/**/*.{test,spec}.{js,ts,jsx,tsx}"], | ||||
|     }, | ||||
|     skipFormatting | ||||
|     skipFormatting, | ||||
| ); | ||||
| 
 | ||||
| export default [ | ||||
|     ...rootConfig, | ||||
|     ...vueConfig | ||||
| ] | ||||
| export default [...rootConfig, ...vueConfig]; | ||||
|  |  | |||
|  | @ -2,12 +2,21 @@ | |||
| <html lang=""> | ||||
|     <head> | ||||
|         <meta charset="UTF-8" /> | ||||
|         <link rel="icon" href="/favicon.ico" /> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|         <link | ||||
|             rel="icon" | ||||
|             href="/favicon.ico" | ||||
|         /> | ||||
|         <meta | ||||
|             name="viewport" | ||||
|             content="width=device-width, initial-scale=1.0" | ||||
|         /> | ||||
|         <title>Vite App</title> | ||||
|     </head> | ||||
|     <body> | ||||
|         <div id="app"></div> | ||||
|         <script type="module" src="/src/main.ts"></script> | ||||
|         <script | ||||
|             type="module" | ||||
|             src="/src/main.ts" | ||||
|         ></script> | ||||
|     </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import process from 'node:process'; | ||||
| import { defineConfig, devices } from '@playwright/test'; | ||||
| import process from "node:process"; | ||||
| import { defineConfig, devices } from "@playwright/test"; | ||||
| 
 | ||||
| /** | ||||
|  * Read environment variables from file. | ||||
|  | @ -11,7 +11,7 @@ import { defineConfig, devices } from '@playwright/test'; | |||
|  * See https://playwright.dev/docs/test-configuration.
 | ||||
|  */ | ||||
| export default defineConfig({ | ||||
|     testDir: './e2e', | ||||
|     testDir: "./e2e", | ||||
|     /* Maximum time one test can run for. */ | ||||
|     timeout: 30 * 1000, | ||||
|     expect: { | ||||
|  | @ -28,18 +28,16 @@ export default defineConfig({ | |||
|     /* Opt out of parallel tests on CI. */ | ||||
|     workers: process.env.CI ? 1 : undefined, | ||||
|     /* Reporter to use. See https://playwright.dev/docs/test-reporters */ | ||||
|     reporter: 'html', | ||||
|     reporter: "html", | ||||
|     /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ | ||||
|     use: { | ||||
|         /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ | ||||
|         actionTimeout: 0, | ||||
|         /* Base URL to use in actions like `await page.goto('/')`. */ | ||||
|         baseURL: process.env.CI | ||||
|             ? 'http://localhost:4173' | ||||
|             : 'http://localhost:5173', | ||||
|         baseURL: process.env.CI ? "http://localhost:4173" : "http://localhost:5173", | ||||
| 
 | ||||
|         /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ | ||||
|         trace: 'on-first-retry', | ||||
|         trace: "on-first-retry", | ||||
| 
 | ||||
|         /* Only on CI systems run the tests headless */ | ||||
|         headless: Boolean(process.env.CI), | ||||
|  | @ -48,21 +46,21 @@ export default defineConfig({ | |||
|     /* Configure projects for major browsers */ | ||||
|     projects: [ | ||||
|         { | ||||
|             name: 'chromium', | ||||
|             name: "chromium", | ||||
|             use: { | ||||
|                 ...devices['Desktop Chrome'], | ||||
|                 ...devices["Desktop Chrome"], | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             name: 'firefox', | ||||
|             name: "firefox", | ||||
|             use: { | ||||
|                 ...devices['Desktop Firefox'], | ||||
|                 ...devices["Desktop Firefox"], | ||||
|             }, | ||||
|         }, | ||||
|         { | ||||
|             name: 'webkit', | ||||
|             name: "webkit", | ||||
|             use: { | ||||
|                 ...devices['Desktop Safari'], | ||||
|                 ...devices["Desktop Safari"], | ||||
|             }, | ||||
|         }, | ||||
| 
 | ||||
|  | @ -105,7 +103,7 @@ export default defineConfig({ | |||
|          * Use the preview server on CI for more realistic testing. | ||||
|          * Playwright will re-use the local server if there is already a dev-server running. | ||||
|          */ | ||||
|         command: process.env.CI ? 'npm run preview' : 'npm run dev', | ||||
|         command: process.env.CI ? "npm run preview" : "npm run dev", | ||||
|         port: process.env.CI ? 4173 : 5173, | ||||
|         reuseExistingServer: !process.env.CI, | ||||
|     }, | ||||
|  |  | |||
|  | @ -2,10 +2,10 @@ | |||
|  * @type {import("prettier").Options} | ||||
|  */ | ||||
| 
 | ||||
| const rootConfig = import ('../prettier.config.js'); | ||||
| const rootConfig = import("../prettier.config.js"); | ||||
| 
 | ||||
| export default { | ||||
|     ...rootConfig, | ||||
|     vueIndentScriptAndStyle: true, | ||||
|     singleAttributePerLine: true | ||||
|     singleAttributePerLine: true, | ||||
| }; | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								frontend/public/assets/home/inclusive.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/assets/home/inclusive.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 183 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/assets/home/innovative.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/assets/home/innovative.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 93 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/assets/home/research_based.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/assets/home/research_based.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 66 KiB | 
							
								
								
									
										
											BIN
										
									
								
								frontend/public/assets/home/socially_relevant.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontend/public/assets/home/socially_relevant.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 85 KiB | 
|  | @ -4,9 +4,7 @@ | |||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <router-view/> | ||||
|     <router-view /> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,9 @@ | |||
| <script setup lang="ts"> | ||||
| // This component contains a list with all themes and will be shown on a student's and teacher's homepage. | ||||
|     // This component contains a list with all themes and will be shown on a student's and teacher's homepage. | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <b>404 - Page Not Found</b> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import {createRouter, createWebHistory} from "vue-router"; | ||||
| import { createRouter, createWebHistory } from "vue-router"; | ||||
| import MenuBar from "@/components/MenuBar.vue"; | ||||
| import StudentHomepage from "@/views/StudentHomepage.vue"; | ||||
| import StudentAssignments from "@/views/assignments/StudentAssignments.vue"; | ||||
|  | @ -23,12 +23,12 @@ const router = createRouter({ | |||
|         { | ||||
|             path: "/", | ||||
|             name: "home", | ||||
|             component: () => {return import("../views/HomePage.vue")}, | ||||
|             component: () => import("../views/HomePage.vue"), | ||||
|         }, | ||||
|         { | ||||
|             path: "/login", | ||||
|             name: "LoginPage", | ||||
|             component: () => {return import("../views/LoginPage.vue")} | ||||
|             component: () => import("../views/LoginPage.vue"), | ||||
|         }, | ||||
|         { | ||||
|             path: "/callback", | ||||
|  | @ -41,24 +41,24 @@ const router = createRouter({ | |||
|                 { | ||||
|                     path: "home", | ||||
|                     name: "StudentHomePage", | ||||
|                     component: StudentHomepage | ||||
|                     component: StudentHomepage, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "assignment", | ||||
|                     name: "StudentAssignments", | ||||
|                     component: StudentAssignments | ||||
|                     component: StudentAssignments, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "class", | ||||
|                     name: "StudentClasses", | ||||
|                     component: StudentClasses | ||||
|                     component: StudentClasses, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "discussion", | ||||
|                     name: "StudentDiscussions", | ||||
|                     component: StudentDiscussions | ||||
|                     component: StudentDiscussions, | ||||
|                 }, | ||||
|             ] | ||||
|             ], | ||||
|         }, | ||||
| 
 | ||||
|         { | ||||
|  | @ -68,56 +68,54 @@ const router = createRouter({ | |||
|                 { | ||||
|                     path: "home", | ||||
|                     name: "TeacherHomepage", | ||||
|                     component: TeacherHomepage | ||||
|                     component: TeacherHomepage, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "assignment", | ||||
|                     name: "TeacherAssignments", | ||||
|                     component: TeacherAssignments | ||||
|                     component: TeacherAssignments, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "class", | ||||
|                     name: "TeacherClasses", | ||||
|                     component: TeacherClasses | ||||
|                     component: TeacherClasses, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: "discussion", | ||||
|                     name: "TeacherDiscussions", | ||||
|                     component: TeacherDiscussions | ||||
|                     component: TeacherDiscussions, | ||||
|                 }, | ||||
|             ] | ||||
|             ], | ||||
|         }, | ||||
|         { | ||||
|             path: "/assignment/create", | ||||
|             name: "CreateAssigment", | ||||
|             component: CreateAssignment | ||||
| 
 | ||||
|             component: CreateAssignment, | ||||
|         }, | ||||
|         { | ||||
|             path: "/assignment/:id", | ||||
|             name: "SingleAssigment", | ||||
|             component: SingleAssignment | ||||
| 
 | ||||
|             component: SingleAssignment, | ||||
|         }, | ||||
|         { | ||||
|             path: "/class/create", | ||||
|             name: "CreateClass", | ||||
|             component: CreateClass | ||||
|             component: CreateClass, | ||||
|         }, | ||||
|         { | ||||
|             path: "/class/:id", | ||||
|             name: "SingleClass", | ||||
|             component: SingleClass | ||||
|             component: SingleClass, | ||||
|         }, | ||||
|         { | ||||
|             path: "/discussion/create", | ||||
|             name: "CreateDiscussion", | ||||
|             component: CreateDiscussion | ||||
|             component: CreateDiscussion, | ||||
|         }, | ||||
|         { | ||||
|             path: "/discussion/:id", | ||||
|             name: "SingleDiscussion", | ||||
|             component: SingleDiscussion | ||||
|             component: SingleDiscussion, | ||||
|         }, | ||||
|         { | ||||
|             path: "/:catchAll(.*)", | ||||
|  |  | |||
							
								
								
									
										18
									
								
								frontend/src/utils/base64ToImage.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontend/src/utils/base64ToImage.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| /** | ||||
|  * Converts a Base64 string to a valid image source URL. | ||||
|  * | ||||
|  * @param base64String - The "image" field from the learning path JSON response. | ||||
|  * @returns A properly formatted data URL for use in an <img> tag. | ||||
|  * | ||||
|  * @example | ||||
|  * // Fetch the learning path data and extract the image
 | ||||
|  * const response = await fetch( learning path route ); | ||||
|  * const data = await response.json(); | ||||
|  * const base64String = data.image; | ||||
|  * | ||||
|  * // Use in an <img> element
 | ||||
|  * <img :src="convertBase64ToImageSrc(base64String)" alt="Learning Path Image" /> | ||||
|  */ | ||||
| export function convertBase64ToImageSrc(base64String: string): string { | ||||
|     return base64String.startsWith("data:image") ? base64String : `data:image/png;base64,${base64String}`; | ||||
| } | ||||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,11 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
| 
 | ||||
| </script> | ||||
| <script setup lang="ts"></script> | ||||
| 
 | ||||
| <template> | ||||
|     <main></main> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
							
								
								
									
										1
									
								
								frontend/tests/base64/base64Sample.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								frontend/tests/base64/base64Sample.txt
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										23
									
								
								frontend/tests/base64/base64ToImage.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								frontend/tests/base64/base64ToImage.test.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,23 @@ | |||
| import { describe, it, expect, beforeAll } from "vitest"; | ||||
| import { convertBase64ToImageSrc } from "../../src/utils/base64ToImage.js"; | ||||
| import fs from "fs"; | ||||
| import path from "path"; | ||||
| 
 | ||||
| let sampleBase64: string; | ||||
| 
 | ||||
| beforeAll(() => { | ||||
|     // Load base64 sample from text file
 | ||||
|     const filePath = path.resolve(__dirname, "base64Sample.txt"); | ||||
|     sampleBase64 = fs.readFileSync(filePath, "utf8").trim(); | ||||
| }); | ||||
| 
 | ||||
| describe("convertBase64ToImageSrc", () => { | ||||
|     it("should return the same string if it is already a valid data URL", () => { | ||||
|         const base64Image = `data:image/png;base64,${sampleBase64}`; | ||||
|         expect(convertBase64ToImageSrc(base64Image)).toBe(base64Image); | ||||
|     }); | ||||
| 
 | ||||
|     it("should correctly format a raw Base64 string as a PNG image URL", () => { | ||||
|         expect(convertBase64ToImageSrc(sampleBase64)).toBe(`data:image/png;base64,${sampleBase64}`); | ||||
|     }); | ||||
| }); | ||||
|  | @ -1,14 +1,15 @@ | |||
| import { fileURLToPath, URL } from 'node:url'; | ||||
| import { fileURLToPath, URL } from "node:url"; | ||||
| 
 | ||||
| import { defineConfig } from 'vite'; | ||||
| import vue from '@vitejs/plugin-vue'; | ||||
| import { defineConfig } from "vite"; | ||||
| import vue from "@vitejs/plugin-vue"; | ||||
| import vueDevTools from "vite-plugin-vue-devtools"; | ||||
| 
 | ||||
| // https://vite.dev/config/
 | ||||
| export default defineConfig({ | ||||
|     plugins: [vue()], | ||||
|     resolve: { | ||||
|         alias: { | ||||
|             '@': fileURLToPath(new URL('./src', import.meta.url)), | ||||
|             "@": fileURLToPath(new URL("./src", import.meta.url)), | ||||
|         }, | ||||
|     }, | ||||
| }); | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| import { fileURLToPath } from 'node:url'; | ||||
| import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'; | ||||
| import viteConfig from './vite.config'; | ||||
| import { fileURLToPath } from "node:url"; | ||||
| import { mergeConfig, defineConfig, configDefaults } from "vitest/config"; | ||||
| import viteConfig from "./vite.config"; | ||||
| 
 | ||||
| export default mergeConfig( | ||||
|     viteConfig, | ||||
|     defineConfig({ | ||||
|         test: { | ||||
|             environment: 'jsdom', | ||||
|             exclude: [...configDefaults.exclude, 'e2e/**'], | ||||
|             root: fileURLToPath(new URL('./', import.meta.url)), | ||||
|             environment: "jsdom", | ||||
|             exclude: [...configDefaults.exclude, "e2e/**"], | ||||
|             root: fileURLToPath(new URL("./", import.meta.url)), | ||||
|         }, | ||||
|     }), | ||||
| ); | ||||
|  |  | |||
		Reference in a new issue
	
	 Gerald Schmittinger
						Gerald Schmittinger