forked from Ivasoft/geovisio-website
Merge branch 'feat/instance-customization' into 'main'
Feat/instance customization See merge request geovisio/website!48
This commit is contained in:
@@ -20,7 +20,8 @@ module.exports = {
|
||||
],
|
||||
rules: {
|
||||
'vue/require-default-prop': 'off',
|
||||
'prettier/prettier': 'error'
|
||||
'prettier/prettier': 'error',
|
||||
'@typescript-eslint/no-namespace': 'off'
|
||||
// override/add rules settings here, such as:
|
||||
// 'vue/no-unused-vars': 'error'
|
||||
}
|
||||
|
||||
20
cypress.config.ts
Normal file
20
cypress.config.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { defineConfig } from 'cypress'
|
||||
|
||||
export default defineConfig({
|
||||
component: {
|
||||
devServer: {
|
||||
framework: 'vue',
|
||||
bundler: 'vite'
|
||||
}
|
||||
},
|
||||
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},
|
||||
baseUrl: 'http://localhost:5173',
|
||||
supportFile: 'src/tests/cypress/support/e2e.{js,jsx,ts,tsx}',
|
||||
specPattern: 'src/tests/cypress/**/*.cy.{js,jsx,ts,tsx}',
|
||||
fixturesFolder: 'src/tests/cypress/fixtures'
|
||||
}
|
||||
})
|
||||
@@ -44,6 +44,7 @@
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.2.4",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"cypress": "^12.12.0",
|
||||
"eslint": "^8.29.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-vue": "^9.8.0",
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import Header from '@/components/Header.vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { useMeta } from 'vue-meta'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import authConfig from './composables/auth'
|
||||
const { authConf } = authConfig()
|
||||
const { t } = useI18n()
|
||||
|
||||
useMeta({
|
||||
title: t('general.title'),
|
||||
og: {
|
||||
@@ -20,6 +24,11 @@ useMeta({
|
||||
<metainfo>
|
||||
<template v-slot:title="{ content }">{{ content }}</template>
|
||||
</metainfo>
|
||||
<Header
|
||||
v-if="authConf.user_profile"
|
||||
:auth-enabled="authConf.enabled"
|
||||
:user-profile-url="authConf.user_profile.url"
|
||||
/>
|
||||
<RouterView />
|
||||
</template>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
path="/partager-des-photos"
|
||||
/>
|
||||
</div>
|
||||
<div class="item-with-sub">
|
||||
<div v-if="authEnabled" class="item-with-sub">
|
||||
<Link
|
||||
type="external"
|
||||
icon="bi bi-person-circle"
|
||||
@@ -49,7 +49,7 @@
|
||||
/>
|
||||
<i v-if="isLogged" class="chevron bi bi-chevron-up"></i>
|
||||
<div v-if="isLogged" class="sub-nav-block">
|
||||
<div class="logged-link">
|
||||
<div v-if="userProfileUrl" class="logged-link">
|
||||
<Link
|
||||
path="mon-compte"
|
||||
:text="$t('general.header.account_text')"
|
||||
@@ -85,6 +85,11 @@ import BetaText from '@/components/BetaText.vue'
|
||||
const { cookies } = useCookies()
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
defineProps({
|
||||
authEnabled: { type: Boolean, default: true },
|
||||
userProfileUrl: { type: String, default: null }
|
||||
})
|
||||
|
||||
let menuIsClosed = ref<boolean>(true)
|
||||
|
||||
function toggleMenu(): void {
|
||||
|
||||
@@ -45,7 +45,7 @@ import Button from '@/components/Button.vue'
|
||||
import { computed, ref } from 'vue'
|
||||
let uploadIsCopied = ref<boolean>(false)
|
||||
|
||||
const props = defineProps({
|
||||
defineProps({
|
||||
textUpload: { type: String, default: '' },
|
||||
textInstall: { type: String, default: '' }
|
||||
})
|
||||
|
||||
23
src/composables/auth.ts
Normal file
23
src/composables/auth.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import axios from 'axios'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
interface UserProfileInterface {
|
||||
url?: string
|
||||
}
|
||||
interface AuthConfigInterface {
|
||||
enabled?: boolean
|
||||
user_profile?: UserProfileInterface
|
||||
}
|
||||
|
||||
export default function authConfig() {
|
||||
const authConf = ref<AuthConfigInterface>({})
|
||||
|
||||
async function getConfig(): Promise<object> {
|
||||
const { data } = await axios.get(
|
||||
`${import.meta.env.VITE_API_URL}api/configuration`
|
||||
)
|
||||
return data.auth
|
||||
}
|
||||
onMounted(async () => (authConf.value = await getConfig()))
|
||||
return { authConf }
|
||||
}
|
||||
@@ -17,6 +17,7 @@ axios.defaults.baseURL = import.meta.env.VITE_API_URL
|
||||
const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
fallbackLocale: 'fr',
|
||||
warnHtmlMessage: false,
|
||||
globalInjection: true,
|
||||
legacy: false,
|
||||
messages: {
|
||||
@@ -24,11 +25,7 @@ const i18n = createI18n({
|
||||
}
|
||||
})
|
||||
globalCookiesConfig({
|
||||
expireTimes: '7d',
|
||||
path: '/',
|
||||
domain: import.meta.env.VITE_API_URL,
|
||||
secure: true,
|
||||
sameSite: 'None'
|
||||
expireTimes: '7d'
|
||||
})
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
23
src/tests/cypress/e2e/home.cy.ts
Normal file
23
src/tests/cypress/e2e/home.cy.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
describe('In the home page', () => {
|
||||
it('click to full and reduce the size of the image', () => {
|
||||
cy.visit('/')
|
||||
cy.get('.gvs-mini-buttons button:nth-child(2)').click()
|
||||
cy.get('.gvs-mini-buttons button:nth-child(2)').click()
|
||||
})
|
||||
it('type an address in the search and go to the localization in the map', () => {
|
||||
cy.visit('/')
|
||||
cy.fixture('home').then((homeData) => {
|
||||
cy.get('.mapboxgl-ctrl-geocoder--input').type(homeData.addressToSearch)
|
||||
cy.contains(homeData.textAddressToSelect).click()
|
||||
})
|
||||
})
|
||||
it('click on the link in the header to go to the upload page', () => {
|
||||
cy.visit('/')
|
||||
cy.fixture('home').then((homeData) => {
|
||||
cy.contains(homeData.textLinkUpload).click()
|
||||
cy.url().should('include', '/partager-des-photos')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
export {}
|
||||
8
src/tests/cypress/e2e/login.cy.ts
Normal file
8
src/tests/cypress/e2e/login.cy.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
describe('In the login page', () => {
|
||||
it('type in the form to login', () => {
|
||||
cy.visit('https://geovisio-backend-dev.osc-fr1.scalingo.io/api/auth/login')
|
||||
cy.get('#password').type('coucouc')
|
||||
})
|
||||
})
|
||||
|
||||
export {}
|
||||
23
src/tests/cypress/e2e/upload.cy.ts
Normal file
23
src/tests/cypress/e2e/upload.cy.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
describe('In the upload page', () => {
|
||||
it('go to the login page', () => {
|
||||
cy.visit('partager-des-photos')
|
||||
cy.fixture('upload').then((uploadData) => {
|
||||
cy.contains(uploadData.textButtonUpload).click()
|
||||
})
|
||||
})
|
||||
it('go to the login page', () => {
|
||||
cy.visit('partager-des-photos')
|
||||
cy.fixture('upload').then((uploadData) => {
|
||||
cy.contains(uploadData.textButtonUpload).click()
|
||||
})
|
||||
})
|
||||
it('go to the cli page', () => {
|
||||
cy.visit('partager-des-photos')
|
||||
cy.fixture('upload').then((uploadData) => {
|
||||
cy.contains(uploadData.textButtonCli).click()
|
||||
cy.url().should('include', '/partager-des-photos')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
export {}
|
||||
5
src/tests/cypress/fixtures/home.json
Normal file
5
src/tests/cypress/fixtures/home.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"addressToSearch": "97 boulevard Voltaire 75011 paris",
|
||||
"textAddressToSelect": "Boulevard Voltaire, Quartier de la Folie-Méricourt, Paris 11e Arrondissement, Paris, Île-de-France, France métropolitaine, 75011, France",
|
||||
"textLinkUpload": "Partager des photos"
|
||||
}
|
||||
4
src/tests/cypress/fixtures/upload.json
Normal file
4
src/tests/cypress/fixtures/upload.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"textButtonUpload": "Créer un compte",
|
||||
"textButtonCli": "Accéder à l'outil"
|
||||
}
|
||||
38
src/tests/cypress/support/commands.ts
Normal file
38
src/tests/cypress/support/commands.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/// <reference types="cypress" />
|
||||
// ***********************************************
|
||||
// This example commands.ts shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||
//
|
||||
// declare global {
|
||||
// namespace Cypress {
|
||||
// interface Chainable {
|
||||
// login(email: string, password: string): Chainable<void>
|
||||
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
export {}
|
||||
20
src/tests/cypress/support/e2e.ts
Normal file
20
src/tests/cypress/support/e2e.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-nocheck
|
||||
// ***********************************************************
|
||||
// This example support/e2e.ts is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
import commands from '/commands'
|
||||
@@ -1,8 +1,8 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import BetaText from '../BetaText.vue'
|
||||
import BetaText from '../../../components/BetaText.vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import fr from '../../locales/fr.json'
|
||||
import fr from '../../../locales/fr.json'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
@@ -1,8 +1,8 @@
|
||||
import { vi, it, beforeEach, describe, expect } from 'vitest'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import fr from '../../locales/fr.json'
|
||||
import Header from '../Header.vue'
|
||||
import fr from '../../../locales/fr.json'
|
||||
import Header from '../../../components/Header.vue'
|
||||
vi.mock('vue-router')
|
||||
|
||||
const i18n = createI18n({
|
||||
@@ -62,6 +62,10 @@ describe('Template', () => {
|
||||
})
|
||||
it('should render the component with good wording keys', async () => {
|
||||
const wrapper = shallowMount(Header, {
|
||||
props: {
|
||||
authEnabled: true,
|
||||
userProfileUrl: 'profil'
|
||||
},
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
mocks: {
|
||||
@@ -79,6 +83,10 @@ describe('Template', () => {
|
||||
})
|
||||
it('should render the component logout link', async () => {
|
||||
const wrapper = shallowMount(Header, {
|
||||
props: {
|
||||
authEnabled: true,
|
||||
userProfileUrl: 'profil'
|
||||
},
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
mocks: {
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, describe, vi, expect } from 'vitest'
|
||||
import { mount, shallowMount } from '@vue/test-utils'
|
||||
import Link from '../Link.vue'
|
||||
import Link from '../../../components/Link.vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
vi.mock('vue-i18n')
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { it, describe, expect, vi } from 'vitest'
|
||||
import { shallowMount, mount } from '@vue/test-utils'
|
||||
import Terminal from '../Terminal.vue'
|
||||
import Button from '../Button.vue'
|
||||
import Terminal from '../../../components/Terminal.vue'
|
||||
import Button from '../../../components/Button.vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import fr from '../../locales/fr.json'
|
||||
import fr from '../../../locales/fr.json'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
@@ -1,6 +1,6 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import MyAccountView from '../MyAccountView.vue'
|
||||
import MyAccountView from '../../../views/MyAccountView.vue'
|
||||
|
||||
describe('Template', () => {
|
||||
it('should render the view with the iframe', async () => {
|
||||
@@ -1,8 +1,8 @@
|
||||
import { it, describe, expect } from 'vitest'
|
||||
import { it, describe, expect, vi } from 'vitest'
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import UploadView from '../UploadView.vue'
|
||||
import UploadView from '../../../views/UploadView.vue'
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import fr from '../../locales/fr.json'
|
||||
import fr from '../../../locales/fr.json'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'fr',
|
||||
@@ -21,7 +21,10 @@ describe('Template', () => {
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
mocks: {
|
||||
$t: (msg) => msg
|
||||
$t: (msg) => msg,
|
||||
authConf: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -32,4 +35,20 @@ describe('Template', () => {
|
||||
expect(wrapper.html()).contains('look="button"')
|
||||
expect(wrapper.html()).contains('type="external"')
|
||||
})
|
||||
it('should render the view without the button link', async () => {
|
||||
import.meta.env.VITE_API_URL = 'api-url/'
|
||||
const wrapper = shallowMount(UploadView, {
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
mocks: {
|
||||
$t: (msg) => msg,
|
||||
authConf: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
console.log(wrapper.html())
|
||||
expect(wrapper.html()).not.toContain('pages.upload.sub_title')
|
||||
})
|
||||
})
|
||||
@@ -4,7 +4,6 @@
|
||||
type="text/css"
|
||||
href="https://cdn.jsdelivr.net/npm/geovisio@develop/build/index.css"
|
||||
/>
|
||||
<Header />
|
||||
<main class="entry-page">
|
||||
<section id="viewer" class="entry-viewer">
|
||||
<div v-if="mapIsLoaded" class="entry-report-button">
|
||||
@@ -23,7 +22,6 @@ import axios from 'axios'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { onMounted, computed, ref } from 'vue'
|
||||
import GeoVisio from 'geovisio'
|
||||
import Header from '@/components/Header.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<template>
|
||||
<Header />
|
||||
<main class="entry-page">
|
||||
<iframe :src="myAccountUrl" class="iframe"></iframe>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Header from '@/components/Header.vue'
|
||||
import { onMounted, computed } from 'vue'
|
||||
import { useCookies } from 'vue3-cookies'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<template>
|
||||
<Header />
|
||||
<main class="entry-page">
|
||||
<section id="sec-1" class="section-upload section-color">
|
||||
<div class="wrapper-upload">
|
||||
@@ -14,7 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<p class="upload-text" v-html="$t('pages.upload.description')" />
|
||||
<div v-if="!isLogged" class="wrapper-account">
|
||||
<div v-if="!isLogged && authConf.enabled" class="wrapper-account">
|
||||
<h4 class="account-subtitle">
|
||||
{{ $t('pages.upload.sub_title') }}
|
||||
</h4>
|
||||
@@ -88,14 +87,15 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Link from '@/components/Link.vue'
|
||||
import Header from '@/components/Header.vue'
|
||||
import Terminal from '@/components/Terminal.vue'
|
||||
import { useCookies } from 'vue3-cookies'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import authConfig from '../composables/auth'
|
||||
const { cookies } = useCookies()
|
||||
const { t } = useI18n()
|
||||
const { authConf } = authConfig()
|
||||
const route = useRoute()
|
||||
|
||||
let hrefSection = ref<string>('#sec-2')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/locales/*.json"],
|
||||
"exclude": ["src/**/__tests__/*"],
|
||||
"exclude": ["src/tests/unit/*"],
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"baseUrl": ".",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
"cypress.config.*",
|
||||
"playwright.config.*"
|
||||
],
|
||||
"extensions": [".js", ".jsx", ".ts", ".tsx"],
|
||||
"compilerOptions": {
|
||||
"types": ["node", "vite/client"]
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ export default defineConfig({
|
||||
server: {
|
||||
host: true,
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
hmr: {
|
||||
port: 9000,
|
||||
overlay: false
|
||||
port: 9000
|
||||
}
|
||||
},
|
||||
base: '/',
|
||||
|
||||
Reference in New Issue
Block a user