1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-02 20:15:24 +02:00

chore: frontend testing setup (#1739)

* add vitest

* initialize lib w/ tests

* move to dev dep

* run tests in CI

* update file names

* move api folder to lib

* move api and api types to same folder

* update generator outpath

* rm husky

* i guess i _did_ need those types

* reorg types

* extract validators into testable components

* (WIP) start composable testing

* fix import type

* fix linter complaint

* simplify icon type def

* fix linter errors (maybe?)

* rename client file for sorting
This commit is contained in:
Hayden 2022-10-22 11:51:07 -08:00 committed by GitHub
parent 9f6bcc83d5
commit fcc5d99d40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
182 changed files with 902 additions and 487 deletions

View file

@ -84,7 +84,7 @@
import { defineComponent, ref, useContext } from "@nuxtjs/composition-api";
import RecipeContextMenu from "./RecipeContextMenu.vue";
import RecipeFavoriteBadge from "./RecipeFavoriteBadge.vue";
import { Recipe } from "~/types/api-types/recipe";
import { Recipe } from "~/lib/api/types/recipe";
const SAVE_EVENT = "save";
const DELETE_EVENT = "delete";

View file

@ -82,7 +82,7 @@ import { defineComponent, reactive, useContext } from "@nuxtjs/composition-api";
import { useStaticRoutes, useUserApi } from "~/composables/api";
import { alert } from "~/composables/use-toast";
import { detectServerBaseUrl } from "~/composables/use-utils";
import { RecipeAsset } from "~/types/api-types/recipe";
import { RecipeAsset } from "~/lib/api/types/recipe";
export default defineComponent({
props: {

View file

@ -129,7 +129,7 @@ import RecipeCard from "./RecipeCard.vue";
import RecipeCardMobile from "./RecipeCardMobile.vue";
import { useAsyncKey } from "~/composables/use-utils";
import { useLazyRecipes } from "~/composables/recipes";
import { Recipe } from "~/types/api-types/recipe";
import { Recipe } from "~/lib/api/types/recipe";
import { useUserSortPreferences } from "~/composables/use-users/preferences";
const REPLACE_RECIPES_EVENT = "replaceRecipes";
@ -230,13 +230,13 @@ export default defineComponent({
page.value,
// we double-up the first call to avoid a bug with large screens that render the entire first page without scrolling, preventing additional loading
perPage.value*2,
perPage.value * 2,
preferences.value.orderBy,
preferences.value.orderDirection,
cookbook.value,
category.value,
tag.value,
tool.value,
tool.value
);
// since we doubled the first call, we also need to advance the page
@ -263,7 +263,7 @@ export default defineComponent({
cookbook.value,
category.value,
tag.value,
tool.value,
tool.value
);
if (!newRecipes.length) {
hasMore.value = false;
@ -325,7 +325,7 @@ export default defineComponent({
cookbook.value,
category.value,
tag.value,
tool.value,
tool.value
);
context.emit(REPLACE_RECIPES_EVENT, newRecipes);

View file

@ -18,7 +18,7 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import { RecipeCategory, RecipeTag, RecipeTool } from "~/types/api-types/user";
import { RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/user";
export type UrlPrefixParam = "tags" | "categories" | "tools";

View file

@ -56,7 +56,7 @@
<script lang="ts">
import { defineComponent, ref, toRefs, onMounted, reactive } from "@nuxtjs/composition-api";
import { useUserApi } from "~/composables/api";
import { RecipeCommentOut } from "~/types/api-types/recipe";
import { RecipeCommentOut } from "~/lib/api/types/recipe";
import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
export default defineComponent({

View file

@ -101,8 +101,8 @@ import RecipeDialogShare from "./RecipeDialogShare.vue";
import { useUserApi } from "~/composables/api";
import { alert } from "~/composables/use-toast";
import { planTypeOptions } from "~/composables/use-group-mealplan";
import { ShoppingListSummary } from "~/types/api-types/group";
import { PlanEntryType } from "~/types/api-types/meal-plan";
import { ShoppingListSummary } from "~/lib/api/types/group";
import { PlanEntryType } from "~/lib/api/types/meal-plan";
import { useAxiosDownloader } from "~/composables/api/use-axios-download";
import { useCopy } from "~/composables/use-copy";

View file

@ -44,9 +44,9 @@
<script lang="ts">
import { computed, defineComponent, onMounted, ref, useContext } from "@nuxtjs/composition-api";
import RecipeChip from "./RecipeChips.vue";
import { Recipe } from "~/types/api-types/recipe";
import { Recipe } from "~/lib/api/types/recipe";
import { useUserApi } from "~/composables/api";
import { UserOut } from "~/types/api-types/user";
import { UserOut } from "~/lib/api/types/user";
const INPUT_EVENT = "input";

View file

@ -57,7 +57,7 @@
import { defineComponent, toRefs, reactive, ref, watch, useRoute } from "@nuxtjs/composition-api";
import RecipeCardMobile from "./RecipeCardMobile.vue";
import { useRecipes, allRecipes, useRecipeSearch } from "~/composables/recipes";
import { RecipeSummary } from "~/types/api-types/recipe";
import { RecipeSummary } from "~/lib/api/types/recipe";
const SELECTED_EVENT = "selected";
export default defineComponent({
components: {

View file

@ -58,7 +58,7 @@
<script lang="ts">
import { defineComponent, computed, toRefs, reactive, useContext } from "@nuxtjs/composition-api";
import { useClipboard, useShare, whenever } from "@vueuse/core";
import { RecipeShareToken } from "~/types/api-types/recipe";
import { RecipeShareToken } from "~/lib/api/types/recipe";
import { useUserApi } from "~/composables/api";
import { alert } from "~/composables/use-toast";

View file

@ -23,7 +23,7 @@
<script lang="ts">
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
import { useUserApi } from "~/composables/api";
import { UserOut } from "~/types/api-types/user";
import { UserOut } from "~/lib/api/types/user";
export default defineComponent({
props: {
slug: {

View file

@ -131,7 +131,7 @@
import { computed, defineComponent, reactive, ref, toRefs, useContext } from "@nuxtjs/composition-api";
import { useFoodStore, useFoodData, useUnitStore, useUnitData } from "~/composables/store";
import { validators } from "~/composables/use-validators";
import { RecipeIngredient } from "~/types/api-types/recipe";
import { RecipeIngredient } from "~/lib/api/types/recipe";
export default defineComponent({
props: {

View file

@ -23,7 +23,7 @@
import { computed, defineComponent, reactive, toRefs } from "@nuxtjs/composition-api";
// @ts-ignore vue-markdown has no types
import { parseIngredientText } from "~/composables/recipes";
import { RecipeIngredient } from "~/types/api-types/recipe";
import { RecipeIngredient } from "~/lib/api/types/recipe";
export default defineComponent({
components: {},

View file

@ -230,7 +230,7 @@ import {
useContext,
computed,
} from "@nuxtjs/composition-api";
import { RecipeStep, IngredientReferences, RecipeIngredient, RecipeAsset } from "~/types/api-types/recipe";
import { RecipeStep, IngredientReferences, RecipeIngredient, RecipeAsset } from "~/lib/api/types/recipe";
import { parseIngredientText } from "~/composables/recipes";
import { uuid4, detectServerBaseUrl } from "~/composables/use-utils";
import { useUserApi, useStaticRoutes } from "~/composables/api";

View file

@ -17,7 +17,7 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import { RecipeSummary } from "~/types/api-types/recipe";
import { RecipeSummary } from "~/lib/api/types/recipe";
export default defineComponent({
props: {
@ -30,4 +30,4 @@ export default defineComponent({
return {};
},
});
</script>
</script>

View file

@ -31,7 +31,7 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import { RecipeNote } from "~/types/api-types/recipe";
import { RecipeNote } from "~/lib/api/types/recipe";
export default defineComponent({
props: {

View file

@ -35,7 +35,7 @@
<script lang="ts">
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
import { Nutrition } from "~/types/api-types/recipe";
import { Nutrition } from "~/lib/api/types/recipe";
export default defineComponent({
props: {

View file

@ -146,9 +146,9 @@ import { until } from "@vueuse/core";
import { invoke } from "@vueuse/shared";
import draggable from "vuedraggable";
import { useUserApi, useStaticRoutes } from "~/composables/api";
import { OcrTsvResponse as NullableOcrTsvResponse } from "~/types/api-types/ocr";
import { OcrTsvResponse as NullableOcrTsvResponse } from "~/lib/api/types/ocr";
import { validators } from "~/composables/use-validators";
import { Recipe, RecipeIngredient, RecipeStep } from "~/types/api-types/recipe";
import { Recipe, RecipeIngredient, RecipeStep } from "~/lib/api/types/recipe";
import { Paths, Leaves, SelectedRecipeLeaves } from "~/types/ocr-types";
import BannerExperimental from "~/components/global/BannerExperimental.vue";
import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue";
@ -157,7 +157,7 @@ import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientE
import RecipeOcrEditorPageCanvas from "~/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageCanvas.vue";
import RecipeOcrEditorPageHelp from "~/components/Domain/Recipe/RecipeOcrEditorPage/RecipeOcrEditorPageParts/RecipeOcrEditorPageHelp.vue";
import { uuid4 } from "~/composables/use-utils";
import { NoUndefinedField } from "~/types/api";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
// Temporary Shim until we have a better solution
// https://github.com/phillipdupuis/pydantic-to-typescript/issues/28

View file

@ -41,8 +41,8 @@
<script lang="ts">
import { defineComponent, reactive, useContext, ref, toRefs, watch } from "@nuxtjs/composition-api";
import { onMounted } from "vue-demi";
import { NoUndefinedField } from "~/types/api";
import { OcrTsvResponse as NullableOcrTsvResponse } from "~/types/api-types/ocr";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { OcrTsvResponse as NullableOcrTsvResponse } from "~/lib/api/types/ocr";
import { CanvasModes, SelectedTextSplitModes, ImagePosition, Mouse, CanvasRect, ToolbarIcons } from "~/types/ocr-types";
// Temporary Shim until we have a better solution

View file

@ -40,7 +40,7 @@
import { computed, defineComponent, reactive, toRefs, useContext, watch } from "@nuxtjs/composition-api";
import { useUserApi } from "~/composables/api";
import { useCategoryStore, useTagStore, useToolStore } from "~/composables/store";
import { RecipeOrganizer, Organizer } from "~/types/recipe/organizers";
import { RecipeOrganizer, Organizer } from "~/lib/api/types/non-generated";
const CREATED_ITEM_EVENT = "created-item";

View file

@ -50,7 +50,7 @@
import { defineComponent, computed, ref } from "@nuxtjs/composition-api";
import { useContextPresets } from "~/composables/use-context-presents";
import RecipeOrganizerDialog from "~/components/Domain/Recipe/RecipeOrganizerDialog.vue";
import { RecipeOrganizer } from "~/types/recipe/organizers";
import { RecipeOrganizer } from "~/lib/api/types/non-generated";
interface GenericItem {
id?: string;

View file

@ -42,11 +42,11 @@
import { defineComponent, ref, useContext } from "@nuxtjs/composition-api";
import { computed, onMounted } from "vue-demi";
import RecipeOrganizerDialog from "./RecipeOrganizerDialog.vue";
import { RecipeCategory, RecipeTag } from "~/types/api-types/user";
import { RecipeTool } from "~/types/api-types/admin";
import { RecipeCategory, RecipeTag } from "~/lib/api/types/user";
import { RecipeTool } from "~/lib/api/types/admin";
import { useTagStore } from "~/composables/store/use-tag-store";
import { useCategoryStore, useToolStore } from "~/composables/store";
import { Organizer, RecipeOrganizer } from "~/types/recipe/organizers";
import { Organizer, RecipeOrganizer } from "~/lib/api/types/non-generated";
export default defineComponent({
components: {

View file

@ -90,8 +90,8 @@ import RecipePageTitleContent from "./RecipePageParts/RecipePageTitleContent.vue
import RecipePageComments from "./RecipePageParts/RecipePageComments.vue";
import RecipePrintView from "~/components/Domain/Recipe/RecipePrintView.vue";
import { EditorMode, PageMode, usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import { useRecipeMeta } from "~/composables/recipes";
import { useRouteQuery } from "~/composables/use-router";
import { useUserApi } from "~/composables/api";

View file

@ -56,9 +56,9 @@
<script lang="ts">
import { defineComponent, ref, toRefs, onMounted, reactive } from "@nuxtjs/composition-api";
import { useUserApi } from "~/composables/api";
import { Recipe, RecipeCommentOut } from "~/types/api-types/recipe";
import { Recipe, RecipeCommentOut } from "~/lib/api/types/recipe";
import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
import { NoUndefinedField } from "~/types/api";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { usePageUser } from "~/composables/recipe-page/shared-state";
export default defineComponent({

View file

@ -13,8 +13,8 @@
<script lang="ts">
import { defineComponent, onUnmounted } from "@nuxtjs/composition-api";
import { clearPageState, usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import { useUserApi } from "~/composables/api";
import RecipeImageUploadBtn from "~/components/Domain/Recipe/RecipeImageUploadBtn.vue";
import RecipeSettingsMenu from "~/components/Domain/Recipe/RecipeSettingsMenu.vue";

View file

@ -57,8 +57,8 @@
<script lang="ts">
import { defineComponent, ref } from "@nuxtjs/composition-api";
import { usePageState } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
export default defineComponent({
props: {
recipe: {

View file

@ -61,8 +61,8 @@ import RecipeRating from "~/components/Domain/Recipe/RecipeRating.vue";
import RecipeActionMenu from "~/components/Domain/Recipe/RecipeActionMenu.vue";
import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue";
import { useStaticRoutes } from "~/composables/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/lib/api/types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { usePageState, usePageUser, PageMode, EditorMode } from "~/composables/recipe-page/shared-state";
export default defineComponent({
components: {

View file

@ -55,8 +55,8 @@
import draggable from "vuedraggable";
import { computed, defineComponent, ref } from "@nuxtjs/composition-api";
import { usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientEditor.vue";
import RecipeDialogBulkAdd from "~/components/Domain/Recipe/RecipeDialogBulkAdd.vue";
import { uuid4 } from "~/composables/use-utils";

View file

@ -28,8 +28,8 @@
import { defineComponent } from "@nuxtjs/composition-api";
import { usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { useToolStore } from "~/composables/store";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import RecipeIngredients from "~/components/Domain/Recipe/RecipeIngredients.vue";
export default defineComponent({

View file

@ -225,12 +225,12 @@ import {
computed,
} from "@nuxtjs/composition-api";
import RecipeIngredientHtml from "../../RecipeIngredientHtml.vue";
import { RecipeStep, IngredientReferences, RecipeIngredient, RecipeAsset, Recipe } from "~/types/api-types/recipe";
import { RecipeStep, IngredientReferences, RecipeIngredient, RecipeAsset, Recipe } from "~/lib/api/types/recipe";
import { parseIngredientText } from "~/composables/recipes";
import { uuid4, detectServerBaseUrl } from "~/composables/use-utils";
import { useUserApi, useStaticRoutes } from "~/composables/api";
import { usePageState } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import DropZone from "~/components/global/DropZone.vue";
interface MergerHistory {

View file

@ -59,8 +59,8 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
import { usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import RecipeOrganizerSelector from "@/components/Domain/Recipe/RecipeOrganizerSelector.vue";
import RecipeNutrition from "~/components/Domain/Recipe/RecipeNutrition.vue";
import RecipeChips from "@/components/Domain/Recipe/RecipeChips.vue";

View file

@ -30,8 +30,8 @@
import { computed, defineComponent } from "@nuxtjs/composition-api";
import RecipeScaleEditButton from "~/components/Domain/Recipe/RecipeScaleEditButton.vue";
import RecipeRating from "~/components/Domain/Recipe/RecipeRating.vue";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import { usePageState } from "~/composables/recipe-page/shared-state";
export default defineComponent({
components: {

View file

@ -44,8 +44,8 @@
import { defineComponent } from "@nuxtjs/composition-api";
import { usePageState, usePageUser } from "~/composables/recipe-page/shared-state";
import { validators } from "~/composables/use-validators";
import { NoUndefinedField } from "~/types/api";
import { Recipe } from "~/types/api-types/recipe";
import { NoUndefinedField } from "~/lib/api/types/non-generated";
import { Recipe } from "~/lib/api/types/recipe";
import RecipeRating from "~/components/Domain/Recipe/RecipeRating.vue";
import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue";

View file

@ -23,9 +23,12 @@
class="print-section"
>
<h4 v-if="ingredientSection.ingredients[0].title" class="ingredient-title mt-2">
{{ ingredientSection.ingredients[0].title }}
{{ ingredientSection.ingredients[0].title }}
</h4>
<div class="ingredient-grid" :style="{gridTemplateRows:`repeat(${Math.ceil(ingredientSection.ingredients.length / 2)}, min-content)`}">
<div
class="ingredient-grid"
:style="{ gridTemplateRows: `repeat(${Math.ceil(ingredientSection.ingredients.length / 2)}, min-content)` }"
>
<template v-for="(ingredient, ingredientIndex) in ingredientSection.ingredients">
<p :key="`ingredient-${ingredientIndex}`" class="ingredient-body" v-html="parseText(ingredient)" />
</template>
@ -70,7 +73,7 @@
<script lang="ts">
import { defineComponent, computed } from "@nuxtjs/composition-api";
import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue";
import { Recipe, RecipeIngredient, RecipeStep } from "~/types/api-types/recipe";
import { Recipe, RecipeIngredient, RecipeStep } from "~/lib/api/types/recipe";
import { parseIngredientText } from "~/composables/recipes";
type IngredientSection = {

View file

@ -16,7 +16,7 @@
<script lang="ts">
import { defineComponent, useContext } from "@nuxtjs/composition-api";
import { RecipeSettings } from "~/types/api-types/recipe";
import { RecipeSettings } from "~/lib/api/types/recipe";
export default defineComponent({
props: {

View file

@ -47,7 +47,7 @@
<script lang="ts">
import { defineComponent, ref, computed } from "@nuxtjs/composition-api";
import { RecipeTool } from "~/types/api-types/recipe";
import { RecipeTool } from "~/lib/api/types/recipe";
import { useTools } from "~/composables/recipes";
export default defineComponent({