update frontend lib : remove histoire (obselete) + update vitest - #1815

This commit is contained in:
Laurent GAY
2025-10-24 13:00:15 +02:00
committed by setop
parent ffa3e0ebd7
commit d971fd77af
192 changed files with 4767 additions and 5300 deletions

1
.gitignore vendored
View File

@@ -55,5 +55,4 @@ node_modules
stats.html stats.html
/coverage /coverage
/playwright-report/ /playwright-report/
.histoire

2
env.d.ts vendored
View File

@@ -1,5 +1,3 @@
/// <reference types="histoire/vue" />
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {

View File

@@ -1,52 +0,0 @@
/// <reference types="@histoire/plugin-vue/components" />
import { defineConfig } from "histoire";
import { HstVue } from "@histoire/plugin-vue";
import path from "path";
export default defineConfig({
plugins: [HstVue()],
setupFile: path.resolve(__dirname, "./src/histoire.setup.ts"),
viteNodeInlineDeps: [/date-fns/],
// viteIgnorePlugins: ['vite-plugin-pwa', 'vite-plugin-pwa:build', 'vite-plugin-pwa:info'],
tree: {
groups: [
{
title: "Actors",
include: (file) => /^src\/components\/Account/.test(file.path),
},
{
title: "Address",
include: (file) => /^src\/components\/Address/.test(file.path),
},
{
title: "Comments",
include: (file) => /^src\/components\/Comment/.test(file.path),
},
{
title: "Discussion",
include: (file) => /^src\/components\/Discussion/.test(file.path),
},
{
title: "Events",
include: (file) => /^src\/components\/Event/.test(file.path),
},
{
title: "Groups",
include: (file) => /^src\/components\/Group/.test(file.path),
},
{
title: "Home",
include: (file) => /^src\/components\/Home/.test(file.path),
},
{
title: "Posts",
include: (file) => /^src\/components\/Post/.test(file.path),
},
{
title: "Others",
include: () => true,
},
],
},
});

3300
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,9 +10,6 @@
"format": "prettier . --write", "format": "prettier . --write",
"build:assets": "vite build", "build:assets": "vite build",
"build:pictures": "bash ./scripts/build/pictures.sh", "build:pictures": "bash ./scripts/build/pictures.sh",
"story:dev": "histoire dev",
"story:build": "histoire build",
"story:preview": "histoire preview",
"test": "vitest", "test": "vitest",
"coverage": "vitest run --coverage", "coverage": "vitest run --coverage",
"prepare": "husky", "prepare": "husky",
@@ -112,7 +109,6 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.38.0", "@eslint/js": "^9.38.0",
"@histoire/plugin-vue": "^0.17.1",
"@playwright/test": "^1.25.1", "@playwright/test": "^1.25.1",
"@rushstack/eslint-patch": "^1.1.4", "@rushstack/eslint-patch": "^1.1.4",
"@tailwindcss/forms": "^0.5.2", "@tailwindcss/forms": "^0.5.2",
@@ -125,9 +121,9 @@
"@types/ngeohash": "^0.6.2", "@types/ngeohash": "^0.6.2",
"@types/phoenix": "^1.5.2", "@types/phoenix": "^1.5.2",
"@types/sanitize-html": "^2.5.0", "@types/sanitize-html": "^2.5.0",
"@vitejs/plugin-vue": "^5.0.0", "@vitejs/plugin-vue": "^6.0.1",
"@vitest/coverage-v8": "^1.2.2", "@vitest/coverage-v8": "^4.0.2",
"@vitest/ui": "^1.2.2", "@vitest/ui": "^4.0.2",
"@vue/eslint-config-prettier": "^10.2.0", "@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.6.0", "@vue/eslint-config-typescript": "^14.6.0",
"@vue/test-utils": "^2.0.2", "@vue/test-utils": "^2.0.2",
@@ -138,21 +134,20 @@
"eslint-plugin-vue": "^10.5.1", "eslint-plugin-vue": "^10.5.1",
"flush-promises": "^1.0.2", "flush-promises": "^1.0.2",
"globals": "^16.4.0", "globals": "^16.4.0",
"histoire": "^0.17.0",
"husky": "^9.0.10", "husky": "^9.0.10",
"jsdom": "^24.0.0", "jsdom": "^24.0.0",
"lint-staged": "^15.1.0", "lint-staged": "^16.2.6",
"mock-apollo-client": "^1.1.0", "mock-apollo-client": "^1.1.0",
"prettier": "^3.0.0", "prettier": "^3.0.0",
"prettier-eslint": "^16.1.2", "prettier-eslint": "^16.1.2",
"rollup-plugin-visualizer": "^5.7.1", "rollup-plugin-visualizer": "^6.0.5",
"sass": "^1.34.1", "sass": "^1.34.1",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.46.2", "typescript-eslint": "^8.46.2",
"vite": "^5.0.12", "vite": "^7.1.12",
"vite-plugin-pwa": "^0.19.0", "vite-plugin-pwa": "^1.1.0",
"vitest": "^1.2.2", "vitest": "^4.0.2",
"vue-i18n-extract": "^2.0.4", "vue-i18n-extract": "^2.0.4",
"vue-router-mock": "^1.0.0" "vue-router-mock": "^2.0.0"
} }
} }

View File

@@ -1,20 +0,0 @@
<template>
<Story>
<Variant title="empty">
<InstanceContactLink />
</Variant>
<Variant title="string">
<InstanceContactLink contact="someone" />
</Variant>
<Variant title="email">
<InstanceContactLink contact="someone@somewhere.tld" />
</Variant>
<Variant title="url">
<InstanceContactLink contact="https://somewhere.com" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import InstanceContactLink from "./InstanceContactLink.vue";
</script>

View File

@@ -1,52 +0,0 @@
<template>
<Story>
<Variant title="local">
<ActorCard :actor="stateLocal"></ActorCard>
<template #controls>
<HstText v-model="stateLocal.preferredUsername" title="username" />
<HstText v-model="stateLocal.name" title="Name" />
</template>
</Variant>
<Variant title="remote">
<ActorCard :actor="stateRemote"></ActorCard>
<template #controls>
<HstText v-model="stateRemote.preferredUsername" title="username" />
<HstText v-model="stateRemote.name" title="Name" />
<HstText v-model="stateRemote.domain" title="Domain" />
<HstText v-model="avatarUrl" title="Avatar" />
</template>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import ActorCard from "./ActorCard.vue";
import { reactive, ref } from "vue";
import { IActor } from "@/types/actor";
import { ActorType } from "@/types/enums";
const avatarUrl = ref<string>(
"https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg"
);
const stateLocal = reactive<IActor>({
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
const stateRemote = reactive<IActor>({
name: "Framasoft",
preferredUsername: "framasoft",
avatar: { url: avatarUrl.value, id: "", name: "", alt: "", metadata: {} },
domain: "framapiaf.org",
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
</script>

View File

@@ -1,52 +0,0 @@
<template>
<Story>
<Variant title="local">
<ActorInline :actor="stateLocal" />
<template #controls>
<HstText v-model="stateLocal.preferredUsername" title="username" />
<HstText v-model="stateLocal.name" title="Name" />
</template>
</Variant>
<Variant title="remote">
<ActorInline :actor="stateRemote" />
<template #controls>
<HstText v-model="stateRemote.preferredUsername" title="username" />
<HstText v-model="stateRemote.name" title="Name" />
<HstText v-model="stateRemote.domain" title="Domain" />
<HstText v-model="avatarUrl" title="Avatar" />
</template>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import ActorInline from "./ActorInline.vue";
import { reactive, ref } from "vue";
import { IActor } from "@/types/actor";
import { ActorType } from "@/types/enums";
const avatarUrl = ref<string>(
"https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg"
);
const stateLocal = reactive<IActor>({
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
const stateRemote = reactive<IActor>({
name: "Framasoft",
preferredUsername: "framasoft",
avatar: { url: avatarUrl.value, id: "", name: "", alt: "", metadata: {} },
domain: "framapiaf.org",
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
</script>

View File

@@ -1,59 +0,0 @@
<template>
<Story>
<Variant :setup-app="setupApp" title="Person">
<div class="p-5">
<PopoverActorCard :actor="baseActor">
<div><b> Popover me !</b></div></PopoverActorCard
>
</div>
</Variant>
<Variant :setup-app="setupApp" title="Group">
<div class="p-5">
<PopoverActorCard :actor="group">
<div><b> Popover me !</b></div></PopoverActorCard
>
</div>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import PopoverActorCard from "./PopoverActorCard.vue";
import FloatingVue from "floating-vue";
import "floating-vue/dist/style.css";
import { ActorType } from "@/types/enums";
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const baseActor = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
};
const group = {
...baseActor,
name: "Framasoft",
preferredUsername: "framasoft",
domain: "mobilizon.fr",
avatar: {
...baseActorAvatar,
url: "https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg",
},
};
function setupApp({ app }) {
app.use(FloatingVue);
}
</script>

View File

@@ -1,29 +0,0 @@
<template>
<Story>
<Variant>
<div class="p-5">
<ProfileOnboarding
:current-actor="baseActor"
instance-name="Instance name"
/>
</div>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import ProfileOnboarding from "./ProfileOnboarding.vue";
import { ActorType } from "@/types/enums";
import { IPerson } from "@/types/actor";
const baseActor: IPerson = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
};
</script>

View File

@@ -1,31 +0,0 @@
<template>
<Story>
<Variant title="Basic">
<AddressInfo :address="address" />
</Variant>
<Variant title="Basic with timezone">
<AddressInfo
:address="address"
:show-timezone="true"
:user-timezone="'Europe/Berlin'"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IAddress } from "@/types/address.model";
import { reactive } from "vue";
import AddressInfo from "./AddressInfo.vue";
const address = reactive<IAddress>({
description: "Locaux Motiv",
street: "10 Rue Jangot",
locality: "Lyon",
postalCode: "69007",
region: "Auvergne Rhône-Alpes",
country: "France",
type: "",
timezone: "Europe/Dublin",
});
</script>

View File

@@ -1,27 +0,0 @@
<template>
<Story>
<Variant title="with locality">
<InlineAddress :physicalAddress="address" />
</Variant>
<Variant title="without locality">
<InlineAddress :physicalAddress="{ ...address, locality: null }" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IAddress } from "@/types/address.model";
import { reactive } from "vue";
import InlineAddress from "./InlineAddress.vue";
const address = reactive<IAddress>({
description: "Locaux Motiv",
street: "10 Rue Jangot",
locality: "Lyon",
postalCode: "69007",
region: "Auvergne Rhône-Alpes",
country: "France",
type: "",
timezone: "Europe/Dublin",
});
</script>

View File

@@ -1,29 +0,0 @@
<template>
<Story>
<Variant title="Basic">
<section class="flex flex-wrap gap-3 md:gap-5">
<CategoryCard :category="category" />
</section>
</Variant>
<Variant title="Details">
<section class="flex flex-wrap gap-3 md:gap-5">
<CategoryCard
:category="{ ...category, key: 'OUTDOORS_ADVENTURE' }"
:with-details="true"
/>
</section>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { CategoryStatsModel } from "@/types/stats.model";
import { reactive } from "vue";
import CategoryCard from "./CategoryCard.vue";
const category = reactive<CategoryStatsModel>({
key: "PHOTOGRAPHY",
number: 5,
label: "Hello",
});
</script>

View File

@@ -1,50 +0,0 @@
<template>
<Story>
<Variant title="Basic">
<DiscussionComment v-model="comment" :currentActor="baseActor" />
</Variant>
<Variant title="Deleted comment">
<DiscussionComment v-model="deletedComment" :currentActor="baseActor" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IPerson } from "@/types/actor";
import { IComment } from "@/types/comment.model";
import { ActorType } from "@/types/enums";
import { reactive } from "vue";
import DiscussionComment from "./DiscussionComment.vue";
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const baseActor: IPerson = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
id: "598",
};
const comment = reactive<IComment>({
text: "Hello there",
publishedAt: new Date().toString(),
actor: baseActor,
});
const deletedComment = reactive<IComment>({
...comment,
actor: null,
deletedAt: new Date().toString(),
});
</script>

View File

@@ -1,33 +0,0 @@
<template>
<Story>
<Variant title="Basic">
<DiscussionListItem :discussion="discussion" />
</Variant>
<Variant title="Deleted comment">
<DiscussionListItem :discussion="discussionWithDeletedComment" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IDiscussion } from "@/types/discussions";
import { reactive } from "vue";
import DiscussionListItem from "@/components/Discussion/DiscussionListItem.vue";
const discussion = reactive<IDiscussion>({
title: "A discussion",
comments: { total: 5, elements: [] },
insertedAt: new Date().toString(),
updatedAt: new Date().toString(),
deletedAt: null,
lastComment: { text: "Hello there", publishedAt: new Date().toString() },
});
const discussionWithDeletedComment = reactive<IDiscussion>({
...discussion,
lastComment: {
...discussion.lastComment,
deletedAt: new Date().toString(),
},
});
</script>

View File

@@ -1,14 +0,0 @@
<template>
<Story>
<Variant title="new">
<DateCalendarIcon :date="new Date().toString()" />
</Variant>
<Variant title="small">
<DateCalendarIcon :date="new Date().toString()" :small="true" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import DateCalendarIcon from "./DateCalendarIcon.vue";
</script>

View File

@@ -1,56 +0,0 @@
<template>
<Story :setup-app="setupApp">
<Variant>
<OrganizerPicker
v-model="actor"
:identities="identities"
v-model:actor-filter="actorFilter"
:groupMemberships="[]"
:current-actor="currentActor"
@update:actor-filter="logEvent('Actor Filter updated', $event)"
@update:model-value="logEvent('Selected actor updated', $event)"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import OrganizerPicker from "./OrganizerPicker.vue";
import { createMemoryHistory, createRouter } from "vue-router";
import { reactive, ref } from "vue";
import { ActorType } from "@/types/enums";
import { logEvent } from "histoire/client";
const currentActor = reactive({
id: "59",
preferredUsername: "me",
name: "Someone",
type: ActorType.PERSON,
});
const actor = reactive({
id: "5",
preferredUsername: "hello",
name: "Sigmund",
type: ActorType.PERSON,
});
const group = reactive({
id: "89",
preferredUsername: "congregation",
name: "College",
type: ActorType.GROUP,
});
const identities = [actor, group];
const actorFilter = ref("");
function setupApp({ app }) {
app.use(
createRouter({
history: createMemoryHistory(),
routes: [{ path: "/", name: "home", component: { render: () => null } }],
})
);
}
</script>

View File

@@ -1,89 +0,0 @@
<template>
<Story :setup-app="setupApp">
<Variant>
<OrganizerPickerWrapper
v-model="actor"
@update:model-value="logEvent('Value', $event)"
@update:contacts="logEvent('Contacts', $event)"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import OrganizerPickerWrapper from "./OrganizerPickerWrapper.vue";
import { DefaultApolloClient } from "@vue/apollo-composable";
import { createMockClient } from "mock-apollo-client";
import { cache } from "@/apollo/memory";
import { ICurrentUserRole } from "@/types/enums";
import { PERSON_GROUP_MEMBERSHIPS } from "@/graphql/actor";
import { createMemoryHistory, createRouter } from "vue-router";
import { IDENTITIES } from "@/graphql/actor";
import { reactive } from "vue";
import { logEvent } from "histoire/client";
const actor = reactive({
id: "5",
preferredUsername: "hello",
name: "Sigmund",
});
function setupApp({ app }) {
const defaultResolvers = {
Query: {
currentUser: (): Record<string, any> => ({
email: "user@mail.com",
id: "2",
role: ICurrentUserRole.USER,
isLoggedIn: true,
__typename: "CurrentUser",
}),
currentActor: (): Record<string, any> => ({
id: "67",
preferredUsername: "someone",
name: "Personne",
avatar: null,
__typename: "CurrentActor",
}),
},
};
const mockClient = createMockClient({
cache,
resolvers: defaultResolvers,
});
mockClient.setRequestHandler(
PERSON_GROUP_MEMBERSHIPS,
() =>
new Promise((resolve) =>
resolve({
data: {
person: { id: "5", memberships: { total: 0, elements: [] } },
},
})
)
);
mockClient.setRequestHandler(
IDENTITIES,
() =>
new Promise((resolve) =>
resolve({
data: {
loggedUser: {
actors: [{ id: "9", preferredUsername: "sam", name: "Samuel" }],
},
},
})
)
);
app.provide(DefaultApolloClient, mockClient);
app.use(
createRouter({
history: createMemoryHistory(),
routes: [{ path: "/", name: "home", component: { render: () => null } }],
})
);
}
</script>

View File

@@ -1,114 +0,0 @@
<template>
<Story>
<Variant title="Unlogged">
<ParticipationButton
:event="event"
:current-actor="emptyCurrentActor"
:participation="undefined"
:identities="[]"
/>
</Variant>
<Variant title="Basic">
<ParticipationButton
:event="event"
:current-actor="currentActor"
:participation="undefined"
:identities="identities"
@join-event="logEvent('Join event', $event)"
@join-modal="logEvent('Join modal', $event)"
@confirm-leave="logEvent('Confirm leave', $event)"
/>
</Variant>
<Variant title="Basic with confirmation">
<ParticipationButton
:event="{ ...event, joinOptions: EventJoinOptions.RESTRICTED }"
:current-actor="currentActor"
:participation="undefined"
:identities="identities"
@join-event-with-confirmation="
logEvent('Join Event with confirmation', $event)
"
@join-modal="logEvent('Join modal', $event)"
/>
</Variant>
<Variant title="Participating">
<ParticipationButton
:event="event"
:current-actor="currentActor"
:participation="participation"
:identities="identities"
@confirm-leave="logEvent('Confirm leave', $event)"
/>
</Variant>
<Variant title="Pending approval">
<ParticipationButton
:event="event"
:current-actor="currentActor"
:participation="{
...participation,
role: ParticipantRole.NOT_APPROVED,
}"
:identities="identities"
@confirm-leave="logEvent('Confirm leave', $event)"
/>
</Variant>
<Variant title="Rejected">
<ParticipationButton
:event="event"
:current-actor="currentActor"
:participation="{
...participation,
role: ParticipantRole.REJECTED,
}"
:identities="identities"
@confirm-leave="logEvent('Confirm leave', $event)"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IPerson } from "@/types/actor";
import { EventJoinOptions, ParticipantRole } from "@/types/enums";
import { IEvent } from "@/types/event.model";
import ParticipationButton from "./ParticipationButton.vue";
import { logEvent } from "histoire/client";
import { IParticipant } from "@/types/participant.model";
const emptyCurrentActor: IPerson = {};
const currentActor: IPerson = {
id: "1",
preferredUsername: "tcit",
name: "Thomas",
avatar: {
url: "https://mobilizon.fr/media/3a5f18c058a8193b1febfaf561f94ae8b91f85ac64c01ddf5ad7b251fb43baf5.jpg?name=profil.jpg",
},
};
const participation: IParticipant = {
actor: currentActor,
role: ParticipantRole.PARTICIPANT,
};
const identities: IPerson[] = [
currentActor,
{
id: "2",
preferredUsername: "another",
name: "Another",
avatar: {
url: "https://mobilizon.fr/media/95ab5ba92287ab4857bb517cadae2a7ab6a553748d1c48cefc27e2b7ab640fea.jpg?name=FB_IMG_16150214351371162.jpg",
},
},
];
const event: IEvent = {
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
options: {
anonymousParticipation: false,
},
joinOptions: EventJoinOptions.FREE,
};
</script>

