diff --git a/client/index.html b/client/index.html index 44eb85d..2ca8227 100644 --- a/client/index.html +++ b/client/index.html @@ -11,6 +11,7 @@
+ diff --git a/client/package.json b/client/package.json index 4f9b854..2469687 100644 --- a/client/package.json +++ b/client/package.json @@ -12,7 +12,8 @@ "core-js": "^3.37.1", "roboto-fontface": "*", "vue": "^3.4.31", - "vuetify": "^3.6.11" + "vuetify": "^3.6.11", + "vue3-notifier":"1.0.3" }, "devDependencies": { "@babel/types": "^7.24.7", diff --git a/client/public/config.js b/client/public/config.js new file mode 100644 index 0000000..e117e98 --- /dev/null +++ b/client/public/config.js @@ -0,0 +1,3 @@ +window.env = { + SERVER_DOMAIN_NAME_API: 'http://127.0.0.1:8000/api', +} diff --git a/client/src/App.vue b/client/src/App.vue index 6ceb9da..d4df927 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,11 +1,7 @@ diff --git a/client/src/api/axios.ts b/client/src/api/axios.ts index dea7a34..655090b 100644 --- a/client/src/api/axios.ts +++ b/client/src/api/axios.ts @@ -1,17 +1,15 @@ -import axios, { AxiosInstance } from 'axios'; - -const AuthClient: AxiosInstance = axios.create({ - baseURL: import.meta.env.VITE_APP_ENDPOINT, - timeout: 1000, - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer ' + localStorage.getItem("token"), - }, -}); - -const BaseClient: AxiosInstance = axios.create({ - baseURL: import.meta.env.VITE_APP_ENDPOINT, - timeout: 1000, -}); - -export { AuthClient, BaseClient }; +import axios, { AxiosInstance } from 'axios' + +export const AuthClient: AxiosInstance = axios.create({ + baseURL: window.env.SERVER_DOMAIN_NAME_API, + timeout: 1000, + headers: { + 'Content-Type': 'application/json', + Authorization: localStorage.getItem('token'), + }, +}) + +export const BaseClient: AxiosInstance = axios.create({ + baseURL: window.env.SERVER_DOMAIN_NAME_API, + timeout: 1000, +}) diff --git a/client/src/api/projectService.ts b/client/src/api/projectService.ts new file mode 100644 index 0000000..f0f2880 --- /dev/null +++ b/client/src/api/projectService.ts @@ -0,0 +1,18 @@ +import { AuthClient } from './axios' +import { Project } from '@/types/types' + +export async function postProject (project :Partial) { + return AuthClient.post('/dashboard/projects/', project) +} + +export async function getProjects (page :number) { + return AuthClient.get('/dashboard/projects/', { + params: { + page, + }, + }) +} + +export async function searchProject (searchInput: string) { + await AuthClient.get(`/project/search/${searchInput}`) +} diff --git a/client/src/components.d.ts b/client/src/components.d.ts index 1898766..fc89776 100644 --- a/client/src/components.d.ts +++ b/client/src/components.d.ts @@ -7,10 +7,8 @@ export {} /* prettier-ignore */ declare module 'vue' { export interface GlobalComponents { - AppFooter: typeof import('./components/AppFooter.vue')['default'] - HelloWorld: typeof import('./components/HelloWorld.vue')['default'] + ProjectForm: typeof import('./components/projects/ProjectForm.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - Test: typeof import('./components/test.vue')['default'] } } diff --git a/client/src/components/projects/ProjectForm.vue b/client/src/components/projects/ProjectForm.vue new file mode 100644 index 0000000..bf54644 --- /dev/null +++ b/client/src/components/projects/ProjectForm.vue @@ -0,0 +1,133 @@ + + + diff --git a/client/src/components/test.vue b/client/src/components/test.vue deleted file mode 100644 index e69de29..0000000 diff --git a/client/src/index.ts b/client/src/index.ts new file mode 100644 index 0000000..5ced3b6 --- /dev/null +++ b/client/src/index.ts @@ -0,0 +1,9 @@ +export {} + +declare global { + interface Window { + env: { + SERVER_DOMAIN_NAME_API: string; + }; + } +} diff --git a/client/src/layouts/README.md b/client/src/layouts/README.md deleted file mode 100644 index 4016af3..0000000 --- a/client/src/layouts/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Layouts - -Layouts are reusable components that wrap around pages. They are used to provide a consistent look and feel across multiple pages. - -Full documentation for this feature can be found in the Official [vite-plugin-vue-layouts](https://github.com/JohnCampionJr/vite-plugin-vue-layouts) repository. diff --git a/client/src/layouts/default.vue b/client/src/layouts/default.vue deleted file mode 100644 index da5c129..0000000 --- a/client/src/layouts/default.vue +++ /dev/null @@ -1,13 +0,0 @@ - - - diff --git a/client/src/main.ts b/client/src/main.ts index c8fc172..0973f50 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -3,6 +3,8 @@ * * Bootstraps Vuetify and other plugins then mounts the App` */ +// Styles +import 'vue3-notifier/style.css' // Plugins import { registerPlugins } from '@/plugins' diff --git a/client/src/pages/DashboardView.vue b/client/src/pages/DashboardView.vue deleted file mode 100644 index c9b4d21..0000000 --- a/client/src/pages/DashboardView.vue +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/client/src/pages/projects/ProjectDetailsView.vue b/client/src/pages/projects/ProjectDetailsView.vue new file mode 100644 index 0000000..a42f043 --- /dev/null +++ b/client/src/pages/projects/ProjectDetailsView.vue @@ -0,0 +1,17 @@ + + + diff --git a/client/src/pages/projects/ProjectsView.vue b/client/src/pages/projects/ProjectsView.vue new file mode 100644 index 0000000..351e7f6 --- /dev/null +++ b/client/src/pages/projects/ProjectsView.vue @@ -0,0 +1,186 @@ + + + + + diff --git a/client/src/plugins/index.ts b/client/src/plugins/index.ts index c75aa61..00ae7ca 100644 --- a/client/src/plugins/index.ts +++ b/client/src/plugins/index.ts @@ -5,16 +5,21 @@ */ // Plugins -import vuetify from './vuetify' +import { $vuetify } from './vuetify' import pinia from '../stores' import router from '../router' +import { useNotifierPlugin } from 'vue3-notifier' // Types import type { App } from 'vue' export function registerPlugins (app: App) { app - .use(vuetify) - .use(router) .use(pinia) + .use($vuetify) + .use(useNotifierPlugin({ + id: 'top right', + position: 'top right', + })) + .use(router) } diff --git a/client/src/plugins/vuetify.ts b/client/src/plugins/vuetify.ts index 7652788..787f585 100644 --- a/client/src/plugins/vuetify.ts +++ b/client/src/plugins/vuetify.ts @@ -12,8 +12,8 @@ import 'vuetify/styles' import { createVuetify } from 'vuetify' // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides -export default createVuetify({ +export const $vuetify = createVuetify({ theme: { - defaultTheme: 'dark', + defaultTheme: 'light', }, }) diff --git a/client/src/router/index.ts b/client/src/router/index.ts index 2f9d03c..5c6e1ce 100644 --- a/client/src/router/index.ts +++ b/client/src/router/index.ts @@ -10,7 +10,7 @@ import { createRouter, createWebHistory } from 'vue-router/auto' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ - { path: '/', component: () => import('@/pages/DashboardView.vue') } + { path: '/projects/:projectId', name: 'projectDetails', component: () => import('@/pages/projects/ProjectDetailsView.vue'), props: true }, ], }) diff --git a/client/src/typed-router.d.ts b/client/src/typed-router.d.ts index 3b75a53..85eff57 100644 --- a/client/src/typed-router.d.ts +++ b/client/src/typed-router.d.ts @@ -18,6 +18,7 @@ declare module 'vue-router/auto-routes' { * Route name map generated by unplugin-vue-router */ export interface RouteNamedMap { - '/DashboardView': RouteRecordInfo<'/DashboardView', '/DashboardView', Record, Record>, + '/projects/ProjectDetailsView': RouteRecordInfo<'/projects/ProjectDetailsView', '/projects/ProjectDetailsView', Record, Record>, + '/projects/ProjectsView': RouteRecordInfo<'/projects/ProjectsView', '/projects/ProjectsView', Record, Record>, } } diff --git a/client/src/types/types.ts b/client/src/types/types.ts index e69de29..a8ce4a8 100644 --- a/client/src/types/types.ts +++ b/client/src/types/types.ts @@ -0,0 +1,73 @@ +enum Status { + NOT_STARTED='not_started', + IN_PROGRESS='in_progress', + COMPLETED='completed', +} + +export type Activity = { + action: string, + date: string, +} + +export type TestPlan = { + id: number, + modified: string, + created: string, + title: string, + type: string, +} + +export type Requirement = { + id: number, + updated: string, + created: string, + title: string, + requirements: string[], +} + +export type TestSuite = { + id: number, + modified: string, + created: string, + title: string, + number_of_test_cases: number, + test_plan: number, +} + +export type TestRun = { + +} + +export type TestCase = { + id: number, + modified: string, + created: string, + title: string, + testcase_title: string, + requirement: string + last_saved: { + id: number, + full_name: string, + } + test_suite: string, + description: string, + test_steps: string, + expected_result: string, +} +export type Project = { + id: number, + user: string, + teams: string[], + modified: string, + created: string, + activity: Activity[], + total_test_plan: TestPlan[], + total_requirements_docs: Requirement[], + total_suites: TestSuite[], + total_test_runs: TestRun[], + incomplete_test_runs_assigned_to_you: TestRun[], + people_with_the_most_incomplete_test_runs: TestRun[], + title: string, + repo_link: string, + short_description: string, +} diff --git a/client/src/utilities/validators.ts b/client/src/utilities/validators.ts index e69de29..30bb4ba 100644 --- a/client/src/utilities/validators.ts +++ b/client/src/utilities/validators.ts @@ -0,0 +1,36 @@ +export const titleRules = [ + (value: string) => { + if (value) return true + return 'You must enter a title.' + }, + (value: string) => { + if (value?.length > 3) return true + return 'Title must be at least 4 character.' + }, + (value: string) => { + if (value?.length < 99) return true + return 'Title must be at most 100 characters.' + }, +] + +export const descriptionRules = [ + (value: string) => { + if (value) return true + return 'You must enter a description.' + }, + (value: string) => { + if (value?.length > 3) return true + return 'Description must be at least 4 character.' + }, + (value: string) => { + if (value?.length < 499) return true + return 'Description must be at most 500 characters.' + }, +] + +export const githubRepoRules = [ + (value: string) => { + if (value?.slice(0, 19) === 'hgithub.com/') return true + return 'Git repository must contain github keyword.' + }, +] diff --git a/package.json b/package.json new file mode 100644 index 0000000..6f122a8 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "vue3-notifier": "^1.0.3" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..d4716f6 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,231 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + vue3-notifier: + specifier: ^1.0.3 + version: 1.0.3 + +packages: + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@vue/compiler-core@3.4.37': + resolution: {integrity: sha512-ZDDT/KiLKuCRXyzWecNzC5vTcubGz4LECAtfGPENpo0nrmqJHwuWtRLxk/Sb9RAKtR9iFflFycbkjkY+W/PZUQ==} + + '@vue/compiler-dom@3.4.37': + resolution: {integrity: sha512-rIiSmL3YrntvgYV84rekAtU/xfogMUJIclUMeIKEtVBFngOL3IeZHhsH3UaFEgB5iFGpj6IW+8YuM/2Up+vVag==} + + '@vue/compiler-sfc@3.4.37': + resolution: {integrity: sha512-vCfetdas40Wk9aK/WWf8XcVESffsbNkBQwS5t13Y/PcfqKfIwJX2gF+82th6dOpnpbptNMlMjAny80li7TaCIg==} + + '@vue/compiler-ssr@3.4.37': + resolution: {integrity: sha512-TyAgYBWrHlFrt4qpdACh8e9Ms6C/AZQ6A6xLJaWrCL8GCX5DxMzxyeFAEMfU/VFr4tylHm+a2NpfJpcd7+20XA==} + + '@vue/reactivity@3.4.37': + resolution: {integrity: sha512-UmdKXGx0BZ5kkxPqQr3PK3tElz6adTey4307NzZ3whZu19i5VavYal7u2FfOmAzlcDVgE8+X0HZ2LxLb/jgbYw==} + + '@vue/runtime-core@3.4.37': + resolution: {integrity: sha512-MNjrVoLV/sirHZoD7QAilU1Ifs7m/KJv4/84QVbE6nyAZGQNVOa1HGxaOzp9YqCG+GpLt1hNDC4RbH+KtanV7w==} + + '@vue/runtime-dom@3.4.37': + resolution: {integrity: sha512-Mg2EwgGZqtwKrqdL/FKMF2NEaOHuH+Ks9TQn3DHKyX//hQTYOun+7Tqp1eo0P4Ds+SjltZshOSRq6VsU0baaNg==} + + '@vue/server-renderer@3.4.37': + resolution: {integrity: sha512-jZ5FAHDR2KBq2FsRUJW6GKDOAG9lUTX8aBEGq4Vf6B/35I9fPce66BornuwmqmKgfiSlecwuOb6oeoamYMohkg==} + peerDependencies: + vue: 3.4.37 + + '@vue/shared@3.4.37': + resolution: {integrity: sha512-nIh8P2fc3DflG8+5Uw8PT/1i17ccFn0xxN/5oE9RfV5SVnd7G0XEFRwakrnNFE/jlS95fpGXDVG5zDETS26nmg==} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + entities@5.0.0: + resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==} + engines: {node: '>=0.12'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + gsap@3.12.5: + resolution: {integrity: sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + postcss@8.4.41: + resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + engines: {node: ^10 || ^12 || >=14} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + vue3-notifier@1.0.3: + resolution: {integrity: sha512-W8cZtq3N7NJLNaP+LDOpABusSyT1zAHEvHFPuGn+Jo/rxHHrbFGD0jar8vDXOmhti7ZqenaTiRz1nKHA/9Cu7g==} + + vue@3.4.37: + resolution: {integrity: sha512-3vXvNfkKTBsSJ7JP+LyR7GBuwQuckbWvuwAid3xbqK9ppsKt/DUvfqgZ48fgOLEfpy1IacL5f8QhUVl77RaI7A==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + +snapshots: + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/parser@7.25.3': + dependencies: + '@babel/types': 7.25.2 + + '@babel/types@7.25.2': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@vue/compiler-core@3.4.37': + dependencies: + '@babel/parser': 7.25.3 + '@vue/shared': 3.4.37 + entities: 5.0.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.37': + dependencies: + '@vue/compiler-core': 3.4.37 + '@vue/shared': 3.4.37 + + '@vue/compiler-sfc@3.4.37': + dependencies: + '@babel/parser': 7.25.3 + '@vue/compiler-core': 3.4.37 + '@vue/compiler-dom': 3.4.37 + '@vue/compiler-ssr': 3.4.37 + '@vue/shared': 3.4.37 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.41 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.37': + dependencies: + '@vue/compiler-dom': 3.4.37 + '@vue/shared': 3.4.37 + + '@vue/reactivity@3.4.37': + dependencies: + '@vue/shared': 3.4.37 + + '@vue/runtime-core@3.4.37': + dependencies: + '@vue/reactivity': 3.4.37 + '@vue/shared': 3.4.37 + + '@vue/runtime-dom@3.4.37': + dependencies: + '@vue/reactivity': 3.4.37 + '@vue/runtime-core': 3.4.37 + '@vue/shared': 3.4.37 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.37(vue@3.4.37)': + dependencies: + '@vue/compiler-ssr': 3.4.37 + '@vue/shared': 3.4.37 + vue: 3.4.37 + + '@vue/shared@3.4.37': {} + + chalk@5.3.0: {} + + csstype@3.1.3: {} + + entities@5.0.0: {} + + estree-walker@2.0.2: {} + + gsap@3.12.5: {} + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + nanoid@3.3.7: {} + + picocolors@1.0.1: {} + + postcss@8.4.41: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + source-map-js@1.2.0: {} + + to-fast-properties@2.0.0: {} + + vue3-notifier@1.0.3: + dependencies: + chalk: 5.3.0 + gsap: 3.12.5 + vue: 3.4.37 + transitivePeerDependencies: + - typescript + + vue@3.4.37: + dependencies: + '@vue/compiler-dom': 3.4.37 + '@vue/compiler-sfc': 3.4.37 + '@vue/runtime-dom': 3.4.37 + '@vue/server-renderer': 3.4.37(vue@3.4.37) + '@vue/shared': 3.4.37 diff --git a/server/test_tracker/views/member.py b/server/test_tracker/views/member.py index 8567a26..ba2f99f 100644 --- a/server/test_tracker/views/member.py +++ b/server/test_tracker/views/member.py @@ -186,7 +186,7 @@ class ProjectMembersAPIView(GenericAPIView): """This class to return all project members""" serializer_class = ProjectTeamSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str) -> Response: """Use this endpoint to get all project members""" diff --git a/server/test_tracker/views/project.py b/server/test_tracker/views/project.py index ea12aab..44e623d 100644 --- a/server/test_tracker/views/project.py +++ b/server/test_tracker/views/project.py @@ -31,7 +31,7 @@ class ProjectsDetailAPIView(GenericAPIView): """ serializer_class = ProjectsSerializer - permission_classes = (HasProjectAccess,) + # def get(self, request: Request, project_id: str) -> Response: """Return a single project based on the given project id""" @@ -130,7 +130,7 @@ class AddMemberToProjectAPIView(GenericAPIView): Add Member to project """ - permission_classes = (HasProjectAccess,) + # def put(self, request: Request, project_id: Project, member_id: Member) -> Response: """ @@ -260,7 +260,7 @@ class SearchProjectAPIView(GenericAPIView): """ serializer_class = ProjectsSerializer - permission_classes = (UserIsAuthenticated,) + # permission_classes = (UserIsAuthenticated,) def get(self, request: Request, project_name: str): """ @@ -288,7 +288,7 @@ class AccountMembersNotInProjectAPIView(GenericAPIView): Class to get all account members where members not in project """ - permission_classes = (HasProjectAccess,) + serializer_class = ProjectTeamSerializer def get(self, request: Request, project_id: str): @@ -318,7 +318,7 @@ def get(self, request: Request, project_id: str): class TestSuitesSectionAPIView(GenericAPIView): serializer_class = TestSuiteSectionSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str): """Post new section, required fields is [Title,]""" @@ -333,7 +333,7 @@ def post(self, request: Request, project_id: str): class GetTestSuitesSectionsAPIView(GenericAPIView): serializer_class = GetTestSuiteSectionSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, test_suite: str) -> Response: """Get all project test suite sections""" @@ -351,7 +351,7 @@ def get(self, request: Request, project_id: str, test_suite: str) -> Response: class DeleteTestSuiteSectionAPIView(GenericAPIView): """Delete a test suite section by its id.""" - permission_classes = (HasProjectAccess,) + def delete(self, request: Request, project_id: str, section_id: str) -> Response: """Delete a section with given id""" @@ -370,7 +370,7 @@ def delete(self, request: Request, project_id: str, section_id: str) -> Response class AddTestCaseToTestSuiteSectionAPIView(GenericAPIView): """Add a test case to test suite section""" - permission_classes = (HasProjectAccess,) + # serializer_class = AddTestCaseToTestSuiteSectionSerializers def put(self, request: Request, project_id: str): diff --git a/server/test_tracker/views/requirement.py b/server/test_tracker/views/requirement.py index dc3172e..6828092 100644 --- a/server/test_tracker/views/requirement.py +++ b/server/test_tracker/views/requirement.py @@ -32,7 +32,7 @@ class PostNewRequirementDocsAPIView(GenericAPIView): """class project requirement view""" serializer_class = RequirementDocsSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str) -> Response: """post a new requirement""" @@ -70,7 +70,7 @@ class GetAllRequirementDocsAPIView(GenericAPIView): """class project requirement view""" serializer_class = RequirementDocsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str) -> Response: """ @@ -96,7 +96,7 @@ class project requirement view search on project requirements """ serializer_class = RequirementDocsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, key_word: str) -> Response: """get all requirements for a project""" @@ -121,7 +121,7 @@ class project requirement view """ serializer_class = RequirementDocsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, requirement_id: str) -> Response: """Use this endpoint to get requirement detail and sub requirements""" @@ -190,7 +190,7 @@ class RequirementAPIView(GenericAPIView): """This class is a sub requirement for project requirements""" serializer_class = RequirementsSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str, requirements_id: str) -> Response: """ @@ -269,7 +269,7 @@ class project requirement view """ serializer_class = RequirementsSerializer - permission_classes = (HasProjectAccess,) + def get( self, @@ -371,7 +371,7 @@ class SearchRequirementsInRequirementDocssAPIView(APIView): Use this endpoint to filter any requirement based on title or description """ - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, key_word: str): """ diff --git a/server/test_tracker/views/test_cases.py b/server/test_tracker/views/test_cases.py index 6b1703a..c0fd220 100644 --- a/server/test_tracker/views/test_cases.py +++ b/server/test_tracker/views/test_cases.py @@ -180,7 +180,7 @@ class SearchTestCaseAPIView(GenericAPIView): """ serializer_class = TestCaseSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, key_word: str): """ @@ -201,7 +201,7 @@ class GetAllProjectRequirementsAPIView(GenericAPIView): """Get all of test cases""" serializer_class = RequirementsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str) -> Response: """Method get to get all of test cases based on the test suite""" @@ -221,7 +221,7 @@ class UpdateTestCaseAfterRunAPIView(GenericAPIView): """This class to update the test case by pass bool field""" serializer_class = UpdateTestCaseAfterRunSerializer - permission_classes = (HasProjectAccess,) + def put(self, request: Request, project_id: str, test_case_id: str) -> Response: """Method put to update the test case by pass bool field""" diff --git a/server/test_tracker/views/test_plan.py b/server/test_tracker/views/test_plan.py index 091eaa4..aedf42d 100644 --- a/server/test_tracker/views/test_plan.py +++ b/server/test_tracker/views/test_plan.py @@ -28,7 +28,7 @@ class TestPlansAPIView(GenericAPIView): """Create a test plan.""" serializer_class = TestPlanSerializer - permission_classes = (HasProjectAccess,) + """""" def post(self, request: Request, project_id: str) -> Response: """ @@ -82,7 +82,7 @@ class TestPlansDetailAPIView(GenericAPIView): """This class for [GET, UPDATE, DELETE] test plans methods""" serializer_class = TestPlanDetailSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, test_plan_id: str) -> Response: """Get a test plan from the specified project""" @@ -113,7 +113,7 @@ def delete(self, request: Request, project_id: str, test_plan_id: str) -> Respon class UpdateTestPlanAPIView(GenericAPIView): serializer_class = UpdateTestPlanSerializer - permission_classes = (HasProjectAccess,) + def put(self, request: Request, project_id: str, test_plan_id: str) -> Response: """Update test plan title""" @@ -147,7 +147,7 @@ class PostNewTestPlanContentAreaAPIView(GenericAPIView): """ serializer_class = TestPlanTempsSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str, test_plan_id: str) -> Response: """Add custom content area to test plan""" @@ -185,7 +185,7 @@ class TestPlanContentAreaAPIView(GenericAPIView): Delete and get test plan content area based on its title """ - permission_classes = (HasProjectAccess,) + serializer_class = TestPlanTempsSerializer def put( @@ -272,7 +272,7 @@ class SearchTestPlanAPIView(GenericAPIView): """ serializer_class = TestPlanDetailSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, key_word: str): """ diff --git a/server/test_tracker/views/test_run.py b/server/test_tracker/views/test_run.py index af72988..b474cc6 100644 --- a/server/test_tracker/views/test_run.py +++ b/server/test_tracker/views/test_run.py @@ -28,7 +28,7 @@ class TestRunAPIView(GenericAPIView): """Class TestRunAPIView to handle test runs endpoints""" serializer_class = TestRunsSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str) -> Response: serializer = self.serializer_class(data=request.data) @@ -89,7 +89,7 @@ class TestRunDetailAPIView(GenericAPIView): """Class TestRunAPIView to handle test runs endpoints""" serializer_class = TestRunsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, test_run_id: str) -> Response: """ @@ -142,7 +142,7 @@ class SearchOnTestRunAPIView(GenericAPIView): """ serializer_class = TestRunsSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str) -> Response: """ @@ -176,7 +176,7 @@ def get(self, request: Request, project_id: str) -> Response: class LastWeekTestRunReportSheetAPIView(GenericAPIView): - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str) -> Response: """ @@ -227,7 +227,7 @@ def get(self, request: Request, project_id: str) -> Response: class RunAllTestCasesAPIView(GenericAPIView): - permission_classes = (HasProjectAccess,) + serializer_class = TestCaseSerializer def get(self, request: Request, project_id: str, test_run_id: str) -> Response: @@ -286,7 +286,7 @@ def put(self, request: Request, project_id: str, test_run_id: str) -> Response: class SetAssignedUserTestRunAPIView(GenericAPIView): - permission_classes = (HasProjectAccess,) + serializer_class = TestRunsSerializer def put(self, request: Request, project_id: str, test_run_id: str) -> Response: @@ -334,7 +334,7 @@ def get(self, request: Request) -> Response: class CompleteTestRunAPIView(GenericAPIView): """Complete test run after run all test cases.""" - permission_classes = (HasProjectAccess,) + def put(self, request: Request, project_id: str, test_run_id: str) -> Response: """We will use this endpoint to complete the test run after running all test cases""" diff --git a/server/test_tracker/views/test_suites.py b/server/test_tracker/views/test_suites.py index 5e0268c..82d3a07 100644 --- a/server/test_tracker/views/test_suites.py +++ b/server/test_tracker/views/test_suites.py @@ -22,7 +22,7 @@ class TestSuitesAPIView(GenericAPIView): """Create a new test suite""" serializer_class = TestSuitesSerializer - permission_classes = (HasProjectAccess,) + def post(self, request: Request, project_id: str) -> Response: """ @@ -74,7 +74,7 @@ class TestSuitesDetailAPIView(GenericAPIView): """Create a new test suite""" serializer_class = TestSuitesDetailSerializer - permission_classes = (HasProjectAccess,) + def put(self, request: Request, project_id: str, test_suite_id: str) -> Response: """ @@ -138,7 +138,7 @@ class SearchTestSuiteAPIView(GenericAPIView): """ serializer_class = TestSuitesSerializer - permission_classes = (HasProjectAccess,) + def get(self, request: Request, project_id: str, key_word: str): """