View File

@@ -1,29 +0,0 @@
<template>
<Story>
<Variant title="Public">
<ShareEventModal :event="event" />
</Variant>
<Variant title="Private">
<ShareEventModal
:event="{ ...event, visibility: EventVisibility.PRIVATE }"
/>
</Variant>
<Variant title="Cancelled">
<ShareEventModal :event="{ ...event, status: EventStatus.CANCELLED }" />
</Variant>
<Variant title="No seats left">
<ShareEventModal :event="event" :event-capacity-o-k="false" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { EventVisibility, EventStatus } from "@/types/enums";
import ShareEventModal from "./ShareEventModal.vue";
const event = {
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
visibility: EventVisibility.PUBLIC,
};
</script>

View File

@@ -1,17 +0,0 @@
<template>
<Story>
<Variant title="row">
<SkeletonEventResult />
</Variant>
<Variant title="column">
<SkeletonEventResult view-mode="column" />
</Variant>
<Variant title="not minimal">
<SkeletonEventResult :minimal="false" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import SkeletonEventResult from "./SkeletonEventResult.vue";
</script>

View File

@@ -1,18 +0,0 @@
<template>
<Story>
<Variant title="new">
<TagInput v-model="tags" />
</Variant>
<!-- <Variant title="small">
<TagInput v-model="tags" />
</Variant> -->
</Story>
</template>
<script lang="ts" setup>
import { ITag } from "@/types/tag.model";
import { reactive } from "vue";
import TagInput from "./TagInput.vue";
const tags = reactive<ITag[]>([{ title: "Hello", slug: "hello" }]);
</script>

View File

@@ -1,60 +0,0 @@
<template>
<Story>
<Variant title="Empty">
<div class="p-5">
<GroupCard :group="basicGroup" />
</div>
</Variant>
<Variant title="With media">
<div class="p-5">
<GroupCard :group="groupWithMedia" />
</div>
</Variant>
<Variant title="with followers or members">
<div class="p-5">
<GroupCard :group="groupWithFollowersOrMembers" />
</div>
</Variant>
<Variant title="Row mode">
<GroupCard :group="groupWithFollowersOrMembers" mode="row" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IGroup } from "@/types/actor";
import GroupCard from "./GroupCard.vue";
const basicGroup: IGroup = {
name: "Framasoft",
preferredUsername: "framasoft",
avatar: null,
domain: "mobilizon.fr",
url: "",
summary: "",
suspended: false,
members: { total: 0, elements: [] },
followers: { total: 0, elements: [] },
};
const groupWithMedia: IGroup = {
...basicGroup,
banner: {
url: "https://mobilizon.fr/media/a8227a16cc80b3d20ff5ee549a29c1b20a0ca1547f8861129aae9f00c3c69d12.jpg?name=framasoft%27s%20banner.jpg",
},
avatar: {
url: "https://mobilizon.fr/media/890f5396ef80081a6b1b18a5db969746cf8bb340e8a4e657d665e41f6646c539.jpg?name=framasoft%27s%20avatar.jpg",
},
};
const groupWithFollowersOrMembers: IGroup = {
...groupWithMedia,
members: { total: 2, elements: [] },
followers: { total: 5, elements: [] },
summary:
"You can also use variant modifiers to target media queries like responsive breakpoints, dark mode, prefers-reduced-motion, and more. For example, use md:h-full to apply the h-full utility at only medium screen sizes and above.",
physicalAddress: {
description: "Nantes",
},
};
</script>

View File

@@ -1,91 +0,0 @@
<template>
<Story>
<Variant title="simple member">
<div class="p-5">
<GroupMemberCard :member="basicMember" />
</div>
</Variant>
<Variant title="moderator">
<div class="p-5">
<GroupMemberCard :member="moderatorMember" />
</div>
</Variant>
<Variant title="administrator">
<div class="p-5">
<GroupMemberCard :member="adminMember" />
</div>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IActor } from "@/types/actor";
import { IMember } from "@/types/actor/member.model";
import { MemberRole } from "@/types/enums";
import GroupMemberCard from "./GroupMemberCard.vue";
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const basePerson: IActor = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
};
const basicGroup: IActor = {
name: "Framasoft",
preferredUsername: "framasoft",
avatar: {
url: "https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png",
},
domain: "mobilizon.fr",
url: "",
summary: `<p><strong>La Fediverse</strong>, <strong>c'est la <em><u>Féd</u>ération qui englobe l'Un<u>ivers</u> des réseaux sociaux libres et décentralisés,</em> </strong>dont Mobilizon (évènements), Mastodon (microblog), Peertube (vidéos), Pixelfed (photos), Funkwhale (musique), Matrix (messagerie instantanée)... et tant d'autres font partie.</p><p><strong>Et "La Fediverse <em>Nantaise</em>" est un collectif cherchant à faire connaître localement tout le potentiel de ces réseaux ! :-)</strong></p>`,
suspended: false,
members: { total: 0, elements: [] },
followers: { total: 0, elements: [] },
};
const basicMember: IMember = {
parent: basicGroup as IActor,
actor: basePerson,
role: MemberRole.MEMBER,
};
const moderatorMember: IMember = {
parent: basicGroup,
actor: basePerson,
role: MemberRole.MODERATOR,
};
const adminMember: IMember = {
parent: basicGroup,
actor: basePerson,
role: MemberRole.ADMINISTRATOR,
};
// const groupWithMedia = {
// ...basicGroup,
// banner: {
// url: "https://mobilizon.fr/media/7b340fe641e7ad711ebb6f8821b5ce824992db08701e37ebb901c175436aaafc.jpg?name=framasoft%27s%20banner.jpg",
// },
// avatar: {
// url: "https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png",
// },
// };
// const groupWithFollowersOrMembers = {
// ...groupWithMedia,
// members: { total: 2, elements: [] },
// followers: { total: 5, elements: [] },
// };
</script>

View File

@@ -1,16 +0,0 @@
<template>
<Story :setup-app="setupApp">
<Variant>
<CategoriesPreview />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { apolloClient } from "@/vue-apollo";
import { DefaultApolloClient } from "@vue/apollo-composable";
import CategoriesPreview from "./CategoriesPreview.vue";
function setupApp({ app }) {
app.provide(DefaultApolloClient, apolloClient);
}
</script>

View File

@@ -1,10 +0,0 @@
<template>
<Story>
<Variant>
<MobilizonPresentation />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import MobilizonPresentation from "./MobilizonPresentation.vue";
</script>

View File

@@ -1,22 +0,0 @@
<template>
<Story :setup-app="setupApp">
<Variant>
<SearchFields
:search="''"
:location="{}"
@update:location="logEvent('update location', $event)"
@update:search="logEvent('update search', $event)"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { apolloClient } from "@/vue-apollo";
import { DefaultApolloClient } from "@vue/apollo-composable";
import SearchFields from "./SearchFields.vue";
import { logEvent } from "histoire/client";
function setupApp({ app }) {
app.provide(DefaultApolloClient, apolloClient);
}
</script>

View File

@@ -1,23 +0,0 @@
<template>
<Story>
<Variant :title="'Open'">
<UnloggedIntroduction :config="config" />
</Variant>
<Variant :title="'Closed'">
<UnloggedIntroduction :config="configClosed" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { reactive } from "vue";
import UnloggedIntroduction from "./UnloggedIntroduction.vue";
const config = reactive({
name: "My instance name",
description: "An instance that doesn't exist",
slogan: "Test! Test! Test!",
registrationsOpen: true,
});
const configClosed = reactive({ ...config, registrationsOpen: false });
</script>

View File

@@ -1,48 +0,0 @@
<template>
<Story>
<Variant title="Public">
<PostListItem :post="post" />
</Variant>
<Variant title="Long">
<PostListItem :post="longPost" />
</Variant>
<Variant title="Is member">
<PostListItem :post="longPost" :is-current-actor-member="true" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IPost } from "@/types/post.model";
import PostListItem from "./PostListItem.vue";
const post: IPost = {
title: "Musique sur Nantes : un groupe à développer ensemble !",
url: "https://mobilizon.fr/p/an-uuid",
insertedAt: new Date(),
author: {
name: "I'm the author",
preferredUsername: "the_author",
},
tags: [
{ slug: "musique", title: "Musique" },
{ slug: "concert", title: "Concert" },
],
picture: {
url: "https://mobilizon.fr/media/70e930f488788afdf5d024be5ac2f9c9f0e1b166e16f645beb2c344cdcc65d62.jpg?name=musiquesurnantesbanner.jpg",
},
};
const longPost = {
...post,
title:
"Musique sur Nantes : un groupe à développer ensemble ! Musique sur Nantes : un groupe à développer ensemble !",
tags: [
...(post.tags ?? []),
{ slug: "verylongtagwhathappensthen", title: "VeryLongTagWhatHappensThen" },
{ slug: "justanother", title: "Just another" },
],
};
</script>

View File

@@ -1,20 +0,0 @@
<template>
<Story>
<Variant title="Public">
<SharePostModal :post="{ ...post, visibility: PostVisibility.PUBLIC }" />
</Variant>
<Variant title="Private">
<SharePostModal :post="post" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { PostVisibility } from "@/types/enums";
import SharePostModal from "./SharePostModal.vue";
const post = {
title: "hello",
url: "https://mobilizon.fr/p/an-uuid",
};
</script>

View File

@@ -1,13 +0,0 @@
<template>
<Story>
<Variant title="Public">
<AuthProviders :oauthProviders="providers" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import AuthProviders from "./AuthProviders.vue";
const providers = [{ id: "keycloak", label: "Entreprise" }, { id: "google" }];
</script>

View File

@@ -1,16 +0,0 @@
<template>
<Story :layout="{ type: 'grid', width: 60 }">
<Variant title="Google">
<MaterialIcon :icon="['', 'google']" />
</Variant>
<Variant title="Calendar">
<MaterialIcon :icon="['', 'calendar']" />
</Variant>
<Variant title="Account Multiple Plus">
<MaterialIcon :icon="['', 'account-multiple-plus']" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import MaterialIcon from "./MaterialIcon.vue";
</script>

View File

@@ -1,17 +0,0 @@
import { defineSetupVue3 } from "@histoire/plugin-vue";
import { orugaConfig } from "./oruga-config";
import { i18n } from "./utils/i18n";
import Oruga from "@oruga-ui/oruga-next";
import "@oruga-ui/oruga-next/dist/oruga-full-vars.css";
import "./assets/tailwind.css";
import "./assets/oruga-tailwindcss.css";
import locale from "date-fns/locale/en-US";
import MaterialIcon from "./components/core/MaterialIcon.vue";
export const setupVue3 = defineSetupVue3(({ app }) => {
// Vue plugin
app.use(i18n);
app.use(Oruga, orugaConfig);
app.component("material-icon", MaterialIcon);
app.provide("dateFnsLocale", locale);
});

View File

@@ -0,0 +1,74 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import InstanceContactLink from "@/components/About/InstanceContactLink.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any = {}) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(InstanceContactLink, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("InstanceContactLink", () => {
it("Show empty", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show string", async () => {
const wrapper = generateWrapper({
contact: "someone",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show email", async () => {
const wrapper = generateWrapper({
contact: "someone@somewhere.tld",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show url", async () => {
const wrapper = generateWrapper({
contact: "https://somewhere.com",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`InstanceContactLink > Show email 1`] = `"<p><a dir="auto" title="someone@somewhere.tld" href="mailto:someone@somewhere.tld">someone@somewhere.tld</a></p>"`;
exports[`InstanceContactLink > Show empty 1`] = `"<p><span>contact uninformed</span></p>"`;
exports[`InstanceContactLink > Show string 1`] = `"<p><span dir="auto">someone</span></p>"`;
exports[`InstanceContactLink > Show url 1`] = `"<p><a dir="auto" title="https://somewhere.com" href="https://somewhere.com">somewhere.com</a></p>"`;

View File

@@ -0,0 +1,87 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import ActorCard from "@/components/Account/ActorCard.vue";
import { reactive, ref } from "vue";
import { IActor } from "@/types/actor";
import { ActorType } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const avatarUrl = ref<string>(
"https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg"
);
const stateLocal = reactive<IActor>({
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
const stateRemote = reactive<IActor>({
name: "Framasoft",
preferredUsername: "framasoft",
avatar: { url: avatarUrl.value, id: "", name: "", alt: "", metadata: {} },
domain: "framapiaf.org",
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(ActorCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("ActorCard", () => {
it("Show local", async () => {
const wrapper = generateWrapper({
actor: stateLocal,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show simple", async () => {
const wrapper = generateWrapper({
actor: stateRemote,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,87 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import ActorInline from "@/components/Account/ActorInline.vue";
import { reactive, ref } from "vue";
import { IActor } from "@/types/actor";
import { ActorType } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(ActorInline, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const avatarUrl = ref<string>(
"https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg"
);
const stateLocal = reactive<IActor>({
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
const stateRemote = reactive<IActor>({
name: "Framasoft",
preferredUsername: "framasoft",
avatar: { url: avatarUrl.value, id: "", name: "", alt: "", metadata: {} },
domain: "framapiaf.org",
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
});
describe("ActorInline", () => {
it("Show local", async () => {
const wrapper = generateWrapper({
actor: stateLocal,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show remote", async () => {
const wrapper = generateWrapper({
actor: stateRemote,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,90 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import PopoverActorCard from "@/components/Account/PopoverActorCard.vue";
import { ActorType } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const baseActor = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
};
const group = {
...baseActor,
name: "Framasoft",
preferredUsername: "framasoft",
domain: "mobilizon.fr",
avatar: {
...baseActorAvatar,
url: "https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg",
},
};
const generateWrapper = (actor: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(PopoverActorCard, {
props: {
actor: actor,
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
slots: {
default: "<div><b> Popover me !</b></div>",
},
});
};
describe("PopoverActorCard", () => {
it("Show Person", async () => {
const wrapper = generateWrapper(baseActor);
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Group", async () => {
const wrapper = generateWrapper(group);
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,63 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import ProfileOnboarding from "@/components/Account/ProfileOnboarding.vue";
import { ActorType } from "@/types/enums";
import { IPerson } from "@/types/actor";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const baseActor: IPerson = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: null,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
};
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(ProfileOnboarding, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("ProfileOnboarding", () => {
it("Show simple", async () => {
const wrapper = generateWrapper({
currentActor: baseActor,
instanceName: "Instance name",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,103 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`ActorCard > Show local 1`] = `
"<div data-v-b0ff4ece="" class="bg-white dark:bg-mbz-purple rounded-lg flex space-x-4 items-center flex-col p-4 shadow-md sm:p-8 pb-10 w-80">
<div data-v-b0ff4ece="" class="flex pl-2"><span data-v-b0ff4ece="" class="ltr:-mr-0.5 rtl:-ml-0.5 material-design-icon account-circle-icon ltr:-mr-0.5 rtl:-ml-0.5" aria-hidden="true" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div data-v-b0ff4ece="" class="text-center overflow-hidden w-full">
<h5 data-v-b0ff4ece="" class="text-xl font-medium violet-title tracking-tight text-gray-900 dark:text-gray-200 whitespace-pre-line line-clamp-2">Thomas Citharel</h5>
<p data-v-b0ff4ece="" class="text-gray-500 dark:text-gray-200 truncate"><span data-v-b0ff4ece="" dir="ltr">@tcit</span></p>
<!--v-if-->
<!--v-if-->
</div>
<div data-v-b0ff4ece="" class="flex pr-2"><a data-v-b0ff4ece="" href="/conversations?newMessage=true&amp;personMentions=tcit" class=""><span data-v-b0ff4ece="" aria-hidden="true" class="material-design-icon email-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20,8L12,13L4,8V6L12,11L20,6M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4Z"><!--v-if--></path></svg></span></a></div>
</div>
<!-- <div
class="p-4 bg-white rounded-lg shadow-md sm:p-8 flex items-center space-x-4"
dir="auto"
>
<div class="flex-shrink-0">
<figure class="w-12 h-12" v-if="actor.avatar">
<img
class="rounded-lg"
:src="actor.avatar.url"
alt=""
width="48"
height="48"
/>
</figure>
<o-icon
v-else
size="large"
icon="account-circle"
class="ltr:-mr-0.5 rtl:-ml-0.5"
/>
</div>
<div class="flex-1 min-w-0">
<h5 class="text-xl font-medium violet-title tracking-tight text-gray-900">
{{ displayName(actor) }}
</h5>
<p class="text-gray-500 truncate" v-if="actor.name">
<span dir="ltr">@{{ usernameWithDomain(actor) }}</span>
</p>
<div
v-if="full"
class="line-clamp-3"
:class="{ limit: limit }"
v-html="actor.summary"
/>
</div>
</div> -->"
`;
exports[`ActorCard > Show simple 1`] = `
"<div data-v-b0ff4ece="" class="bg-white dark:bg-mbz-purple rounded-lg flex space-x-4 items-center flex-col p-4 shadow-md sm:p-8 pb-10 w-80">
<div data-v-b0ff4ece="" class="flex pl-2">
<figure data-v-b0ff4ece="" class="w-12 h-12"><img data-v-b0ff4ece="" class="rounded-full object-cover h-full" src="https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg" alt="" width="48" height="48" loading="lazy"></figure>
</div>
<div data-v-b0ff4ece="" class="text-center overflow-hidden w-full">
<h5 data-v-b0ff4ece="" class="text-xl font-medium violet-title tracking-tight text-gray-900 dark:text-gray-200 whitespace-pre-line line-clamp-2">Framasoft</h5>
<p data-v-b0ff4ece="" class="text-gray-500 dark:text-gray-200 truncate"><span data-v-b0ff4ece="" dir="ltr">@framasoft@framapiaf.org</span></p>
<!--v-if-->
<!--v-if-->
</div>
<div data-v-b0ff4ece="" class="flex pr-2"><a data-v-b0ff4ece="" href="/conversations?newMessage=true&amp;personMentions=framasoft@framapiaf.org" class=""><span data-v-b0ff4ece="" aria-hidden="true" class="material-design-icon email-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20,8L12,13L4,8V6L12,11L20,6M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4Z"><!--v-if--></path></svg></span></a></div>
</div>
<!-- <div
class="p-4 bg-white rounded-lg shadow-md sm:p-8 flex items-center space-x-4"
dir="auto"
>
<div class="flex-shrink-0">
<figure class="w-12 h-12" v-if="actor.avatar">
<img
class="rounded-lg"
:src="actor.avatar.url"
alt=""
width="48"
height="48"
/>
</figure>
<o-icon
v-else
size="large"
icon="account-circle"
class="ltr:-mr-0.5 rtl:-ml-0.5"
/>
</div>
<div class="flex-1 min-w-0">
<h5 class="text-xl font-medium violet-title tracking-tight text-gray-900">
{{ displayName(actor) }}
</h5>
<p class="text-gray-500 truncate" v-if="actor.name">
<span dir="ltr">@{{ usernameWithDomain(actor) }}</span>
</p>
<div
v-if="full"
class="line-clamp-3"
:class="{ limit: limit }"
v-html="actor.summary"
/>
</div>
</div> -->"
`;

View File

@@ -0,0 +1,23 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`ActorInline > Show local 1`] = `
"<div data-v-397a2c1c="" class="inline-flex items-start gap-2 bg-white dark:bg-violet-1 dark:text-white p-2 rounded-md">
<div data-v-397a2c1c="" class="flex-none"><span data-v-397a2c1c="" aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="36" height="36" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div data-v-397a2c1c="" class="flex-auto">
<p data-v-397a2c1c="" class="text-lg line-clamp-3 md:line-clamp-2 max-w-xl">Thomas Citharel</p>
<p data-v-397a2c1c="" class="text-sm text-gray-500 dark:text-gray-300 truncate"> @tcit</p>
</div>
</div>"
`;
exports[`ActorInline > Show remote 1`] = `
"<div data-v-397a2c1c="" class="inline-flex items-start gap-2 bg-white dark:bg-violet-1 dark:text-white p-2 rounded-md">
<div data-v-397a2c1c="" class="flex-none">
<figure data-v-397a2c1c=""><img data-v-397a2c1c="" class="rounded-xl" src="https://stockage.framapiaf.org/framapiaf/accounts/avatars/000/000/399/original/52b08a3e80b43d40.jpg" alt="" width="36" height="36" loading="lazy"></figure>
</div>
<div data-v-397a2c1c="" class="flex-auto">
<p data-v-397a2c1c="" class="text-lg line-clamp-3 md:line-clamp-2 max-w-xl">Framasoft</p>
<p data-v-397a2c1c="" class="text-sm text-gray-500 dark:text-gray-300 truncate"> @framasoft@framapiaf.org</p>
</div>
</div>"
`;

View File

@@ -0,0 +1,13 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`PopoverActorCard > Show Group 1`] = `
"<vmenu distance="16" triggers="hover" class="popover">
<div><b> Popover me !</b></div>
</vmenu>"
`;
exports[`PopoverActorCard > Show Person 1`] = `
"<vmenu distance="16" triggers="hover" class="popover">
<div><b> Popover me !</b></div>
</vmenu>"
`;

View File

@@ -0,0 +1,13 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`ProfileOnboarding > Show simple 1`] = `
"<div class="">
<h2 class="text-2xl">Profiles and federation</h2>
</div>
<p class="my-2">Mobilizon uses a system of profiles to compartiment your activities. You will be able to create as many profiles as you want.</p>
<hr role="presentation">
<p class="my-2"><span>Mobilizon is a federated software, meaning you can interact - depending on your admin's federation settings - with content from other instances, such as joining groups or events that were created elsewhere.</span>This instance, <b>Instance name (localhost)</b>, hosts your profile, so remember its name.</p>
<hr role="presentation">
<p class="my-2">If you are being asked for your federated indentity, it's composed of your username and your instance. For instance, the federated identity for your first profile is:</p>
<div class="text-center"><code>tcit@localhost</code></div>"
`;

View File

@@ -0,0 +1,73 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import AddressInfo from "@/components/Address/AddressInfo.vue";
import { IAddress } from "@/types/address.model";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(AddressInfo, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const address = reactive<IAddress>({
description: "Locaux Motiv",
street: "10 Rue Jangot",
locality: "Lyon",
postalCode: "69007",
region: "Auvergne Rhône-Alpes",
country: "France",
type: "",
timezone: "Europe/Dublin",
});
describe("AddressInfo", () => {
it("Show Basic", async () => {
const wrapper = generateWrapper({
address: address,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Basic with timezone", async () => {
const wrapper = generateWrapper({
address: address,
showTimezone: true,
userTimezone: "Europe/Berlin",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,71 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import { IAddress } from "@/types/address.model";
import { reactive } from "vue";
import InlineAddress from "@/components/Address/InlineAddress.vue";
const address = reactive<IAddress>({
description: "Locaux Motiv",
street: "10 Rue Jangot",
locality: "Lyon",
postalCode: "69007",
region: "Auvergne Rhône-Alpes",
country: "France",
type: "",
timezone: "Europe/Dublin",
});
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any = {}) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(InlineAddress, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("InlineAddress", () => {
it("Show with locality", async () => {
const wrapper = generateWrapper({
physicalAddress: address,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show without locality", async () => {
const wrapper = generateWrapper({
physicalAddress: { ...address, locality: null },
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`AddressInfo > Show Basic 1`] = `
"<address data-v-f169049d="" dir="auto">
<!--v-if-->
<p data-v-f169049d=""><span data-v-f169049d="" class="addressDescription" title="Locaux Motiv">Locaux Motiv</span><br data-v-f169049d=""><span data-v-f169049d="">10 Rue Jangot, 69007, Lyon</span><br data-v-f169049d="">
<!--v-if-->
</p>
</address>"
`;
exports[`AddressInfo > Show Basic with timezone 1`] = `
"<address data-v-f169049d="" dir="auto">
<!--v-if-->
<p data-v-f169049d=""><span data-v-f169049d="" class="addressDescription" title="Locaux Motiv">Locaux Motiv</span><br data-v-f169049d=""><span data-v-f169049d="">10 Rue Jangot, 69007, Lyon</span><br data-v-f169049d=""><small data-v-f169049d=""> 🌐 heure moyenne de Greenwich (UTC)</small></p>
</address>"
`;

View File

@@ -0,0 +1,5 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`InlineAddress > Show with locality 1`] = `"<div class="truncate flex gap-1" dir="auto" title="Locaux Motiv, Lyon"><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Lyon</span></div>"`;
exports[`InlineAddress > Show without locality 1`] = `"<div class="truncate flex gap-1" dir="auto" title="Locaux Motiv, null"><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Locaux Motiv</span></div>"`;

View File

@@ -0,0 +1,67 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import CategoryCard from "@/components/Categories/CategoryCard.vue";
import { CategoryStatsModel } from "@/types/stats.model";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(CategoryCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const category = reactive<CategoryStatsModel>({
key: "PHOTOGRAPHY",
number: 5,
label: "Hello",
});
describe("CategoryCard", () => {
it("Show Basic", async () => {
const wrapper = generateWrapper({
category: category,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Details", async () => {
const wrapper = generateWrapper({
category: { ...category, key: "OUTDOORS_ADVENTURE" },
withDetails: true,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,26 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`CategoryCard > Show Basic 1`] = `
"<a href="/search?categoryOneOf=PHOTOGRAPHY&amp;contentType=EVENTS" class="max-w-xs rounded-lg overflow-hidden bg-center bg-no-repeat bg-cover shadow-lg relative group">
<picture class="brightness-50">
<source srcset="/img/categories/photography.webp 2x, /img/categories/photography.webp" media="(min-width: 1000px)">
<source srcset="/img/categories/photography.webp 2x, /img/categories/photography-small.webp" media="(min-width: 300px)"><img class="w-full h-36 w-36 md:h-52 md:w-52 object-cover" src="/img/categories/photography.webp" srcset="/img/categories/photography-small.webp " width="384" height="384" alt="" loading="lazy">
</picture>
<div class="px-3 py-1 absolute left-0 bottom-0">
<h2 class="group-hover:text-slate-200 font-semibold text-white tracking-tight text-xl mb-3">Hello</h2>
</div>
<!--v-if-->
</a>"
`;
exports[`CategoryCard > Show Details 1`] = `
"<a href="/search?categoryOneOf=OUTDOORS_ADVENTURE&amp;contentType=EVENTS" class="max-w-xs rounded-lg overflow-hidden bg-center bg-no-repeat bg-cover shadow-lg relative group">
<picture class="brightness-50">
<source srcset="/img/categories/outdoors_adventure.webp 2x, /img/categories/outdoors_adventure.webp" media="(min-width: 1000px)">
<source srcset="/img/categories/outdoors_adventure.webp 2x, /img/categories/outdoors_adventure-small.webp" media="(min-width: 300px)"><img class="w-full h-36 w-36 md:h-52 md:w-52 object-cover" src="/img/categories/outdoors_adventure.webp" srcset="/img/categories/outdoors_adventure-small.webp " width="384" height="384" alt="" loading="lazy">
</picture>
<div class="px-3 py-1 absolute left-0 bottom-0">
<h2 class="group-hover:text-slate-200 font-semibold text-white tracking-tight text-xl mb-3">Hello</h2>
</div><span class="absolute z-10 inline-flex items-center px-3 py-1 text-xs font-semibold text-white bg-black rounded-full right-2 top-2">5 events</span>
</a>"
`;

View File

@@ -1,28 +1,13 @@
<template> import { beforeEach, describe, it, expect } from "vitest";
<Story :setup-app="setupApp"> import { enUS } from "date-fns/locale";
<Variant title="Basic"> import { routes } from "@/router";
<Comment import { createRouter, createWebHistory, Router } from "vue-router";
:comment="comment" import { config, mount } from "@vue/test-utils";
:event="event" import { Oruga } from "@oruga-ui/oruga-next";
:currentActor="baseActor" import flushPromises from "flush-promises";
@create-comment="logEvent('Create comment', $event)" import { getMockClient } from "../../mocks/client";
@delete-comment="logEvent('Delete comment', $event)" import { htmlRemoveId } from "../../common";
@report-comment="logEvent('Report comment', $event)" import EventComment from "@/components/Comment/EventComment.vue";
/>
</Variant>
<Variant title="Announcement">
<Comment
:comment="{ ...comment, isAnnouncement: true }"
:event="event"
:currentActor="baseActor"
@create-comment="logEvent('Create comment', $event)"
@delete-comment="logEvent('Delete comment', $event)"
@report-comment="logEvent('Report comment', $event)"
/>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IPerson } from "@/types/actor"; import { IPerson } from "@/types/actor";
import { IComment } from "@/types/comment.model"; import { IComment } from "@/types/comment.model";
import { import {
@@ -34,27 +19,19 @@ import {
} from "@/types/enums"; } from "@/types/enums";
import { IEvent } from "@/types/event.model"; import { IEvent } from "@/types/event.model";
import { reactive } from "vue"; import { reactive } from "vue";
import Comment from "./EventComment.vue";
import FloatingVue from "floating-vue";
import "floating-vue/dist/style.css";
import { logEvent } from "histoire/client";
import { createMemoryHistory, createRouter } from "vue-router";
function setupApp({ app }) { config.global.plugins.push(Oruga);
app.use(FloatingVue);
app.use( let router: Router;
createRouter({
history: createMemoryHistory(), beforeEach(async () => {
routes: [ router = createRouter({
{ history: createWebHistory(),
path: "/event/:uuid", routes: routes,
name: "Event", });
component: { render: () => null },
}, // await router.isReady();
], });
})
);
}
const baseActorAvatar = { const baseActorAvatar = {
id: "", id: "",
@@ -187,4 +164,41 @@ const comment = reactive<IComment>({
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
url: "http://somewhere.tld", url: "http://somewhere.tld",
}); });
</script>
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(EventComment, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("EventComment", () => {
it("Show Basic", async () => {
const wrapper = generateWrapper({
comment: comment,
event: event,
currentActor: baseActor,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Announcement", async () => {
const wrapper = generateWrapper({
comment: { ...comment, isAnnouncement: true },
event: event,
currentActor: baseActor,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,177 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`EventComment > Show Announcement 1`] = `
"<li class="bg-white dark:bg-zinc-800 rounded p-2 bg-mbz-purple-50 dark:bg-mbz-purple-500">
<article id="comment-undefined" dir="auto" class="mbz-comment">
<div>
<div class="flex items-center gap-2">
<div class="flex items-center gap-1">
<vmenu distance="16" triggers="hover" class="popover inline">
<figure><img class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="24" height="24"></figure>
</vmenu><strong dir="auto" class="organizer">Thomas Citharel</strong>
</div><a href="/events/an-uuid#comment-undefined"><small>in over 3 years</small></a>
</div>
<div dir="auto" class="prose dark:prose-invert xl:prose-lg !max-w-full text-black dark:text-white">hello</div>
<nav class="flex gap-1 mt-1"><button class="cursor-pointer flex hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon reply-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10,9V5L3,12L10,19V14.9C15,14.9 18.5,16.5 21,20C20,15 17,10 10,9Z"><!--v-if--></path></svg></span><span>Reply</span></button>
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button class="cursor-pointer flex hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon dots-horizontal-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span><span class="sr-only">More options</span></button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item"><button class="flex items-center gap-1"><span aria-hidden="true" class="material-design-icon delete-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="16" height="16" viewBox="0 0 24 24"><path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"><!--v-if--></path></svg></span><span>Delete</span></button></div>
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item"><button class="flex items-center gap-1"><span aria-hidden="true" class="material-design-icon alert-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="16" height="16" viewBox="0 0 24 24"><path d="M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z"><!--v-if--></path></svg></span><span>Report</span></button></div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</nav>
<div class=""><button class="flex cursor-pointer hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon chevron-down-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"><!--v-if--></path></svg></span><span>View a reply</span></button></div>
</div>
</article>
<form style="display: none;">
<article class="flex gap-2">
<figure class="mt-4"><img src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="48" height="48" class="rounded-md"></figure>
<div class="flex-1">
<div class="flex gap-1 items-center"><strong>Thomas Citharel</strong><small dir="ltr">@tcit</small></div>
<div class="flex flex-col gap-2">
<!----><button disabled="" type="submit" class="o-btn o-btn--primary o-btn--disabled self-end" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Post a reply</span>
<!----></span>
</button>
</div>
</div>
</article>
</form>
<!--v-if-->
<!--teleport start-->
<transition-stub name="zoom-out" appear="false" persisted="false" css="true">
<div has-modal-card="" close-button-aria-label="Close" data-oruga="modal" class="o-modal" tabindex="-1" aria-modal="false" style="display: none;">
<div class="o-modal__overlay" tabindex="-1" aria-hidden="true"></div>
<div class="o-modal__content" style="max-width: 960px;">
<div data-v-e0cceef3="" class="p-2">
<header data-v-e0cceef3="" class="mb-3">
<h2 data-v-e0cceef3="" class="text-2xl">Report this comment</h2>
</header>
<section data-v-e0cceef3="">
<div data-v-e0cceef3="" class="flex gap-1 flex-row mb-3 bg-mbz-yellow dark:text-black p-3 rounded items-center"><span data-v-e0cceef3="" class="o-icon o-icon--warning hidden md:block flex-1" data-oruga="icon"><i class="mdi mdi-alert 48"></i></span>
<p data-v-e0cceef3="">The report will be sent to the moderators of your instance. You can explain why you report this content below.</p>
</div>
<div data-v-e0cceef3="">
<!--v-if-->
<div data-v-e0cceef3="" data-oruga="field" class="o-field"><label for="additional-comments" class="o-field__label">Additional comments</label>
<div class="o-field__body">
<div class="o-field o-field--addons">
<div data-v-e0cceef3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><textarea autofocus="" id="additional-comments" data-oruga-input="textarea" class="o-input o-input__textarea"></textarea>
<!---->
<!---->
<!---->
</div>
</div>
</div>
<!---->
</div>
<!--v-if-->
</div>
</section>
<footer data-v-e0cceef3="" class="flex gap-2 py-3"><button data-v-e0cceef3="" type="button" class="o-btn o-btn--outlined" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Cancel</span>
<!----></span>
</button><button data-v-e0cceef3="" type="button" class="o-btn o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Send the report</span>
<!----></span>
</button></footer>
</div><span class="o-icon o-icon--clickable o-icon--medium o-modal__close" data-oruga="icon" style="display: none;"><i class="mdi mdi-close mdi-36px"></i></span>
</div>
</div>
</transition-stub>
<!--teleport end-->
</li>"
`;
exports[`EventComment > Show Basic 1`] = `
"<li class="bg-white dark:bg-zinc-800 rounded p-2">
<article id="comment-undefined" dir="auto" class="mbz-comment">
<div>
<div class="flex items-center gap-2">
<div class="flex items-center gap-1">
<vmenu distance="16" triggers="hover" class="popover inline">
<figure><img class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="24" height="24"></figure>
</vmenu><strong dir="auto" class="organizer">Thomas Citharel</strong>
</div><a href="/events/an-uuid#comment-undefined"><small>in over 3 years</small></a>
</div>
<div dir="auto" class="prose dark:prose-invert xl:prose-lg !max-w-full">hello</div>
<nav class="flex gap-1 mt-1"><button class="cursor-pointer flex hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon reply-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10,9V5L3,12L10,19V14.9C15,14.9 18.5,16.5 21,20C20,15 17,10 10,9Z"><!--v-if--></path></svg></span><span>Reply</span></button>
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button class="cursor-pointer flex hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon dots-horizontal-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span><span class="sr-only">More options</span></button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item"><button class="flex items-center gap-1"><span aria-hidden="true" class="material-design-icon delete-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="16" height="16" viewBox="0 0 24 24"><path d="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"><!--v-if--></path></svg></span><span>Delete</span></button></div>
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item"><button class="flex items-center gap-1"><span aria-hidden="true" class="material-design-icon alert-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="16" height="16" viewBox="0 0 24 24"><path d="M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z"><!--v-if--></path></svg></span><span>Report</span></button></div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</nav>
<div class=""><button class="flex cursor-pointer hover:bg-zinc-300 dark:hover:bg-zinc-600 rounded p-1"><span aria-hidden="true" class="material-design-icon chevron-down-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"><!--v-if--></path></svg></span><span>View a reply</span></button></div>
</div>
</article>
<form style="display: none;">
<article class="flex gap-2">
<figure class="mt-4"><img src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="48" height="48" class="rounded-md"></figure>
<div class="flex-1">
<div class="flex gap-1 items-center"><strong>Thomas Citharel</strong><small dir="ltr">@tcit</small></div>
<div class="flex flex-col gap-2">
<!----><button disabled="" type="submit" class="o-btn o-btn--primary o-btn--disabled self-end" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Post a reply</span>
<!----></span>
</button>
</div>
</div>
</article>
</form>
<!--v-if-->
<!--teleport start-->
<transition-stub name="zoom-out" appear="false" persisted="false" css="true">
<div has-modal-card="" close-button-aria-label="Close" data-oruga="modal" class="o-modal" tabindex="-1" aria-modal="false" style="display: none;">
<div class="o-modal__overlay" tabindex="-1" aria-hidden="true"></div>
<div class="o-modal__content" style="max-width: 960px;">
<div data-v-e0cceef3="" class="p-2">
<header data-v-e0cceef3="" class="mb-3">
<h2 data-v-e0cceef3="" class="text-2xl">Report this comment</h2>
</header>
<section data-v-e0cceef3="">
<div data-v-e0cceef3="" class="flex gap-1 flex-row mb-3 bg-mbz-yellow dark:text-black p-3 rounded items-center"><span data-v-e0cceef3="" class="o-icon o-icon--warning hidden md:block flex-1" data-oruga="icon"><i class="mdi mdi-alert 48"></i></span>
<p data-v-e0cceef3="">The report will be sent to the moderators of your instance. You can explain why you report this content below.</p>
</div>
<div data-v-e0cceef3="">
<!--v-if-->
<div data-v-e0cceef3="" data-oruga="field" class="o-field"><label for="additional-comments" class="o-field__label">Additional comments</label>
<div class="o-field__body">
<div class="o-field o-field--addons">
<div data-v-e0cceef3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><textarea autofocus="" id="additional-comments" data-oruga-input="textarea" class="o-input o-input__textarea"></textarea>
<!---->
<!---->
<!---->
</div>
</div>
</div>
<!---->
</div>
<!--v-if-->
</div>
</section>
<footer data-v-e0cceef3="" class="flex gap-2 py-3"><button data-v-e0cceef3="" type="button" class="o-btn o-btn--outlined" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Cancel</span>
<!----></span>
</button><button data-v-e0cceef3="" type="button" class="o-btn o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Send the report</span>
<!----></span>
</button></footer>
</div><span class="o-icon o-icon--clickable o-icon--medium o-modal__close" data-oruga="icon" style="display: none;"><i class="mdi mdi-close mdi-36px"></i></span>
</div>
</div>
</transition-stub>
<!--teleport end-->
</li>"
`;

View File

@@ -0,0 +1,96 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import DiscussionComment from "@/components/Discussion/DiscussionComment.vue";
import { IPerson } from "@/types/actor";
import { IComment } from "@/types/comment.model";
import { ActorType } from "@/types/enums";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const baseActor: IPerson = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
type: ActorType.PERSON,
id: "598",
};
const comment = reactive<IComment>({
text: "Hello there",
publishedAt: new Date().toString(),
actor: baseActor,
});
const deletedComment = reactive<IComment>({
...comment,
actor: null,
deletedAt: new Date().toString(),
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(DiscussionComment, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("DiscussionComment", () => {
it("Show Basic", async () => {
const wrapper = generateWrapper({
modelValue: comment,
currentActor: baseActor,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Deleted comment", async () => {
const wrapper = generateWrapper({
modelValue: deletedComment,
currentActor: baseActor,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,60 @@
import { describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import DiscussionListItem from "@/components/Discussion/DiscussionListItem.vue";
import { IDiscussion } from "@/types/discussions";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [];
return mount(DiscussionListItem, {
props: props,
global: {
...global_data,
},
});
};
const mockdiscussion = reactive<IDiscussion>({
title: "A discussion",
comments: { total: 5, elements: [] },
insertedAt: "2022-02-02T02:04:00.000Z",
updatedAt: "2022-02-04T02:04:00.000Z",
deletedAt: null,
lastComment: { text: "Hello there", publishedAt: new Date().toString() },
});
const mockdiscussionWithDeletedComment = reactive<IDiscussion>({
...mockdiscussion,
lastComment: {
...mockdiscussion.lastComment,
deletedAt: "2022-02-06T02:04:00.000Z",
},
});
describe("DiscussionListItem", () => {
it("Show Basic", async () => {
const wrapper = generateWrapper({
discussion: mockdiscussion,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Deleted comment", async () => {
const wrapper = generateWrapper({
discussion: mockdiscussion,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,130 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`DiscussionComment > Show Basic 1`] = `
"<article data-v-49696bef="" class="flex gap-2 bg-white dark:bg-transparent border rounded-md p-2 mt-2">
<div data-v-49696bef="" class="">
<figure data-v-49696bef="" class=""><img data-v-49696bef="" class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="48" height="48"></figure>
</div>
<div data-v-49696bef="" class="mb-2 pt-1 flex-1">
<div data-v-49696bef="" class="flex items-center gap-1" dir="auto">
<div data-v-49696bef="" class="flex flex-1 flex-col"><strong data-v-49696bef="">Thomas Citharel</strong><small data-v-49696bef="">@tcit</small></div><span data-v-49696bef="" class="icons"><div data-v-49696bef="" data-oruga="dropdown" class="o-drop o-drop--position-bottom-left"><div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><span data-v-49696bef="" class="cursor-pointer material-design-icon dots-horizontal-icon cursor-pointer" aria-hidden="true" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span>
</div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div data-v-49696bef="" class="o-drop__item o-drop__item--clickable" role="menuitem" tabindex="0" data-oruga="dropdown-item"><span data-v-49696bef="" class="o-icon" data-oruga="icon"><i class="mdi mdi-pencil mdi-24px"></i></span> Edit</div>
<div data-v-49696bef="" class="o-drop__item o-drop__item--clickable" role="menuitem" tabindex="0" data-oruga="dropdown-item"><span data-v-49696bef="" class="o-icon" data-oruga="icon"><i class="mdi mdi-delete mdi-24px"></i></span> Delete</div>
<!--v-if-->
</div>
</transition-stub>
<!--teleport end-->
</div></span>
<div data-v-49696bef="" class="self-center">
<!--v-if-->
</div>
</div>
<div data-v-49696bef="" class="text-wrapper" dir="auto">
<div data-v-49696bef="" class="prose md:prose-lg lg:prose-xl dark:prose-invert">Hello there</div>
<!--v-if-->
</div>
</div>
</article>
<!--teleport start-->
<transition-stub name="zoom-out" appear="false" persisted="false" css="true">
<div has-modal-card="" close-button-aria-label="Close" data-oruga="modal" class="o-modal" tabindex="-1" aria-modal="false" style="display: none;">
<div class="o-modal__overlay" tabindex="-1" aria-hidden="true"></div>
<div class="o-modal__content" style="max-width: 960px;">
<div data-v-e0cceef3="" data-v-49696bef="" class="p-2">
<header data-v-e0cceef3="" class="mb-3">
<h2 data-v-e0cceef3="" class="text-2xl">Report this comment</h2>
</header>
<section data-v-e0cceef3="">
<div data-v-e0cceef3="" class="flex gap-1 flex-row mb-3 bg-mbz-yellow dark:text-black p-3 rounded items-center"><span data-v-e0cceef3="" class="o-icon o-icon--warning hidden md:block flex-1" data-oruga="icon"><i class="mdi mdi-alert 48"></i></span>
<p data-v-e0cceef3="">The report will be sent to the moderators of your instance. You can explain why you report this content below.</p>
</div>
<div data-v-e0cceef3="">
<!--v-if-->
<div data-v-e0cceef3="" data-oruga="field" class="o-field"><label for="additional-comments" class="o-field__label">Additional comments</label>
<div class="o-field__body">
<div class="o-field o-field--addons">
<div data-v-e0cceef3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><textarea autofocus="" id="additional-comments" data-oruga-input="textarea" class="o-input o-input__textarea"></textarea>
<!---->
<!---->
<!---->
</div>
</div>
</div>
<!---->
</div>
<!--v-if-->
</div>
</section>
<footer data-v-e0cceef3="" class="flex gap-2 py-3"><button data-v-e0cceef3="" type="button" class="o-btn o-btn--outlined" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Cancel</span>
<!----></span>
</button><button data-v-e0cceef3="" type="button" class="o-btn o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Send the report</span>
<!----></span>
</button></footer>
</div><span class="o-icon o-icon--clickable o-icon--medium o-modal__close" data-oruga="icon" style="display: none;"><i class="mdi mdi-close mdi-36px"></i></span>
</div>
</div>
</transition-stub>
<!--teleport end-->"
`;
exports[`DiscussionComment > Show Deleted comment 1`] = `
"<article data-v-49696bef="" class="flex gap-2 bg-white dark:bg-transparent border rounded-md p-2 mt-2">
<div data-v-49696bef="" class=""><span data-v-49696bef="" aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div data-v-49696bef="" class="mb-2 pt-1 flex-1">
<div data-v-49696bef="" class="flex items-center gap-1" dir="auto"><span data-v-49696bef="" class="name comment-link has-text-grey">[deleted]</span>
<!--v-if-->
<div data-v-49696bef="" class="self-center">
<!--v-if-->
</div>
</div>
<div data-v-49696bef="" class="comment-deleted">[This comment has been deleted by it's author]</div>
</div>
</article>
<!--teleport start-->
<transition-stub name="zoom-out" appear="false" persisted="false" css="true">
<div has-modal-card="" close-button-aria-label="Close" data-oruga="modal" class="o-modal" tabindex="-1" aria-modal="false" style="display: none;">
<div class="o-modal__overlay" tabindex="-1" aria-hidden="true"></div>
<div class="o-modal__content" style="max-width: 960px;">
<div data-v-e0cceef3="" data-v-49696bef="" class="p-2">
<header data-v-e0cceef3="" class="mb-3">
<h2 data-v-e0cceef3="" class="text-2xl">Report this comment</h2>
</header>
<section data-v-e0cceef3="">
<div data-v-e0cceef3="" class="flex gap-1 flex-row mb-3 bg-mbz-yellow dark:text-black p-3 rounded items-center"><span data-v-e0cceef3="" class="o-icon o-icon--warning hidden md:block flex-1" data-oruga="icon"><i class="mdi mdi-alert 48"></i></span>
<p data-v-e0cceef3="">The report will be sent to the moderators of your instance. You can explain why you report this content below.</p>
</div>
<div data-v-e0cceef3="">
<!--v-if-->
<div data-v-e0cceef3="" data-oruga="field" class="o-field"><label for="additional-comments" class="o-field__label">Additional comments</label>
<div class="o-field__body">
<div class="o-field o-field--addons">
<div data-v-e0cceef3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><textarea autofocus="" id="additional-comments" data-oruga-input="textarea" class="o-input o-input__textarea"></textarea>
<!---->
<!---->
<!---->
</div>
</div>
</div>
<!---->
</div>
<!--v-if-->
</div>
</section>
<footer data-v-e0cceef3="" class="flex gap-2 py-3"><button data-v-e0cceef3="" type="button" class="o-btn o-btn--outlined" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Cancel</span>
<!----></span>
</button><button data-v-e0cceef3="" type="button" class="o-btn o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Send the report</span>
<!----></span>
</button></footer>
</div><span class="o-icon o-icon--clickable o-icon--medium o-modal__close" data-oruga="icon" style="display: none;"><i class="mdi mdi-close mdi-36px"></i></span>
</div>
</div>
</transition-stub>
<!--teleport end-->"
`;

View File

@@ -0,0 +1,25 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`DiscussionListItem > Show Basic 1`] = `
"<router-link class="flex gap-1 w-full items-center p-2 border-b-stone-200 border-b bg-white dark:bg-transparent" dir="auto" to="[object Object]">
<div class=""><span aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="32" height="32" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div class="flex-1">
<div class="flex items-center">
<p class="text-violet-3 dark:text-white text-lg font-semibold flex-1">A discussion</p><span class="" title="Friday, February 4, 2022 at 3:04 AM">2 days</span>
</div>
<div class="line-clamp-2" dir="auto"></div>
</div>
</router-link>"
`;
exports[`DiscussionListItem > Show Deleted comment 1`] = `
"<router-link class="flex gap-1 w-full items-center p-2 border-b-stone-200 border-b bg-white dark:bg-transparent" dir="auto" to="[object Object]">
<div class=""><span aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="32" height="32" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div class="flex-1">
<div class="flex items-center">
<p class="text-violet-3 dark:text-white text-lg font-semibold flex-1">A discussion</p><span class="" title="Friday, February 4, 2022 at 3:04 AM">2 days</span>
</div>
<div class="line-clamp-2" dir="auto"></div>
</div>
</router-link>"
`;

View File

@@ -0,0 +1,59 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import DateCalendarIcon from "@/components/Event/DateCalendarIcon.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(DateCalendarIcon, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("DateCalendarIcon", () => {
it("Show new", async () => {
const wrapper = generateWrapper({
date: new Date().toString(),
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show small", async () => {
const wrapper = generateWrapper({
date: new Date().toString(),
small: true,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -1,26 +1,13 @@
<template> import { beforeEach, describe, it, expect, vi } from "vitest";
<Story title="EventCard"> import { enUS } from "date-fns/locale";
<Variant title="default"> import { routes } from "@/router";
<EventCard :event="event" /> import { createRouter, createWebHistory, Router } from "vue-router";
</Variant> import { config, mount } from "@vue/test-utils";
<Variant title="long"> import { Oruga } from "@oruga-ui/oruga-next";
<EventCard :event="longEvent" /> import flushPromises from "flush-promises";
</Variant> import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
<Variant title="tentative"> import EventCard from "@/components/Event/EventCard.vue";
<EventCard :event="tentativeEvent" />
</Variant>
<Variant title="cancelled">
<EventCard :event="cancelledEvent" />
</Variant>
<Variant title="Row mode">
<EventCard :event="longEvent" mode="row" />
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { IActor } from "@/types/actor"; import { IActor } from "@/types/actor";
import { import {
ActorType, ActorType,
@@ -31,7 +18,44 @@ import {
} from "@/types/enums"; } from "@/types/enums";
import { IEvent } from "@/types/event.model"; import { IEvent } from "@/types/event.model";
import { reactive } from "vue"; import { reactive } from "vue";
import EventCard from "./EventCard.vue";
config.global.plugins.push(Oruga);
let router: Router;
class MockIntersectionObserver implements IntersectionObserver {
root: Document | Element | null = null;
rootMargin: string = ``;
thresholds: readonly number[] = [];
disconnect = vi.fn();
observe = vi.fn();
takeRecords = vi.fn();
unobserve = vi.fn();
}
window.IntersectionObserver = MockIntersectionObserver;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(EventCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const baseActorAvatar = { const baseActorAvatar = {
id: "", id: "",
@@ -53,11 +77,11 @@ const baseActor: IActor = {
}; };
const baseEvent: IEvent = { const baseEvent: IEvent = {
uuid: "", uuid: "0123456789",
title: "A very interesting event", title: "A very interesting event",
description: "Things happen", description: "Things happen",
beginsOn: new Date().toISOString(), beginsOn: "2022-02-02T02:04:00.000Z",
endsOn: new Date().toISOString(), endsOn: "2022-02-02T02:04:00.000Z",
physicalAddress: { physicalAddress: {
description: "Somewhere", description: "Somewhere",
street: "", street: "",
@@ -145,4 +169,51 @@ const cancelledEvent = reactive<IEvent>({
...baseEvent, ...baseEvent,
status: EventStatus.CANCELLED, status: EventStatus.CANCELLED,
}); });
</script>
describe("EventCard", () => {
it("Show default", async () => {
const wrapper = generateWrapper({
event: event,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show long", async () => {
const wrapper = generateWrapper({
event: longEvent,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show tentative", async () => {
const wrapper = generateWrapper({
event: tentativeEvent,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show cancelled", async () => {
const wrapper = generateWrapper({
event: cancelledEvent,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Row mode", async () => {
const wrapper = generateWrapper({
event: longEvent,
mode: "row",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -1,23 +1,13 @@
<template> import { beforeEach, describe, it, expect } from "vitest";
<Story title="EventListViewCard"> import { enUS } from "date-fns/locale";
<Variant title="default"> import { routes } from "@/router";
<EventListViewCard :event="baseEvent" /> import { createRouter, createWebHistory, Router } from "vue-router";
</Variant> import { config, mount } from "@vue/test-utils";
<Variant title="long"> import { Oruga } from "@oruga-ui/oruga-next";
<EventListViewCard :event="longEvent" /> import flushPromises from "flush-promises";
</Variant> import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
<!-- <Variant title="tentative"> import EventListViewCard from "@/components/Event/EventListViewCard.vue";
<EventListViewCard :event="tentativeEvent" />
</Variant>
<Variant title="cancelled">
<EventListViewCard :event="cancelledEvent" />
</Variant> -->
</Story>
</template>
<script lang="ts" setup>
import { IActor } from "@/types/actor"; import { IActor } from "@/types/actor";
import { import {
ActorType, ActorType,
@@ -28,7 +18,34 @@ import {
} from "@/types/enums"; } from "@/types/enums";
import { IEvent } from "@/types/event.model"; import { IEvent } from "@/types/event.model";
import { reactive } from "vue"; import { reactive } from "vue";
import EventListViewCard from "./EventListViewCard.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(EventListViewCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const baseActorAvatar = { const baseActorAvatar = {
id: "", id: "",
@@ -50,11 +67,11 @@ const baseActor: IActor = {
}; };
const baseEvent: IEvent = { const baseEvent: IEvent = {
uuid: "", uuid: "0123456789",
title: "A very interesting event", title: "A very interesting event",
description: "Things happen", description: "Things happen",
beginsOn: new Date().toISOString(), beginsOn: "2022-02-02T02:04:00.000Z",
endsOn: new Date().toISOString(), endsOn: "2022-02-04T02:04:00.000Z",
physicalAddress: { physicalAddress: {
description: "Somewhere", description: "Somewhere",
street: "", street: "",
@@ -74,7 +91,7 @@ const baseEvent: IEvent = {
url: "", url: "",
local: true, local: true,
slug: "", slug: "",
publishAt: new Date().toISOString(), publishAt: "2022-02-02T02:04:00.000Z",
status: EventStatus.CONFIRMED, status: EventStatus.CONFIRMED,
visibility: EventVisibility.PUBLIC, visibility: EventVisibility.PUBLIC,
joinOptions: EventJoinOptions.FREE, joinOptions: EventJoinOptions.FREE,
@@ -131,13 +148,22 @@ const longEvent = reactive<IEvent>({
"A very long title that will have trouble to display because it will take multiple lines but where will it stop ?! Maybe after 3 lines is enough. Let's say so.", "A very long title that will have trouble to display because it will take multiple lines but where will it stop ?! Maybe after 3 lines is enough. Let's say so.",
}); });
// const tentativeEvent = reactive<IEvent>({ describe("EventListViewCard", () => {
// ...baseEvent, it("Show default", async () => {
// status: EventStatus.TENTATIVE, const wrapper = generateWrapper({
// }); event: baseEvent,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
// const cancelledEvent = reactive<IEvent>({ it("Show long", async () => {
// ...baseEvent, const wrapper = generateWrapper({
// status: EventStatus.CANCELLED, event: longEvent,
// }); });
</script> await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,78 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import OrganizerPicker from "@/components/Event/OrganizerPicker.vue";
import { reactive, ref } from "vue";
import { ActorType } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const currentActor = reactive({
id: "59",
preferredUsername: "me",
name: "Someone",
type: ActorType.PERSON,
});
const actor = reactive({
id: "5",
preferredUsername: "hello",
name: "Sigmund",
type: ActorType.PERSON,
});
const group = reactive({
id: "89",
preferredUsername: "congregation",
name: "College",
type: ActorType.GROUP,
});
const identities = [actor, group];
const generateWrapper = () => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(OrganizerPicker, {
props: {
modelValue: actor,
identities: identities,
actorFilter: "",
groupMemberships: [],
currentActor: currentActor,
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("OrganizerPicker", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,73 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import OrganizerPickerWrapper from "@/components/Event/OrganizerPickerWrapper.vue";
import { PERSON_GROUP_MEMBERSHIPS } from "@/graphql/actor";
import { IDENTITIES } from "@/graphql/actor";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const mock_person = {
data: {
person: { id: "5", memberships: { total: 0, elements: [] } },
},
};
const mock_loggeduser = {
data: {
loggedUser: {
actors: [{ id: "9", preferredUsername: "sam", name: "Samuel" }],
},
},
};
const generateWrapper = () => {
const global_data = getMockClient([
[PERSON_GROUP_MEMBERSHIPS, mock_person],
[IDENTITIES, mock_loggeduser],
]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(OrganizerPickerWrapper, {
props: {
modelValue: {
id: "5",
preferredUsername: "hello",
name: "Sigmund",
},
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("OrganizerPickerWrapper", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
expect(requestHandlers.handle_0).toHaveBeenCalledTimes(0);
expect(requestHandlers.handle_1).toHaveBeenCalledTimes(0);
});
});

View File

@@ -0,0 +1,160 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import ParticipationButton from "@/components/Event/ParticipationButton.vue";
import { IPerson } from "@/types/actor";
import { EventJoinOptions, ParticipantRole } from "@/types/enums";
import { IEvent } from "@/types/event.model";
import { IParticipant } from "@/types/participant.model";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(ParticipationButton, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const emptyCurrentActor: IPerson = {};
const currentActor: IPerson = {
id: "1",
preferredUsername: "tcit",
name: "Thomas",
avatar: {
url: "https://mobilizon.fr/media/3a5f18c058a8193b1febfaf561f94ae8b91f85ac64c01ddf5ad7b251fb43baf5.jpg?name=profil.jpg",
},
};
const participation: IParticipant = {
actor: currentActor,
role: ParticipantRole.PARTICIPANT,
};
const identities: IPerson[] = [
currentActor,
{
id: "2",
preferredUsername: "another",
name: "Another",
avatar: {
url: "https://mobilizon.fr/media/95ab5ba92287ab4857bb517cadae2a7ab6a553748d1c48cefc27e2b7ab640fea.jpg?name=FB_IMG_16150214351371162.jpg",
},
},
];
const event: IEvent = {
uuid: "0123456789",
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
options: {
anonymousParticipation: false,
},
joinOptions: EventJoinOptions.FREE,
};
describe("ParticipationButton", () => {
it("Show Unlogged", async () => {
const wrapper = generateWrapper({
event: event,
currentActor: emptyCurrentActor,
participation: undefined,
identities: [],
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Basic", async () => {
const wrapper = generateWrapper({
event: event,
currentActor: currentActor,
participation: undefined,
identities: identities,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Basic with confirmation", async () => {
const wrapper = generateWrapper({
event: { ...event, joinOptions: EventJoinOptions.RESTRICTED },
currentActor: currentActor,
participation: undefined,
identities: identities,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Participating", async () => {
const wrapper = generateWrapper({
event: event,
currentActor: currentActor,
participation: participation,
identities: identities,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Pending approval", async () => {
const wrapper = generateWrapper({
event: event,
currentActor: currentActor,
participation: {
...participation,
role: ParticipantRole.NOT_APPROVED,
},
identities: identities,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Rejected", async () => {
const wrapper = generateWrapper({
event: event,
currentActor: currentActor,
participation: {
...participation,
role: ParticipantRole.REJECTED,
},
identities: identities,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,92 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import ShareEventModal from "@/components/Event/ShareEventModal.vue";
import { EventVisibility, EventStatus } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (event: any, eventCapacityOK: boolean = true) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(ShareEventModal, {
props: {
event: event,
eventCapacityOK: eventCapacityOK,
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("ShareEventModal", () => {
it("Show Public", async () => {
const wrapper = generateWrapper({
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
visibility: EventVisibility.PUBLIC,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Private", async () => {
const wrapper = generateWrapper({
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
visibility: EventVisibility.PRIVATE,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Cancelled", async () => {
const wrapper = generateWrapper({
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
visibility: EventVisibility.PUBLIC,
status: EventStatus.CANCELLED,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show No seats left", async () => {
const wrapper = generateWrapper(
{
title: "hello",
url: "https://mobilizon.fr/events/an-uuid",
visibility: EventVisibility.PUBLIC,
},
false
);
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,65 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import SkeletonEventResult from "@/components/Event/SkeletonEventResult.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any = {}) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(SkeletonEventResult, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("SkeletonEventResult", () => {
it("Show row", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show column", async () => {
const wrapper = generateWrapper({
viewMode: "column",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show not minimal", async () => {
const wrapper = generateWrapper({
minimal: false,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,55 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import TagInput from "@/components/Event/TagInput.vue";
import { FILTER_TAGS } from "@/graphql/tags";
import { ITag } from "@/types/tag.model";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const tags = reactive<ITag[]>([{ title: "Hello", slug: "hello" }]);
const generateWrapper = () => {
const global_data = getMockClient([FILTER_TAGS]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(TagInput, {
props: {
modelValue: tags,
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("TagInput", () => {
it("Show new", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
expect(requestHandlers.handle_0).toHaveBeenCalledTimes(0);
});
});

View File

@@ -0,0 +1,17 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`DateCalendarIcon > Show new 1`] = `
"<div data-v-1df97f42="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white" style="--small: 2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>"
`;
exports[`DateCalendarIcon > Show small 1`] = `
"<div data-v-1df97f42="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>"
`;

View File

@@ -0,0 +1,252 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`EventCard > Show Row mode 1`] = `
"<a data-v-4bd07c72="" href="/events/0123456789" class="mbz-card snap-center dark:bg-mbz-purple sm:flex sm:items-start">
<div data-v-4bd07c72="" class="rounded-lg sm:w-full sm:max-w-[20rem]">
<div data-v-4bd07c72="" class="-mt-3 h-0 mb-3 ltr:ml-0 rtl:mr-0 block relative z-10 sm:hidden calendar-simple">
<div data-v-1df97f42="" data-v-4bd07c72="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
<!--v-if-->
<!--v-if-->
</div>
<figure data-v-4bd07c72="" class="block relative pt-40">
<div data-v-4bd07c72="" class="flex-1" style="height: 100%; position: absolute; top: 0px; left: 0px; width: 100%;">
<div class="h-full w-full max-w-100 min-h-[10rem]">
<!-- Show the placeholder as background -->
<!--v-if-->
<!-- Show the real image on the top and fade in after loading --><img class="transition-opacity duration-500 rounded-lg object-cover mx-auto h-full opacity-0" alt="" src="https://mobilizon.fr/media/81d9c76aaf740f84eefb28cf2b9988bdd2495ab1f3246159fd688e242155cb23.png?name=Screenshot_20220315_171848.png" loading="lazy">
</div>
</div>
<div data-v-4bd07c72="" class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end" style="display: none;">
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</figure>
</div>
<div data-v-4bd07c72="" class="p-2 flex-auto sm:flex-1">
<div data-v-4bd07c72="" class="relative flex flex-col h-full">
<div data-v-4bd07c72="" class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end sm:hidden">
<!--v-if-->
</div><span data-v-4bd07c72="" class="text-gray-700 dark:text-white font-semibold hidden sm:block">Feb 2, 2022, 3:04 AM</span>
<!--v-if-->
<div data-v-4bd07c72="" class="w-full flex flex-col justify-between h-full">
<h2 data-v-4bd07c72="" class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto" lang="en">A very long title that will have trouble to display because it will take multiple lines but where will it stop&nbsp;?! Maybe after 3 lines is enough. Let's say so. But if it doesn't work, we really need to truncate it at some point. Definitively.</h2>
<div data-v-4bd07c72="" class="">
<div data-v-4bd07c72="" class="flex items-center text-violet-3 dark:text-white" dir="auto">
<figure data-v-4bd07c72="" class=""><img data-v-4bd07c72="" class="rounded-xl" src="https://mobilizon.fr/media/653c2dcbb830636e0db975798163b85e038dfb7713e866e96d36bd411e105e3c.png?name=festivalsanantes%27s%20avatar.png" alt="" width="24" height="24" loading="lazy"></figure><span data-v-4bd07c72="" class="font-semibold ltr:pl-2 rtl:pr-2">Hello</span>
</div>
<div data-v-4bd07c72="" class="truncate flex gap-1" dir="auto" title="Somewhere, "><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Somewhere</span></div>
<div data-v-4bd07c72="" class="mt-1 no-underline gap-1 items-center hidden sm:flex">
<!--v-if-->
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</div>
</div>
</div>
</div>
</a>"
`;
exports[`EventCard > Show cancelled 1`] = `
"<a data-v-4bd07c72="" href="/events/0123456789" class="mbz-card snap-center dark:bg-mbz-purple sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div data-v-4bd07c72="" class="rounded-lg">
<div data-v-4bd07c72="" class="-mt-3 h-0 mb-3 ltr:ml-0 rtl:mr-0 block relative z-10 calendar-simple">
<div data-v-1df97f42="" data-v-4bd07c72="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
<!--v-if-->
<!--v-if-->
</div>
<figure data-v-4bd07c72="" class="block relative pt-40">
<div data-v-4bd07c72="" class="flex-1" style="height: 100%; position: absolute; top: 0px; left: 0px; width: 100%;">
<div class="h-full w-full max-w-100 min-h-[10rem]">
<!-- Show the placeholder as background -->
<!--v-if-->
<!-- Show the real image on the top and fade in after loading --><img class="transition-opacity duration-500 rounded-lg object-cover mx-auto h-full opacity-0" alt="" src="https://mobilizon.fr/media/81d9c76aaf740f84eefb28cf2b9988bdd2495ab1f3246159fd688e242155cb23.png?name=Screenshot_20220315_171848.png" loading="lazy">
</div>
</div>
<div data-v-4bd07c72="" class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end">
<!--v-if--><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-danger dark:text-white">Cancelled</span><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</figure>
</div>
<div data-v-4bd07c72="" class="p-2 flex-auto">
<div data-v-4bd07c72="" class="relative flex flex-col h-full">
<div data-v-4bd07c72="" class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end">
<!--v-if-->
</div><span data-v-4bd07c72="" class="text-gray-700 dark:text-white font-semibold hidden">Feb 2, 2022, 3:04 AM</span>
<!--v-if-->
<div data-v-4bd07c72="" class="w-full flex flex-col justify-between h-full">
<h2 data-v-4bd07c72="" class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto" lang="en">A very interesting event</h2>
<div data-v-4bd07c72="" class="">
<div data-v-4bd07c72="" class="flex items-center text-violet-3 dark:text-white" dir="auto">
<figure data-v-4bd07c72="" class=""><img data-v-4bd07c72="" class="rounded-xl" src="https://mobilizon.fr/media/653c2dcbb830636e0db975798163b85e038dfb7713e866e96d36bd411e105e3c.png?name=festivalsanantes%27s%20avatar.png" alt="" width="24" height="24" loading="lazy"></figure><span data-v-4bd07c72="" class="font-semibold ltr:pl-2 rtl:pr-2">Hello</span>
</div>
<div data-v-4bd07c72="" class="truncate flex gap-1" dir="auto" title="Somewhere, "><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Somewhere</span></div>
<div data-v-4bd07c72="" class="mt-1 no-underline gap-1 items-center hidden">
<!--v-if-->
<!--v-if--><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-danger dark:text-white">Cancelled</span><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</div>
</div>
</div>
</div>
</a>"
`;
exports[`EventCard > Show default 1`] = `
"<a data-v-4bd07c72="" href="/events/0123456789" class="mbz-card snap-center dark:bg-mbz-purple sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div data-v-4bd07c72="" class="rounded-lg">
<div data-v-4bd07c72="" class="-mt-3 h-0 mb-3 ltr:ml-0 rtl:mr-0 block relative z-10 calendar-simple">
<div data-v-1df97f42="" data-v-4bd07c72="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
<!--v-if-->
<!--v-if-->
</div>
<figure data-v-4bd07c72="" class="block relative pt-40">
<div data-v-4bd07c72="" class="flex-1" style="height: 100%; position: absolute; top: 0px; left: 0px; width: 100%;">
<div class="h-full w-full max-w-100 min-h-[10rem]">
<!-- Show the placeholder as background -->
<!--v-if-->
<!-- Show the real image on the top and fade in after loading --><img class="transition-opacity duration-500 rounded-lg object-cover mx-auto h-full opacity-0" alt="" src="https://mobilizon.fr/media/81d9c76aaf740f84eefb28cf2b9988bdd2495ab1f3246159fd688e242155cb23.png?name=Screenshot_20220315_171848.png" loading="lazy">
</div>
</div>
<div data-v-4bd07c72="" class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end">
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</figure>
</div>
<div data-v-4bd07c72="" class="p-2 flex-auto">
<div data-v-4bd07c72="" class="relative flex flex-col h-full">
<div data-v-4bd07c72="" class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end">
<!--v-if-->
</div><span data-v-4bd07c72="" class="text-gray-700 dark:text-white font-semibold hidden">Feb 2, 2022, 3:04 AM</span>
<!--v-if-->
<div data-v-4bd07c72="" class="w-full flex flex-col justify-between h-full">
<h2 data-v-4bd07c72="" class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto" lang="en">A very interesting event</h2>
<div data-v-4bd07c72="" class="">
<div data-v-4bd07c72="" class="flex items-center text-violet-3 dark:text-white" dir="auto">
<figure data-v-4bd07c72="" class=""><img data-v-4bd07c72="" class="rounded-xl" src="https://mobilizon.fr/media/653c2dcbb830636e0db975798163b85e038dfb7713e866e96d36bd411e105e3c.png?name=festivalsanantes%27s%20avatar.png" alt="" width="24" height="24" loading="lazy"></figure><span data-v-4bd07c72="" class="font-semibold ltr:pl-2 rtl:pr-2">Hello</span>
</div>
<div data-v-4bd07c72="" class="truncate flex gap-1" dir="auto" title="Somewhere, "><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Somewhere</span></div>
<div data-v-4bd07c72="" class="mt-1 no-underline gap-1 items-center hidden">
<!--v-if-->
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</div>
</div>
</div>
</div>
</a>"
`;
exports[`EventCard > Show long 1`] = `
"<a data-v-4bd07c72="" href="/events/0123456789" class="mbz-card snap-center dark:bg-mbz-purple sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div data-v-4bd07c72="" class="rounded-lg">
<div data-v-4bd07c72="" class="-mt-3 h-0 mb-3 ltr:ml-0 rtl:mr-0 block relative z-10 calendar-simple">
<div data-v-1df97f42="" data-v-4bd07c72="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
<!--v-if-->
<!--v-if-->
</div>
<figure data-v-4bd07c72="" class="block relative pt-40">
<div data-v-4bd07c72="" class="flex-1" style="height: 100%; position: absolute; top: 0px; left: 0px; width: 100%;">
<div class="h-full w-full max-w-100 min-h-[10rem]">
<!-- Show the placeholder as background -->
<!--v-if-->
<!-- Show the real image on the top and fade in after loading --><img class="transition-opacity duration-500 rounded-lg object-cover mx-auto h-full opacity-0" alt="" src="https://mobilizon.fr/media/81d9c76aaf740f84eefb28cf2b9988bdd2495ab1f3246159fd688e242155cb23.png?name=Screenshot_20220315_171848.png" loading="lazy">
</div>
</div>
<div data-v-4bd07c72="" class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end">
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</figure>
</div>
<div data-v-4bd07c72="" class="p-2 flex-auto">
<div data-v-4bd07c72="" class="relative flex flex-col h-full">
<div data-v-4bd07c72="" class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end">
<!--v-if-->
</div><span data-v-4bd07c72="" class="text-gray-700 dark:text-white font-semibold hidden">Feb 2, 2022, 3:04 AM</span>
<!--v-if-->
<div data-v-4bd07c72="" class="w-full flex flex-col justify-between h-full">
<h2 data-v-4bd07c72="" class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto" lang="en">A very long title that will have trouble to display because it will take multiple lines but where will it stop&nbsp;?! Maybe after 3 lines is enough. Let's say so. But if it doesn't work, we really need to truncate it at some point. Definitively.</h2>
<div data-v-4bd07c72="" class="">
<div data-v-4bd07c72="" class="flex items-center text-violet-3 dark:text-white" dir="auto">
<figure data-v-4bd07c72="" class=""><img data-v-4bd07c72="" class="rounded-xl" src="https://mobilizon.fr/media/653c2dcbb830636e0db975798163b85e038dfb7713e866e96d36bd411e105e3c.png?name=festivalsanantes%27s%20avatar.png" alt="" width="24" height="24" loading="lazy"></figure><span data-v-4bd07c72="" class="font-semibold ltr:pl-2 rtl:pr-2">Hello</span>
</div>
<div data-v-4bd07c72="" class="truncate flex gap-1" dir="auto" title="Somewhere, "><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Somewhere</span></div>
<div data-v-4bd07c72="" class="mt-1 no-underline gap-1 items-center hidden">
<!--v-if-->
<!--v-if-->
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</div>
</div>
</div>
</div>
</a>"
`;
exports[`EventCard > Show tentative 1`] = `
"<a data-v-4bd07c72="" href="/events/0123456789" class="mbz-card snap-center dark:bg-mbz-purple sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div data-v-4bd07c72="" class="rounded-lg">
<div data-v-4bd07c72="" class="-mt-3 h-0 mb-3 ltr:ml-0 rtl:mr-0 block relative z-10 calendar-simple">
<div data-v-1df97f42="" data-v-4bd07c72="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
<!--v-if-->
<!--v-if-->
</div>
<figure data-v-4bd07c72="" class="block relative pt-40">
<div data-v-4bd07c72="" class="flex-1" style="height: 100%; position: absolute; top: 0px; left: 0px; width: 100%;">
<div class="h-full w-full max-w-100 min-h-[10rem]">
<!-- Show the placeholder as background -->
<!--v-if-->
<!-- Show the real image on the top and fade in after loading --><img class="transition-opacity duration-500 rounded-lg object-cover mx-auto h-full opacity-0" alt="" src="https://mobilizon.fr/media/81d9c76aaf740f84eefb28cf2b9988bdd2495ab1f3246159fd688e242155cb23.png?name=Screenshot_20220315_171848.png" loading="lazy">
</div>
</div>
<div data-v-4bd07c72="" class="absolute top-3 right-0 ltr:-mr-1 rtl:-ml-1 z-10 max-w-xs no-underline flex flex-col gap-1 items-end"><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-info dark:text-black">Tentative</span>
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</figure>
</div>
<div data-v-4bd07c72="" class="p-2 flex-auto">
<div data-v-4bd07c72="" class="relative flex flex-col h-full">
<div data-v-4bd07c72="" class="-mt-3 h-0 flex mb-3 ltr:ml-0 rtl:mr-0 items-end self-end">
<!--v-if-->
</div><span data-v-4bd07c72="" class="text-gray-700 dark:text-white font-semibold hidden">Feb 2, 2022, 3:04 AM</span>
<!--v-if-->
<div data-v-4bd07c72="" class="w-full flex flex-col justify-between h-full">
<h2 data-v-4bd07c72="" class="mt-0 mb-2 text-2xl line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto" lang="en">A very interesting event</h2>
<div data-v-4bd07c72="" class="">
<div data-v-4bd07c72="" class="flex items-center text-violet-3 dark:text-white" dir="auto">
<figure data-v-4bd07c72="" class=""><img data-v-4bd07c72="" class="rounded-xl" src="https://mobilizon.fr/media/653c2dcbb830636e0db975798163b85e038dfb7713e866e96d36bd411e105e3c.png?name=festivalsanantes%27s%20avatar.png" alt="" width="24" height="24" loading="lazy"></figure><span data-v-4bd07c72="" class="font-semibold ltr:pl-2 rtl:pr-2">Hello</span>
</div>
<div data-v-4bd07c72="" class="truncate flex gap-1" dir="auto" title="Somewhere, "><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Somewhere</span></div>
<div data-v-4bd07c72="" class="mt-1 no-underline gap-1 items-center hidden">
<!--v-if--><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-info dark:text-black">Tentative</span>
<!--v-if--><a data-v-4bd07c72="" href="/tag/Something" class=""><span data-v-6955ca87="" data-v-4bd07c72="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-purple-3 dark:text-violet-3 before:content-['#']" dir="auto">Something</span></a>
</div>
</div>
</div>
</div>
</div>
</a>"
`;

View File

@@ -0,0 +1,47 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`EventListViewCard > Show default 1`] = `
"<article class="bg-white dark:bg-zinc-700 dark:text-white dark:hover:text-white rounded-lg shadow-md max-w-3xl p-2">
<div class="flex gap-2">
<div class="">
<div data-v-1df97f42="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
</div><a href="/events/0123456789" class="">
<h2 class="mt-0 line-clamp-2">A very interesting event</h2>
</a>
</div>
<div class="">
<!--v-if--><span>Published by Hello</span>
</div>
<div class="flex gap-1"><span><span aria-hidden="true" class="material-design-icon earth-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.9,17.39C17.64,16.59 16.89,16 16,16H15V13A1,1 0 0,0 14,12H8V10H10A1,1 0 0,0 11,9V7H13A2,2 0 0,0 15,5V4.59C17.93,5.77 20,8.64 20,12C20,14.08 19.2,15.97 17.9,17.39M11,19.93C7.05,19.44 4,16.08 4,12C4,11.38 4.08,10.78 4.21,10.21L9,15V16A2,2 0 0,0 11,18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"><!--v-if--></path></svg></span>
<!--v-if-->
<!--v-if--></span><span><span>0 participants</span></span>
</div>
</article>"
`;
exports[`EventListViewCard > Show long 1`] = `
"<article class="bg-white dark:bg-zinc-700 dark:text-white dark:hover:text-white rounded-lg shadow-md max-w-3xl p-2">
<div class="flex gap-2">
<div class="">
<div data-v-1df97f42="" class="datetime-container flex flex-col rounded-lg text-center justify-center overflow-hidden items-stretch bg-white dark:bg-gray-700 text-black dark:text-white small" style="--small: 1.2;">
<div data-v-1df97f42="" class="datetime-container-header bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="weekday">Wed</time></div>
<div data-v-1df97f42="" class="datetime-container-content"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="day block font-semibold">2</time><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="month font-semibold block uppercase py-1 px-0">Feb</time></div>
<div data-v-1df97f42="" class="datetime-container-footer bg-red-400 dark:bg-red-900"><time data-v-1df97f42="" datetime="2022-02-02T02:04:00.000Z" class="year">2022</time></div>
</div>
</div><a href="/events/0123456789" class="">
<h2 class="mt-0 line-clamp-2">A very long title that will have trouble to display because it will take multiple lines but where will it stop&nbsp;?! Maybe after 3 lines is enough. Let's say so.</h2>
</a>
</div>
<div class="">
<!--v-if--><span>Published by Hello</span>
</div>
<div class="flex gap-1"><span><span aria-hidden="true" class="material-design-icon earth-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.9,17.39C17.64,16.59 16.89,16 16,16H15V13A1,1 0 0,0 14,12H8V10H10A1,1 0 0,0 11,9V7H13A2,2 0 0,0 15,5V4.59C17.93,5.77 20,8.64 20,12C20,14.08 19.2,15.97 17.9,17.39M11,19.93C7.05,19.44 4,16.08 4,12C4,11.38 4.08,10.78 4.21,10.21L9,15V16A2,2 0 0,0 11,18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"><!--v-if--></path></svg></span>
<!--v-if-->
<!--v-if--></span><span><span>0 participants</span></span>
</div>
</article>"
`;

View File

@@ -0,0 +1,28 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`OrganizerPicker > Show simple 1`] = `
"<div data-v-4ef6e9b3="" class="max-w-md mx-auto">
<div data-v-4ef6e9b3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><input dir="auto" class="o-input" id="" data-oruga-input="text" type="text" autocomplete="off" placeholder="Filter by profile or group name">
<!---->
<!---->
<!---->
</div>
<transition-group-stub data-v-4ef6e9b3="" tag="ul" enteractiveclass="duration-300 ease-out" enterfromclass="transform opacity-0" entertoclass="opacity-100" leaveactiveclass="duration-200 ease-in" leavefromclass="opacity-100" leavetoclass="transform opacity-0" appear="false" persisted="false" css="true" class="grid grid-cols-1 gap-y-3 m-5 max-w-md mx-auto">
<li data-v-4ef6e9b3="" class="relative focus-within:shadow-lg"><input data-v-4ef6e9b3="" class="sr-only peer" type="radio" name="availableActors" id="availableActor-59" value="[object Object]"><label data-v-4ef6e9b3="" class="flex items-center gap-2 p-3 bg-white hover:bg-gray-50 dark:bg-violet-3 dark:hover:bg-violet-3/60 border border-gray-300 rounded-lg cursor-pointer peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent" for="availableActor-59"><span data-v-4ef6e9b3="" aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span>
<div data-v-4ef6e9b3="" class="flex-1 w-px">
<h3 data-v-4ef6e9b3="" class="line-clamp-2">Someone</h3><small data-v-4ef6e9b3="" class="flex truncate">@me</small>
</div>
</label></li>
<li data-v-4ef6e9b3="" class="relative focus-within:shadow-lg"><input data-v-4ef6e9b3="" class="sr-only peer" type="radio" name="availableActors" id="availableActor-5" value="[object Object]"><label data-v-4ef6e9b3="" class="flex items-center gap-2 p-3 bg-white hover:bg-gray-50 dark:bg-violet-3 dark:hover:bg-violet-3/60 border border-gray-300 rounded-lg cursor-pointer peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent" for="availableActor-5"><span data-v-4ef6e9b3="" aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span>
<div data-v-4ef6e9b3="" class="flex-1 w-px">
<h3 data-v-4ef6e9b3="" class="line-clamp-2">Sigmund</h3><small data-v-4ef6e9b3="" class="flex truncate">@hello</small>
</div>
</label></li>
<li data-v-4ef6e9b3="" class="relative focus-within:shadow-lg"><input data-v-4ef6e9b3="" class="sr-only peer" type="radio" name="availableActors" id="availableActor-89" value="[object Object]"><label data-v-4ef6e9b3="" class="flex items-center gap-2 p-3 bg-white hover:bg-gray-50 dark:bg-violet-3 dark:hover:bg-violet-3/60 border border-gray-300 rounded-lg cursor-pointer peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent" for="availableActor-89"><span data-v-4ef6e9b3="" aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span>
<div data-v-4ef6e9b3="" class="flex-1 w-px">
<h3 data-v-4ef6e9b3="" class="line-clamp-2">College</h3><small data-v-4ef6e9b3="" class="flex truncate">@congregation</small>
</div>
</label></li>
</transition-group-stub>
</div>"
`;

View File

@@ -0,0 +1,47 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`OrganizerPickerWrapper > Show simple 1`] = `
"<div class="bg-white dark:bg-violet-3 border border-gray-300 rounded-lg cursor-pointer">
<!-- If we have a current actor (inline) -->
<div class="" dir="auto">
<div class="flex gap-1 p-4">
<div class=""><span aria-hidden="true" class="material-design-icon account-circle-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="48" height="48" viewBox="0 0 24 24"><path d="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z"><!--v-if--></path></svg></span></div>
<div class="flex-1">
<p class="">Sigmund</p>
<p class="">@hello</p>
</div><button type="button" class="o-btn" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Change</span>
<!----></span>
</button>
</div>
</div>
<!--teleport start-->
<transition-stub name="zoom-out" appear="false" persisted="false" css="true">
<div has-modal-card="" close-button-aria-label="Close" data-oruga="modal" class="o-modal" tabindex="-1" aria-modal="false" style="display: none;">
<div class="o-modal__overlay" tabindex="-1" aria-hidden="true"></div>
<div class="o-modal__content" style="max-width: 960px;">
<div class="p-2 rounded">
<header class="">
<h2 class="">Pick a profile or a group</h2>
</header>
<section class="">
<div class="flex flex-wrap gap-2 items-center flex-col lg:flex-row">
<div class="max-h-[400px] overflow-y-auto flex-1 w-full">
<!--v-if-->
</div>
<div class="pl-2 max-h-[400px] overflow-y-auto">
<div class="">
<p>Your profile will be shown as contact.</p>
</div>
</div>
</div>
</section>
<footer class="my-2 text-center sm:text-right"><button type="button" class="o-btn o-btn--primary w-full sm:w-auto" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Pick</span>
<!----></span>
</button></footer>
</div><span class="o-icon o-icon--clickable o-icon--medium o-modal__close" data-oruga="icon" style="display: none;"><i class="mdi mdi-close mdi-36px"></i></span>
</div>
</div>
</transition-stub>
<!--teleport end-->
</div>"
`;

View File

@@ -0,0 +1,104 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`ParticipationButton > Show Basic 1`] = `
"<div class="ml-auto w-min">
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button type="button" class="o-btn o-btn--large o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Participate</span><span class="o-icon o-icon--large o-btn__icon o-btn__icon-right" data-oruga="icon"><i class="mdi mdi-menu-down mdi-48px"></i></span></span></button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">
<div class="flex gap-2 items-center">
<figure class=""><img class="rounded-xl" src="https://mobilizon.fr/media/3a5f18c058a8193b1febfaf561f94ae8b91f85ac64c01ddf5ad7b251fb43baf5.jpg?name=profil.jpg" alt="" width="24" height="24"></figure>
<div class=""><span>as Thomas</span></div>
</div>
</div>
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">with another identity…</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>"
`;
exports[`ParticipationButton > Show Basic with confirmation 1`] = `
"<div class="ml-auto w-min">
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button type="button" class="o-btn o-btn--large o-btn--primary" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Participate</span><span class="o-icon o-icon--large o-btn__icon o-btn__icon-right" data-oruga="icon"><i class="mdi mdi-menu-down mdi-48px"></i></span></span></button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">
<div class="flex gap-2 items-center">
<figure class=""><img class="rounded-xl" src="https://mobilizon.fr/media/3a5f18c058a8193b1febfaf561f94ae8b91f85ac64c01ddf5ad7b251fb43baf5.jpg?name=profil.jpg" alt="" width="24" height="24"></figure>
<div class=""><span>as Thomas</span></div>
</div>
</div>
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">with another identity…</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>"
`;
exports[`ParticipationButton > Show Participating 1`] = `
"<div class="ml-auto w-min">
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button type="button" class="o-btn o-btn--large o-btn--success" role="button" data-oruga="button"><span class="o-btn__wrapper"><span class="o-icon o-icon--large o-btn__icon o-btn__icon-left" data-oruga="icon"><i class="mdi mdi-check mdi-48px"></i></span><span class="o-btn__label">I participate</span><span class="o-icon o-icon--large o-btn__icon o-btn__icon-right" data-oruga="icon"><i class="mdi mdi-menu-down mdi-48px"></i></span></span></button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">Cancel my participation…</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>"
`;
exports[`ParticipationButton > Show Pending approval 1`] = `
"<div class="ml-auto w-min">
<div class="flex flex-col">
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><button type="button" class="o-btn o-btn--large o-btn--success" role="button" data-oruga="button"><span class="o-btn__wrapper"><!----><span class="o-btn__label"><template class="flex items-center"></template></span>
<!----></span>
</button></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">Change my identity…</div>
<div class="o-drop__item o-drop__item--clickable" role="listitem" tabindex="0" data-oruga="dropdown-item">Cancel my participation request…</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
<p>Participation requested!</p>
<p>Waiting for organization team approval.</p>
</div>
</div>"
`;
exports[`ParticipationButton > Show Rejected 1`] = `
"<div class="ml-auto w-min">
<div><span>Unfortunately, your participation request was rejected by the organizers.</span></div>
</div>"
`;
exports[`ParticipationButton > Show Unlogged 1`] = `
"<div class="ml-auto w-min"><a href="/events/0123456789/participate/with-account" class="o-btn o-btn--large o-btn--primary" role="button" data-oruga="button" rel="nofollow"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Participate</span>
<!----></span>
</a></div>"
`;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,62 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`SkeletonEventResult > Show column 1`] = `
"<div class="bg-white dark:bg-slate-800 shadow rounded-md max-w-sm w-full mx-auto">
<div class="animate-pulse flex flex-col items-center md:flex-col">
<div class="object-cover h-56 w-full md:max-w-[20rem] bg-slate-700"></div>
<div class="flex-1 space-3-4 flex self-start flex-col justify-between p-2 md:p-4 w-full"><span class="h-2 bg-slate-700"></span><span class="mb-2 h-4 bg-slate-700"></span>
<div class="flex space-x-4 flex-row">
<div class="rounded-full bg-slate-700 h-10 w-10"></div>
<div class="flex flex-col flex-1 space-y-2">
<div class="h-3 bg-slate-700"></div>
<div class="h-2 bg-slate-700"></div>
</div>
</div>
<!--v-if-->
<!--v-if-->
</div>
</div>
</div>"
`;
exports[`SkeletonEventResult > Show not minimal 1`] = `
"<div class="bg-white dark:bg-slate-800 shadow rounded-md max-w-4xl w-full mx-auto">
<div class="animate-pulse flex flex-col items-center md:flex-row">
<div class="object-cover h-56 w-full md:max-w-[20rem] bg-slate-700"></div>
<div class="flex-1 space-3-4 flex self-start flex-col justify-between p-2 md:p-4 w-full"><span class="h-2 bg-slate-700"></span><span class="mb-2 h-4 bg-slate-700"></span>
<div class="flex space-x-4 flex-row">
<div class="rounded-full bg-slate-700 h-10 w-10"></div>
<div class="flex flex-col flex-1 space-y-2">
<div class="h-3 bg-slate-700"></div>
<div class="h-2 bg-slate-700"></div>
</div>
</div>
<div class="h-3 bg-slate-700 mt-3 w-60"></div>
<div class="flex">
<div class="h-3 bg-slate-700 mt-2 w-20 mr-2 rounded"></div>
<div class="h-3 bg-slate-700 mt-2 w-20 mr-2 rounded"></div>
<div class="h-3 bg-slate-700 mt-2 w-20 mr-2 rounded"></div>
</div>
</div>
</div>
</div>"
`;
exports[`SkeletonEventResult > Show row 1`] = `
"<div class="bg-white dark:bg-slate-800 shadow rounded-md max-w-4xl w-full mx-auto">
<div class="animate-pulse flex flex-col items-center md:flex-row">
<div class="object-cover h-56 w-full md:max-w-[20rem] bg-slate-700"></div>
<div class="flex-1 space-3-4 flex self-start flex-col justify-between p-2 md:p-4 w-full"><span class="h-2 bg-slate-700"></span><span class="mb-2 h-4 bg-slate-700"></span>
<div class="flex space-x-4 flex-row">
<div class="rounded-full bg-slate-700 h-10 w-10"></div>
<div class="flex flex-col flex-1 space-y-2">
<div class="h-3 bg-slate-700"></div>
<div class="h-2 bg-slate-700"></div>
</div>
</div>
<!--v-if-->
<!--v-if-->
</div>
</div>
</div>"
`;

View File

@@ -0,0 +1,42 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`TagInput > Show new 1`] = `
"<div data-oruga="field" class="o-field taginput-field"><label for="tag-input-1" class="o-field__label">
<p class="inline-flex items-center gap-0.5">Add some tags
<div class="o-tip" data-oruga="tooltip">
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-tip__content o-tip__content--auto o-tip__content--dark" style="display: none;"><span class="o-tip__arrow o-tip__arrow--auto o-tip__arrow--dark"></span>You can add tags by hitting the Enter key or by adding a comma</div>
</transition-stub>
<!--teleport end-->
<div class="o-tip__trigger" aria-haspopup="true"><span aria-hidden="true" class="material-design-icon help-circle-outline-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="16" height="16" viewBox="0 0 24 24"><path d="M11,18H13V16H11V18M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,6A4,4 0 0,0 8,10H10A2,2 0 0,1 12,8A2,2 0 0,1 14,10C14,12 11,11.75 11,15H13C13,12.75 16,12.5 16,10A4,4 0 0,0 12,6Z"><!--v-if--></path></svg></span></div>
</div>
</p>
</label>
<div class="o-field__body">
<div class="o-field o-field--addons">
<div data-oruga="taginput" class="o-taginput o-taginput--expanded">
<div class="o-taginput__container"><span class="o-taginput__item"><span>Hello</span><span class="o-icon o-icon--clickable o-taginput__item__close" data-oruga="icon"><i class="mdi mdi-close mdi-24px"></i></span></span>
<div data-oruga="autocomplete" class="o-drop o-drop--expanded o-drop--position-auto o-acp o-taginput__autocomplete">
<div tabindex="-1" class="o-drop__trigger" aria-haspopup="listbox">
<div data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><input dir="auto" has-counter="false" role="combobox" aria-autocomplete="list" aria-controls="" aria-expanded="false" id="tag-input-1" data-oruga-input="text" type="text" class="o-input o-taginput__input o-input--iconspace-left" maxlength="20" autocomplete="off" placeholder="Eg: Stockholm, Dance, Chess…"><span class="o-icon o-input__icon-left" data-oruga="icon"><i class="mdi mdi-label mdi-24px"></i></span>
<!---->
<!---->
</div>
</div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div id="" tabindex="-1" class="o-drop__menu o-drop__menu--auto" style="max-height: 200px; overflow: auto; display: none;" role="listbox" aria-hidden="true" aria-modal="false"></div>
</transition-stub>
<!--teleport end-->
</div>
</div><small class="o-taginput__counter">1 / 10</small>
</div>
</div>
</div>
<!---->
</div>"
`;

View File

@@ -0,0 +1,111 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import GroupCard from "@/components/Group/GroupCard.vue";
import { IGroup } from "@/types/actor";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const basicGroup: IGroup = {
name: "Framasoft",
preferredUsername: "framasoft",
avatar: null,
domain: "mobilizon.fr",
url: "",
summary: "",
suspended: false,
members: { total: 0, elements: [] },
followers: { total: 0, elements: [] },
};
const groupWithMedia: IGroup = {
...basicGroup,
banner: {
url: "https://mobilizon.fr/media/a8227a16cc80b3d20ff5ee549a29c1b20a0ca1547f8861129aae9f00c3c69d12.jpg?name=framasoft%27s%20banner.jpg",
},
avatar: {
url: "https://mobilizon.fr/media/890f5396ef80081a6b1b18a5db969746cf8bb340e8a4e657d665e41f6646c539.jpg?name=framasoft%27s%20avatar.jpg",
},
};
const groupWithFollowersOrMembers: IGroup = {
...groupWithMedia,
members: { total: 2, elements: [] },
followers: { total: 5, elements: [] },
summary:
"You can also use variant modifiers to target media queries like responsive breakpoints, dark mode, prefers-reduced-motion, and more. For example, use md:h-full to apply the h-full utility at only medium screen sizes and above.",
physicalAddress: {
description: "Nantes",
},
};
const generateWrapper = (props: any = {}) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(GroupCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("GroupCard", () => {
it("Show Empty", async () => {
const wrapper = generateWrapper({
group: basicGroup,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show With media", async () => {
const wrapper = generateWrapper({
group: groupWithMedia,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show with followers or members", async () => {
const wrapper = generateWrapper({
group: groupWithFollowersOrMembers,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show Row mode", async () => {
const wrapper = generateWrapper({
group: groupWithFollowersOrMembers,
mode: "row",
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,120 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import GroupMemberCard from "@/components/Group/GroupMemberCard.vue";
import { IActor } from "@/types/actor";
import { IMember } from "@/types/actor/member.model";
import { MemberRole } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(GroupMemberCard, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const baseActorAvatar = {
id: "",
name: "",
alt: "",
metadata: {},
url: "https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg",
};
const basePerson: IActor = {
name: "Thomas Citharel",
preferredUsername: "tcit",
avatar: baseActorAvatar,
domain: null,
url: "",
summary: "",
suspended: false,
};
const basicGroup: IActor = {
name: "Framasoft",
preferredUsername: "framasoft",
avatar: {
url: "https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png",
},
domain: "mobilizon.fr",
url: "",
summary: `<p><strong>La Fediverse</strong>, <strong>c'est la <em><u>Féd</u>ération qui englobe l'Un<u>ivers</u> des réseaux sociaux libres et décentralisés,</em> </strong>dont Mobilizon (évènements), Mastodon (microblog), Peertube (vidéos), Pixelfed (photos), Funkwhale (musique), Matrix (messagerie instantanée)... et tant d'autres font partie.</p><p><strong>Et "La Fediverse <em>Nantaise</em>" est un collectif cherchant à faire connaître localement tout le potentiel de ces réseaux ! :-)</strong></p>`,
suspended: false,
members: { total: 0, elements: [] },
followers: { total: 0, elements: [] },
};
const basicMember: IMember = {
parent: basicGroup as IActor,
actor: basePerson,
role: MemberRole.MEMBER,
};
const moderatorMember: IMember = {
parent: basicGroup,
actor: basePerson,
role: MemberRole.MODERATOR,
};
const adminMember: IMember = {
parent: basicGroup,
actor: basePerson,
role: MemberRole.ADMINISTRATOR,
};
describe("GroupMemberCard", () => {
it("Show simple member", async () => {
const wrapper = generateWrapper({
member: basicMember,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show moderator", async () => {
const wrapper = generateWrapper({
member: moderatorMember,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show administrator", async () => {
const wrapper = generateWrapper({
member: adminMember,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,79 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`GroupCard > Show Empty 1`] = `
"<a href="/@framasoft@mobilizon.fr" class="mbz-card snap-center shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div class="flex-none p-2 md:p-4"><span aria-hidden="true" class="material-design-icon account-group-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="128" height="128" viewBox="0 0 24 24"><path d="M12,5.5A3.5,3.5 0 0,1 15.5,9A3.5,3.5 0 0,1 12,12.5A3.5,3.5 0 0,1 8.5,9A3.5,3.5 0 0,1 12,5.5M5,8C5.56,8 6.08,8.15 6.53,8.42C6.38,9.85 6.8,11.27 7.66,12.38C7.16,13.34 6.16,14 5,14A3,3 0 0,1 2,11A3,3 0 0,1 5,8M19,8A3,3 0 0,1 22,11A3,3 0 0,1 19,14C17.84,14 16.84,13.34 16.34,12.38C17.2,11.27 17.62,9.85 17.47,8.42C17.92,8.15 18.44,8 19,8M5.5,18.25C5.5,16.18 8.41,14.5 12,14.5C15.59,14.5 18.5,16.18 18.5,18.25V20H5.5V18.25M0,20V18.5C0,17.11 1.89,15.94 4.45,15.6C3.86,16.28 3.5,17.22 3.5,18.25V20H0M24,20H20.5V18.25C20.5,17.22 20.14,16.28 19.55,15.6C22.11,15.94 24,17.11 24,18.5V20Z"><!--v-if--></path></svg></span></div>
<div class="py-2 px-2 md:px-4 flex flex-col h-full justify-between w-full">
<div class="flex gap-1 mb-2">
<div class="overflow-hidden flex-auto">
<h3 class="text-2xl leading-5 line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto">Framasoft</h3><span class="block truncate">@framasoft@mobilizon.fr</span>
</div>
</div>
<div class="mb-2 line-clamp-3" dir="auto"></div>
<div>
<!--v-if-->
<!--v-if-->
</div>
</div>
</a>"
`;
exports[`GroupCard > Show Row mode 1`] = `
"<a href="/@framasoft@mobilizon.fr" class="mbz-card snap-center shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col sm:flex-row">
<div class="flex-none p-2 md:p-4">
<figure class=""><img class="rounded-full" src="https://mobilizon.fr/media/890f5396ef80081a6b1b18a5db969746cf8bb340e8a4e657d665e41f6646c539.jpg?name=framasoft%27s%20avatar.jpg" alt="" height="128" width="128"></figure>
</div>
<div class="py-2 px-2 md:px-4 flex flex-col h-full justify-between w-full sm:flex-1">
<div class="flex gap-1 mb-2">
<div class="overflow-hidden flex-auto">
<h3 class="text-2xl leading-5 line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto">Framasoft</h3><span class="block truncate">@framasoft@mobilizon.fr</span>
</div>
</div>
<div class="mb-2 line-clamp-3" dir="auto">You can also use variant modifiers to target media queries like responsive breakpoints, dark mode, prefers-reduced-motion, and more. For example, use md:h-full to apply the h-full utility at only medium screen sizes and above.</div>
<div>
<div class="truncate flex gap-1" dir="auto" title="Nantes, undefined"><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Nantes</span></div>
<p class="flex gap-1"><span aria-hidden="true" class="material-design-icon account-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"><!--v-if--></path></svg></span> 7 members or followers</p>
</div>
</div>
</a>"
`;
exports[`GroupCard > Show With media 1`] = `
"<a href="/@framasoft@mobilizon.fr" class="mbz-card snap-center shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div class="flex-none p-2 md:p-4">
<figure class=""><img class="rounded-full" src="https://mobilizon.fr/media/890f5396ef80081a6b1b18a5db969746cf8bb340e8a4e657d665e41f6646c539.jpg?name=framasoft%27s%20avatar.jpg" alt="" height="128" width="128"></figure>
</div>
<div class="py-2 px-2 md:px-4 flex flex-col h-full justify-between w-full">
<div class="flex gap-1 mb-2">
<div class="overflow-hidden flex-auto">
<h3 class="text-2xl leading-5 line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto">Framasoft</h3><span class="block truncate">@framasoft@mobilizon.fr</span>
</div>
</div>
<div class="mb-2 line-clamp-3" dir="auto"></div>
<div>
<!--v-if-->
<!--v-if-->
</div>
</div>
</a>"
`;
exports[`GroupCard > Show with followers or members 1`] = `
"<a href="/@framasoft@mobilizon.fr" class="mbz-card snap-center shrink-0 dark:bg-mbz-purple dark:text-white rounded-lg shadow-lg flex items-center flex-col sm:max-w-xs w-[18rem] shrink-0 flex flex-col">
<div class="flex-none p-2 md:p-4">
<figure class=""><img class="rounded-full" src="https://mobilizon.fr/media/890f5396ef80081a6b1b18a5db969746cf8bb340e8a4e657d665e41f6646c539.jpg?name=framasoft%27s%20avatar.jpg" alt="" height="128" width="128"></figure>
</div>
<div class="py-2 px-2 md:px-4 flex flex-col h-full justify-between w-full">
<div class="flex gap-1 mb-2">
<div class="overflow-hidden flex-auto">
<h3 class="text-2xl leading-5 line-clamp-3 font-bold text-violet-3 dark:text-white" dir="auto">Framasoft</h3><span class="block truncate">@framasoft@mobilizon.fr</span>
</div>
</div>
<div class="mb-2 line-clamp-3" dir="auto">You can also use variant modifiers to target media queries like responsive breakpoints, dark mode, prefers-reduced-motion, and more. For example, use md:h-full to apply the h-full utility at only medium screen sizes and above.</div>
<div>
<div class="truncate flex gap-1" dir="auto" title="Nantes, undefined"><span aria-hidden="true" class="material-design-icon map-marker-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z"><!--v-if--></path></svg></span><span>Nantes</span></div>
<p class="flex gap-1"><span aria-hidden="true" class="material-design-icon account-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"><!--v-if--></path></svg></span> 7 members or followers</p>
</div>
</div>
</a>"
`;

View File

@@ -0,0 +1,123 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`GroupMemberCard > Show administrator 1`] = `
"<div class="rounded shadow-lg bg-white dark:bg-mbz-purple dark:text-white">
<div class="bg-mbz-yellow-alt-50 text-black flex items-center gap-1 p-2 rounded-t-lg" dir="auto">
<figure class=""><img class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="24" height="24"></figure> Thomas Citharel (@tcit)
</div>
<div class="flex items-center gap-2 p-2 pr-4" dir="auto">
<div class="flex-1">
<div class="p-2 flex gap-2">
<div class="">
<figure class="h-12 w-12"><img class="rounded-full w-full h-full object-cover" src="https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png" alt="" width="48" height="48"></figure>
</div>
<div class="" dir="auto"><a href="/@framasoft@mobilizon.fr" class="">
<h2 class="mt-0">Framasoft</h2>
<div class="flex flex-col items-start"><span class="text-sm">@framasoft@mobilizon.fr</span><span data-v-6955ca87="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-info dark:text-black">Administrator</span></div>
</a></div>
</div>
<div class="mt-3 prose dark:prose-invert lg:prose-xl prose-p:m-0 line-clamp-2">
<p><strong>La Fediverse</strong>, <strong>c'est la <em><u>Féd</u>ération qui englobe l'Un<u>ivers</u> des réseaux sociaux libres et décentralisés,</em> </strong>dont Mobilizon (évènements), Mastodon (microblog), Peertube (vidéos), Pixelfed (photos), Funkwhale (musique), Matrix (messagerie instantanée)... et tant d'autres font partie.</p>
<p><strong>Et "La Fediverse <em>Nantaise</em>" est un collectif cherchant à faire connaître localement tout le potentiel de ces réseaux ! :-)</strong></p>
</div>
</div>
<div>
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><span class="cursor-pointer material-design-icon dots-horizontal-icon cursor-pointer" aria-hidden="true" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable inline-flex gap-1" role="listitem" tabindex="0" data-oruga="dropdown-item"><span aria-hidden="true" class="material-design-icon exit-to-app-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19,3H5C3.89,3 3,3.89 3,5V9H5V5H19V19H5V15H3V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M10.08,15.58L11.5,17L16.5,12L11.5,7L10.08,8.41L12.67,11H3V13H12.67L10.08,15.58Z"><!--v-if--></path></svg></span> Leave</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>
</div>
</div>"
`;
exports[`GroupMemberCard > Show moderator 1`] = `
"<div class="rounded shadow-lg bg-white dark:bg-mbz-purple dark:text-white">
<div class="bg-mbz-yellow-alt-50 text-black flex items-center gap-1 p-2 rounded-t-lg" dir="auto">
<figure class=""><img class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="24" height="24"></figure> Thomas Citharel (@tcit)
</div>
<div class="flex items-center gap-2 p-2 pr-4" dir="auto">
<div class="flex-1">
<div class="p-2 flex gap-2">
<div class="">
<figure class="h-12 w-12"><img class="rounded-full w-full h-full object-cover" src="https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png" alt="" width="48" height="48"></figure>
</div>
<div class="" dir="auto"><a href="/@framasoft@mobilizon.fr" class="">
<h2 class="mt-0">Framasoft</h2>
<div class="flex flex-col items-start"><span class="text-sm">@framasoft@mobilizon.fr</span><span data-v-6955ca87="" class="rounded-md truncate text-sm text-black px-2 py-1 bg-mbz-info dark:text-black">Moderator</span></div>
</a></div>
</div>
<div class="mt-3 prose dark:prose-invert lg:prose-xl prose-p:m-0 line-clamp-2">
<p><strong>La Fediverse</strong>, <strong>c'est la <em><u>Féd</u>ération qui englobe l'Un<u>ivers</u> des réseaux sociaux libres et décentralisés,</em> </strong>dont Mobilizon (évènements), Mastodon (microblog), Peertube (vidéos), Pixelfed (photos), Funkwhale (musique), Matrix (messagerie instantanée)... et tant d'autres font partie.</p>
<p><strong>Et "La Fediverse <em>Nantaise</em>" est un collectif cherchant à faire connaître localement tout le potentiel de ces réseaux ! :-)</strong></p>
</div>
</div>
<div>
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><span class="cursor-pointer material-design-icon dots-horizontal-icon cursor-pointer" aria-hidden="true" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable inline-flex gap-1" role="listitem" tabindex="0" data-oruga="dropdown-item"><span aria-hidden="true" class="material-design-icon exit-to-app-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19,3H5C3.89,3 3,3.89 3,5V9H5V5H19V19H5V15H3V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M10.08,15.58L11.5,17L16.5,12L11.5,7L10.08,8.41L12.67,11H3V13H12.67L10.08,15.58Z"><!--v-if--></path></svg></span> Leave</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>
</div>
</div>"
`;
exports[`GroupMemberCard > Show simple member 1`] = `
"<div class="rounded shadow-lg bg-white dark:bg-mbz-purple dark:text-white">
<div class="bg-mbz-yellow-alt-50 text-black flex items-center gap-1 p-2 rounded-t-lg" dir="auto">
<figure class=""><img class="rounded-xl" src="https://social.tcit.fr/system/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg" alt="" width="24" height="24"></figure> Thomas Citharel (@tcit)
</div>
<div class="flex items-center gap-2 p-2 pr-4" dir="auto">
<div class="flex-1">
<div class="p-2 flex gap-2">
<div class="">
<figure class="h-12 w-12"><img class="rounded-full w-full h-full object-cover" src="https://mobilizon.fr/media/ff5b2d425fb73e17fcbb56a1a032359ee0b21453c11af59e103e783817a32fdf.png?name=framasoft%27s%20avatar.png" alt="" width="48" height="48"></figure>
</div>
<div class="" dir="auto"><a href="/@framasoft@mobilizon.fr" class="">
<h2 class="mt-0">Framasoft</h2>
<div class="flex flex-col items-start"><span class="text-sm">@framasoft@mobilizon.fr</span>
<!--v-if-->
</div>
</a></div>
</div>
<div class="mt-3 prose dark:prose-invert lg:prose-xl prose-p:m-0 line-clamp-2">
<p><strong>La Fediverse</strong>, <strong>c'est la <em><u>Féd</u>ération qui englobe l'Un<u>ivers</u> des réseaux sociaux libres et décentralisés,</em> </strong>dont Mobilizon (évènements), Mastodon (microblog), Peertube (vidéos), Pixelfed (photos), Funkwhale (musique), Matrix (messagerie instantanée)... et tant d'autres font partie.</p>
<p><strong>Et "La Fediverse <em>Nantaise</em>" est un collectif cherchant à faire connaître localement tout le potentiel de ces réseaux ! :-)</strong></p>
</div>
</div>
<div>
<div data-oruga="dropdown" class="o-drop o-drop--position-bottom-left">
<div tabindex="0" class="o-drop__trigger" aria-haspopup="true"><span class="cursor-pointer material-design-icon dots-horizontal-icon cursor-pointer" aria-hidden="true" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16,12A2,2 0 0,1 18,10A2,2 0 0,1 20,12A2,2 0 0,1 18,14A2,2 0 0,1 16,12M10,12A2,2 0 0,1 12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12M4,12A2,2 0 0,1 6,10A2,2 0 0,1 8,12A2,2 0 0,1 6,14A2,2 0 0,1 4,12Z"><!--v-if--></path></svg></span></div>
<!--teleport start-->
<transition-stub name="fade" appear="false" persisted="false" css="true">
<!---->
</transition-stub>
<transition-stub name="fade" appear="false" persisted="false" css="true">
<div class="o-drop__menu o-drop__menu--bottom-left" role="list" aria-hidden="true" aria-modal="true" style="display: none;">
<div class="o-drop__item o-drop__item--clickable inline-flex gap-1" role="listitem" tabindex="0" data-oruga="dropdown-item"><span aria-hidden="true" class="material-design-icon exit-to-app-icon" role="img"><svg fill="currentColor" class="material-design-icon__svg" width="24" height="24" viewBox="0 0 24 24"><path d="M19,3H5C3.89,3 3,3.89 3,5V9H5V5H19V19H5V15H3V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M10.08,15.58L11.5,17L16.5,12L11.5,7L10.08,8.41L12.67,11H3V13H12.67L10.08,15.58Z"><!--v-if--></path></svg></span> Leave</div>
</div>
</transition-stub>
<!--teleport end-->
</div>
</div>
</div>
</div>"
`;

View File

@@ -0,0 +1,50 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import CategoriesPreview from "@/components/Home/CategoriesPreview.vue";
import { CATEGORY_STATISTICS } from "@/graphql/statistics";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = () => {
const global_data = getMockClient([CATEGORY_STATISTICS]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(CategoriesPreview, {
props: {},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("CategoriesPreview", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
expect(requestHandlers.handle_0).toHaveBeenCalledTimes(1);
expect(requestHandlers.handle_0).toHaveBeenCalledWith({});
});
});

View File

@@ -0,0 +1,47 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import MobilizonPresentation from "@/components/Home/MobilizonPresentation.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = () => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(MobilizonPresentation, {
props: {},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("MobilizonPresentation", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,50 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import SearchFields from "@/components/Home/SearchFields.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = () => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(SearchFields, {
props: {
search: "",
location: {},
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("SearchFields", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,68 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import UnloggedIntroduction from "@/components/Home/UnloggedIntroduction.vue";
import { reactive } from "vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(UnloggedIntroduction, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const mockconfig = reactive({
name: "My instance name",
description: "An instance that doesn't exist",
slogan: "Test! Test! Test!",
registrationsOpen: true,
});
const mockconfigClosed = reactive({ ...config, registrationsOpen: false });
describe("UnloggedIntroduction", () => {
it("Show open", async () => {
const wrapper = generateWrapper({
config: mockconfig,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show close", async () => {
const wrapper = generateWrapper({
config: mockconfigClosed,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,3 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`CategoriesPreview > Show simple 1`] = `"<!--v-if-->"`;

View File

@@ -0,0 +1,23 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`MobilizonPresentation > Show simple 1`] = `
"<div class="container mx-auto py-4 px-2">
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
<div>
<h3 class="dark:text-white text-3xl font-bold">A practical tool</h3>
<p class="dark:text-white">Mobilizon is a tool that helps you <b>find, create and organise events</b>.</p>
</div>
<div>
<h3 class="dark:text-white text-3xl font-bold">An ethical alternative</h3>
<p class="dark:text-white">Ethical alternative to Facebook events, groups and pages, Mobilizon is a <b>tool designed to serve you</b>. Period.</p>
</div>
<div>
<h3 class="dark:text-white text-3xl font-bold">A federated software</h3>
<p class="dark:text-white">Mobilizon is not a giant platform, but a <b>multitude of interconnected Mobilizon websites</b>.</p>
</div>
</div>
<div class="mt-4 text-center"><a class="o-btn o-btn--large o-btn--primary" role="button" data-oruga="button" href="https://mobilizon.org"><span class="o-btn__wrapper"><!----><span class="o-btn__label">Learn more about Mobilizon</span>
<!----></span>
</a></div>
</div>"
`;

View File

@@ -0,0 +1,21 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`SearchFields > Show simple 1`] = `
"<form data-v-a19720a3="" id="search-anchor" class="container mx-auto p-2 flex flex-col flex-wrap items-stretch gap-2 justify-center dark:text-slate-100" role="search" location="[object Object]">
<div data-v-a19720a3="" class="flex flex-col flex-wrap sm:flex-row gap-2 justify-center"><label data-v-a19720a3="" class="sr-only" for="search_field_input">Keyword, event title, group name, etc.</label>
<div data-v-a19720a3="" data-oruga="input" class="o-input__wrapper o-input__wrapper--expanded"><input class="min-w-48 o-input" autofocus="" autocapitalize="off" autocorrect="off" id="search_field_input" data-oruga-input="text" type="text" maxlength="1024" autocomplete="off" placeholder="Keyword, event title, group name, etc.">
<!---->
<!---->
<!---->
</div>
<!---->
</div>
<div data-v-a19720a3="" class="flex flex-col flex-wrap sm:flex-row gap-2 justify-center"><button data-v-a19720a3="" type="submit" class="o-btn search-Event min-w-40" role="button" data-oruga="button"><span class="o-btn__wrapper"><span class="o-icon o-btn__icon o-btn__icon-left" data-oruga="icon"><i class="mdi mdi-calendar mdi-24px"></i></span><span class="o-btn__label">Events</span>
<!----></span>
</button>
<!--v-if--><button data-v-a19720a3="" type="submit" class="o-btn search-Group min-w-40" role="button" data-oruga="button"><span class="o-btn__wrapper"><span class="o-icon o-btn__icon o-btn__icon-left" data-oruga="icon"><i class="mdi mdi-account-multiple mdi-24px"></i></span><span class="o-btn__label">Groups</span>
<!----></span>
</button>
</div>
</form>"
`;

View File

@@ -0,0 +1,15 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`UnloggedIntroduction > Show close 1`] = `
"<section class="container mx-auto px-2 my-3">
<h1 class="dark:text-white font-bold">Gather ⋅ Organize ⋅ Mobilize</h1>
<p class="dark:text-white mb-2"></p>
</section>"
`;
exports[`UnloggedIntroduction > Show open 1`] = `
"<section class="container mx-auto px-2 my-3">
<h1 class="dark:text-white font-bold">Test! Test! Test!</h1>
<p class="dark:text-white mb-2">An instance that doesn't exist</p>
</section>"
`;

View File

@@ -0,0 +1,64 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import SharePostModal from "@/components/Post/SharePostModal.vue";
import { PostVisibility } from "@/types/enums";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (props: any = {}) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(SharePostModal, {
props: props,
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
const post = {
title: "hello",
url: "https://mobilizon.fr/p/an-uuid",
};
describe("SharePostModal", () => {
it("Show public", async () => {
const wrapper = generateWrapper({
post: { ...post, visibility: PostVisibility.PUBLIC },
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show private", async () => {
const wrapper = generateWrapper({
post: post,
});
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,51 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, mount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import AuthProviders from "@/components/User/AuthProviders.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const providers = [{ id: "keycloak", label: "Entreprise" }, { id: "google" }];
const generateWrapper = () => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return mount(AuthProviders, {
props: {
oauthProviders: providers,
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("AuthProviders", () => {
it("Show simple", async () => {
const wrapper = generateWrapper();
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,11 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`AuthProviders > Show simple 1`] = `
"<div><b>Sign in with</b>
<div class="flex gap-1 flex-wrap"><a class="o-btn o-btn--primary o-btn--outlined-primary" role="button" data-oruga="button" href="/auth/keycloak"><span class="o-btn__wrapper"><span class="o-icon o-btn__icon o-btn__icon-left" data-oruga="icon"><i class="mdi mdi-lock mdi-24px"></i></span><span class="o-btn__label"><span>Entreprise</span></span>
<!----></span>
</a><a class="o-btn o-btn--primary o-btn--outlined-primary" role="button" data-oruga="button" href="/auth/google"><span class="o-btn__wrapper"><span class="o-icon o-btn__icon o-btn__icon-left" data-oruga="icon"><i class="mdi mdi-google mdi-24px"></i></span><span class="o-btn__label"><span>Google</span></span>
<!----></span>
</a></div>
</div>"
`;

View File

@@ -0,0 +1,63 @@
import { beforeEach, describe, it, expect } from "vitest";
import { enUS } from "date-fns/locale";
import { routes } from "@/router";
import { createRouter, createWebHistory, Router } from "vue-router";
import { config, shallowMount } from "@vue/test-utils";
import { Oruga } from "@oruga-ui/oruga-next";
import flushPromises from "flush-promises";
import { getMockClient, requestHandlers } from "../../mocks/client";
import { htmlRemoveId } from "../../common";
import MaterialIcon from "@/components/core/MaterialIcon.vue";
config.global.plugins.push(Oruga);
let router: Router;
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes,
});
// await router.isReady();
});
const generateWrapper = (iconname: string) => {
const global_data = getMockClient([]);
global_data.provide.dateFnsLocale = enUS;
global_data.plugins = [router];
return shallowMount(MaterialIcon, {
props: {
icon: ["", iconname],
},
global: {
...global_data,
stubs: {
RouterLink: false,
},
},
});
};
describe("MaterialIcon", () => {
it("Show GoogleHangouts", async () => {
const wrapper = generateWrapper("GoogleHangouts");
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show CalendarStar", async () => {
const wrapper = generateWrapper("CalendarStar");
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
it("Show account-multiple-plus", async () => {
const wrapper = generateWrapper("account-multiple-plus");
await wrapper.vm.$nextTick();
await flushPromises();
expect(htmlRemoveId(wrapper.html())).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`MaterialIcon > Show CalendarStar 1`] = `"<async-component-wrapper-stub size="18"></async-component-wrapper-stub>"`;
exports[`MaterialIcon > Show GoogleHangouts 1`] = `"<async-component-wrapper-stub size="18"></async-component-wrapper-stub>"`;
exports[`MaterialIcon > Show account-multiple-plus 1`] = `"<async-component-wrapper-stub size="18"></async-component-wrapper-stub>"`;

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import ActorCardStory from "@/components/Account/ActorCard.story.vue";
describe("Actor Card Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(ActorCardStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import ActorInlineStory from "@/components/Account/ActorInline.story.vue";
describe("Actor Inline Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(ActorInlineStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import AddressInfoStory from "@/components/Address/AddressInfo.story.vue";
describe("Address Info Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(AddressInfoStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import AuthProvidersStory from "@/components/User/AuthProviders.story.vue";
describe("Auth Providers Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(AuthProvidersStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,19 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import CategoriesPreviewStory from "@/components/Home/CategoriesPreview.story.vue";
import { getMockClient } from "../../mocks/client";
import { CATEGORY_STATISTICS } from "@/graphql/statistics";
describe("Categories Preview Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(CategoriesPreviewStory, {
global: getMockClient([CATEGORY_STATISTICS]),
});
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,16 +0,0 @@
import { afterEach, describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import CategoryCardStory from "@/components/Categories/CategoryCard.story.vue";
describe("Category Card Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(CategoryCardStory);
};
afterEach(() => {});
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import DateCalendarIconStory from "@/components/Event/DateCalendarIcon.story.vue";
describe("Date Calendar Icon Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(DateCalendarIconStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,15 +0,0 @@
import { describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import DiscussionListItemStory from "@/components/Discussion/DiscussionListItem.story.vue";
describe("Discussion List Item Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(DiscussionListItemStory);
};
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

View File

@@ -1,25 +0,0 @@
import { beforeEach, describe, expect, it } from "vitest";
import { mount, VueWrapper } from "@vue/test-utils";
import EventCardStory from "@/components/Event/EventCard.story.vue";
import {
createMockIntersectionObserver,
getMockClient,
} from "../../mocks/client";
import { CONFIG } from "@/graphql/config"; //
describe("Event Card Story", () => {
let wrapper: VueWrapper;
const generateWrapper = () => {
wrapper = mount(EventCardStory, {
global: getMockClient([CONFIG]),
});
};
beforeEach(() => {
createMockIntersectionObserver();
});
it("Default", async () => {
generateWrapper();
expect(wrapper.html()).toMatchSnapshot();
});
});

Some files were not shown because too many files have changed in this diff Show More