Migrates headless tests to new structure (#1760)

This commit is contained in:
Mihovil Ilakovac 2024-02-13 18:56:24 +01:00 committed by GitHub
parent 0e7a951742
commit 7ff1d06976
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 8488 additions and 248 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
{
"name": "todo-app",
"dependencies": {
"react": "^18.2.0",
"wasp": "file:.wasp/out/sdk/wasp",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/typography": "^0.5.7"
},
"devDependencies": {
"@types/cors": "^2.8.5",
"@types/express": "^4.17.13",
"@types/react": "^18.0.37",
"prisma": "4.16.2",
"typescript": "^5.1.0",
"vite": "^4.3.9"
}
}

View File

@ -1,9 +1,6 @@
import { Link } from '@wasp/router'
import logout from '@wasp/auth/logout'
import useAuth from '@wasp/auth/useAuth'
import { useQuery } from '@wasp/queries'
import getDate from '@wasp/queries/getDate'
import { Link } from "wasp/client/router";
import { logout, useAuth } from "wasp/client/auth";
import { useQuery, getDate } from "wasp/client/operations";
import './Main.css'
import { getName } from './user'

View File

@ -1,14 +1,18 @@
import React, { useState, FormEventHandler, ChangeEventHandler } from 'react'
import { Link } from '@wasp/router'
import { Link } from 'wasp/client/router'
import { type Task } from 'wasp/entities'
import { useQuery } from '@wasp/queries'
import { OptimisticUpdateDefinition, useAction } from '@wasp/actions'
import getTasks from '@wasp/queries/getTasks.js'
import createTask from '@wasp/actions/createTask.js'
import updateTaskIsDone from '@wasp/actions/updateTaskIsDone.js'
import deleteCompletedTasks from '@wasp/actions/deleteCompletedTasks.js'
import toggleAllTasks from '@wasp/actions/toggleAllTasks.js'
import { Task } from '@wasp/entities'
import {
useAction,
type OptimisticUpdateDefinition,
createTask,
updateTaskIsDone,
deleteCompletedTasks,
toggleAllTasks,
useQuery,
getTasks,
} from 'wasp/client/operations'
import React, { useState, FormEventHandler, ChangeEventHandler } from 'react'
type NonEmptyArray<T> = [T, ...T[]]
@ -138,7 +142,9 @@ const TaskView = ({ task }: { task: Task }) => {
/>
</td>
<td>
<Link to={`/task/${task.id}`}> {task.description} </Link>
<Link to="/task/:id" params={{ id: task.id }}>
{task.description}
</Link>
</td>
</tr>
)

View File

@ -1,6 +1,6 @@
import { sayHi } from '../shared/util'
import { sayHi } from '../util'
export default function setup() {
console.log("This was called from the client setup function")
console.log('This was called from the client setup function')
sayHi()
}

View File

@ -1,6 +1,5 @@
import React from 'react'
import { Link } from '@wasp/router'
import { Link } from "wasp/client/router";
const About = () => {
return (

View File

@ -1,7 +1,7 @@
import React, { useEffect } from 'react'
import { Link } from '@wasp/router'
import { User } from '@wasp/auth/types'
import api from '@wasp/api'
import { type AuthUser as User } from "wasp/auth";
import { Link } from "wasp/client/router";
import { api } from "wasp/client/api";
import { getName, getProviderData } from '../user'
async function fetchCustomRoute() {

View File

@ -1,12 +1,16 @@
import React from 'react'
import { Link } from '@wasp/router'
import { Link } from 'wasp/client/router'
import { type Task } from 'wasp/entities'
import {
useAction,
type OptimisticUpdateDefinition,
updateTaskIsDone,
useQuery,
getTask,
getTasks,
} from 'wasp/client/operations'
import { useQuery } from '@wasp/queries'
import { OptimisticUpdateDefinition, useAction } from '@wasp/actions'
import updateTaskIsDone from '@wasp/actions/updateTaskIsDone'
import getTask from '@wasp/queries/getTask.js'
import getTasks from '@wasp/queries/getTasks.js'
import { Task } from '@wasp/entities'
type TaskPayload = Pick<Task, 'id' | 'isDone'>
@ -34,7 +38,7 @@ const Todo = (props: any) => {
})
if (!task) return <div>Task with id {taskId} does not exist.</div>
if (error) return <div>Error occurred! {error}</div>
if (error) return <div>Error occurred! {error.message}</div>
async function toggleIsDone({ id, isDone }: Task) {
try {

View File

@ -1,6 +1,6 @@
import { Link } from '@wasp/router'
import { Link } from "wasp/client/router";
import { VerifyEmailForm } from '@wasp/auth/forms/VerifyEmail'
import { VerifyEmailForm } from "wasp/client/auth";
import appearance from './appearance'
import todoLogo from '../../todoLogo.png'

View File

@ -1,6 +1,6 @@
import { Link } from '@wasp/router'
import { Link } from "wasp/client/router";
import { LoginForm } from '@wasp/auth/forms/Login'
import { LoginForm } from "wasp/client/auth";
import appearance from './appearance'
import todoLogo from '../../todoLogo.png'

View File

@ -1,6 +1,6 @@
import { Link } from '@wasp/router'
import { Link } from "wasp/client/router";
import { ResetPasswordForm } from '@wasp/auth/forms/ResetPassword'
import { ResetPasswordForm } from "wasp/client/auth";
import appearance from './appearance'
import todoLogo from '../../todoLogo.png'

View File

@ -1,4 +1,4 @@
import { ForgotPasswordForm } from '@wasp/auth/forms/ForgotPassword'
import { ForgotPasswordForm } from "wasp/client/auth";
import appearance from './appearance'
import todoLogo from '../../todoLogo.png'

View File

@ -1,8 +1,6 @@
import { Link } from '@wasp/router'
import { SignupForm } from '@wasp/auth/forms/Signup'
import getNumTasks from '@wasp/queries/getNumTasks'
import { useQuery } from '@wasp/queries'
import { Link } from "wasp/client/router";
import { SignupForm } from "wasp/client/auth";
import { useQuery, getNumTasks } from "wasp/client/operations";
import { getTotalTaskCountMessage } from './helpers'
import appearance from './appearance'

View File

@ -1,55 +0,0 @@
// =============================== IMPORTANT =================================
//
// This file is only used for Wasp IDE support. You can change it to configure
// your IDE checks, but none of these options will affect the TypeScript
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
{
"compilerOptions": {
// JSX support
"jsx": "preserve",
"strict": true,
// Allow default imports.
"esModuleInterop": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
// Wasp needs the following settings enable IDE support in your source
// files. Editing them might break features like import autocompletion and
// definition lookup. Don't change them unless you know what you're doing.
//
// The relative path to the generated web app's root directory. This must be
// set to define the "paths" option.
"baseUrl": "../../.wasp/out/web-app/",
"paths": {
// Resolve all "@wasp" imports to the generated source code.
"@wasp/*": [
"src/*"
],
// Resolve all non-relative imports to the correct node module. Source:
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
"*": [
// Start by looking for the definiton inside the node modules root
// directory...
"node_modules/*",
// ... If that fails, try to find it inside definitely-typed type
// definitions.
"node_modules/@types/*"
]
},
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
"typeRoots": [
"../../.wasp/out/web-app/node_modules/@types"
],
// Since this TS config is used only for IDE support and not for
// compilation, the following directory doesn't exist. We need to specify
// it to prevent this error:
// https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file
"outDir": "phantom"
},
"exclude": [
"phantom"
],
}

View File

@ -1,5 +1,4 @@
import { User } from '@wasp/auth/types'
import { findUserIdentity, getEmail } from '@wasp/auth/user'
import { getEmail, findUserIdentity, type AuthUser as User } from "wasp/auth";
export function getName(user?: User) {
if (!user) {

View File

@ -1 +0,0 @@
/// <reference types="../../.wasp/out/web-app/node_modules/vite/client" />

View File

@ -1,12 +1,12 @@
import HttpError from '@wasp/core/HttpError.js'
import { getSomeResource } from './serverSetup.js'
import { Task } from '@wasp/entities'
import { type Task } from "wasp/entities";
import { HttpError } from "wasp/server";
import {
CreateTask,
DeleteCompletedTasks,
ToggleAllTasks,
UpdateTaskIsDone,
} from '@wasp/actions/types'
type CreateTask,
type DeleteCompletedTasks,
type ToggleAllTasks,
type UpdateTaskIsDone,
} from "wasp/server/operations";
import { getSomeResource } from './serverSetup.js'
export const createTask: CreateTask<Pick<Task, 'description'>> = async (
task,

View File

@ -1,7 +1,7 @@
import { BarBaz, FooBar, WebhookCallback } from '@wasp/apis/types'
import { getFirstProviderUserId } from "wasp/auth";
import { type MiddlewareConfigFn } from "wasp/server";
import { type BarBaz, type FooBar, type WebhookCallback } from "wasp/server/api";
import express from 'express'
import { MiddlewareConfigFn } from '@wasp/middleware'
import { getFirstProviderUserId } from '@wasp/auth/user.js'
export const fooBar: FooBar = (_req, res, context) => {
const username = getFirstProviderUserId(context?.user) ?? 'Anonymous'

View File

@ -1,7 +1,4 @@
import {
GetPasswordResetEmailContentFn,
GetVerificationEmailContentFn,
} from '@wasp/types'
import { type GetVerificationEmailContentFn, type GetPasswordResetEmailContentFn } from "wasp/server/auth";
export const getPasswordResetEmailContent: GetPasswordResetEmailContentFn = ({
passwordResetLink,

View File

@ -1,5 +1,5 @@
import { type DbSeedFn } from "wasp/server";
import { createTask } from './actions.js'
import type { DbSeedFn } from '@wasp/dbSeed/types.js'
async function createUser (prismaClient, data) {
const { password, ...newUser } = await prismaClient.user.create({ data })

View File

@ -1,7 +1,11 @@
import { sleep } from '@wasp/utils.js'
export async function foo(args, context) {
console.log("Inside Job bar's callback foo: ", args, context)
await sleep(4000)
return { hello: "world" }
return { hello: 'world' }
}
async function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}

View File

@ -1,11 +1,6 @@
import HttpError from '@wasp/core/HttpError.js'
import { Task } from '@wasp/entities'
import {
GetNumTasks,
GetTask,
GetTasks,
GetDate,
} from '@wasp/queries/types'
import { type Task } from "wasp/entities";
import { HttpError } from "wasp/server";
import { type GetNumTasks, type GetTask, type GetTasks, type GetDate } from "wasp/server/operations";
export const getTasks: GetTasks<void, Task[]> = async (_args, context) => {
if (!context.user) {

View File

@ -1,9 +1,12 @@
import { mySpecialJob } from '@wasp/jobs/mySpecialJob.js'
import { sayHi } from '../shared/util.js'
import { ServerSetupFn, Application } from '@wasp/types'
import { MiddlewareConfigFn } from '@wasp/middleware'
import { type Application } from 'express'
import { mySpecialJob } from 'wasp/server/jobs'
import {
config,
type MiddlewareConfigFn,
type ServerSetupFn,
} from 'wasp/server'
import { sayHi } from '../util.js'
import cors from 'cors'
import config from '@wasp/config.js'
let someResource: string | undefined = undefined

View File

@ -1,48 +0,0 @@
// =============================== IMPORTANT =================================
//
// This file is only used for Wasp IDE support. You can change it to configure
// your IDE checks, but none of these options will affect the TypeScript
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
{
"compilerOptions": {
// Allows default imports.
"esModuleInterop": true,
"allowJs": true,
"strict": true,
// Wasp needs the following settings enable IDE support in your source
// files. Editing them might break features like import autocompletion and
// definition lookup. Don't change them unless you know what you're doing.
//
// The relative path to the generated web app's root directory. This must be
// set to define the "paths" option.
"baseUrl": "../../.wasp/out/server/",
"paths": {
// Resolve all "@wasp" imports to the generated source code.
"@wasp/*": [
"src/*"
],
// Resolve all non-relative imports to the correct node module. Source:
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
"*": [
// Start by looking for the definiton inside the node modules root
// directory...
"node_modules/*",
// ... If that fails, try to find it inside definitely-typed type
// definitions.
"node_modules/@types/*"
]
},
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
"typeRoots": [
"../../.wasp/out/server/node_modules/@types"
],
// Since this TS config is used only for IDE support and not for
// compilation, the following directory doesn't exist. We need to specify
// it to prevent this error:
// https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file
"outDir": "phantom",
},
"exclude": [
"phantom"
],
}

View File

@ -1,28 +0,0 @@
{
"compilerOptions": {
// Enable default imports in TypeScript.
"esModuleInterop": true,
"allowJs": true,
// The following settings enable IDE support in user-provided source files.
// Editing them might break features like import autocompletion and
// definition lookup. Don't change them unless you know what you're doing.
//
// The relative path to the generated web app's root directory. This must be
// set to define the "paths" option.
"baseUrl": "../../.wasp/out/server/",
"paths": {
// Resolve all non-relative imports to the correct node module. Source:
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
"*": [
// Start by looking for the definiton inside the node modules root
// directory...
"node_modules/*",
// ... If that fails, try to find it inside definitely-typed type
// definitions.
"node_modules/@types/*"
]
},
// Correctly resolve types: https://www.typescriptlang.org/tsconfig#typeRoots
"typeRoots": ["../../.wasp/out/server/node_modules/@types"]
}
}

View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@ -1,4 +1,4 @@
const { resolveProjectPath } = require('wasp/client')
const { resolveProjectPath } = require('wasp/dev')
/** @type {import('tailwindcss').Config} */
module.exports = {

View File

@ -3,10 +3,6 @@ app todoApp {
version: "^0.12.0"
},
title: "ToDo App",
dependencies: [
("@tailwindcss/forms", "^0.5.3"),
("@tailwindcss/typography", "^0.5.7")
],
auth: {
userEntity: User,
methods: {
@ -16,11 +12,11 @@ app todoApp {
email: "mihovil@ilakovac.com"
},
emailVerification: {
getEmailContentFn: import { getVerificationEmailContent } from "@server/auth/email.js",
getEmailContentFn: import { getVerificationEmailContent } from "@src/server/auth/email.js",
clientRoute: EmailVerificationRoute,
},
passwordReset: {
getEmailContentFn: import { getPasswordResetEmailContent } from "@server/auth/email.js",
getEmailContentFn: import { getPasswordResetEmailContent } from "@src/server/auth/email.js",
clientRoute: PasswordResetRoute
}
},
@ -30,18 +26,18 @@ app todoApp {
onAuthSucceededRedirectTo: "/profile"
},
server: {
setupFn: import setup from "@server/serverSetup.js",
middlewareConfigFn: import { serverMiddlewareFn } from "@server/serverSetup.js"
setupFn: import setup from "@src/server/serverSetup.js",
middlewareConfigFn: import { serverMiddlewareFn } from "@src/server/serverSetup.js"
},
client: {
rootComponent: import { App } from "@client/App.tsx",
setupFn: import setup from "@client/clientSetup.js"
rootComponent: import { App } from "@src/client/App.tsx",
setupFn: import setup from "@src/client/clientSetup.js"
},
db: {
system: PostgreSQL,
seeds: [
import { devSeedSimple } from "@server/dbSeeds.js",
import { prodSeed } from "@server/dbSeeds.js"
import { devSeedSimple } from "@src/server/dbSeeds.js",
import { prodSeed } from "@src/server/dbSeeds.js"
]
},
emailSender: {
@ -68,44 +64,44 @@ psl=}
route SignupRoute { path: "/signup", to: SignupPage }
page SignupPage {
component: import Signup from "@client/pages/auth/Signup.tsx"
component: import Signup from "@src/client/pages/auth/Signup.tsx"
}
route LoginRoute { path: "/login", to: LoginPage }
page LoginPage {
component: import Login from "@client/pages/auth/Login.tsx"
component: import Login from "@src/client/pages/auth/Login.tsx"
}
route PasswordResetRoute { path: "/password-reset", to: PasswordResetPage }
page PasswordResetPage {
component: import { PasswordReset } from "@client/pages/auth/PasswordReset.tsx",
component: import { PasswordReset } from "@src/client/pages/auth/PasswordReset.tsx",
}
route EmailVerificationRoute { path: "/email-verification-", to: EmailVerificationPage }
page EmailVerificationPage {
component: import { EmailVerification } from "@client/pages/auth/EmailVerification.tsx",
component: import { EmailVerification } from "@src/client/pages/auth/EmailVerification.tsx",
}
route RequestPasswordResetRoute { path: "/request-password-reset", to: RequestPasswordResetPage }
page RequestPasswordResetPage {
component: import { RequestPasswordReset } from "@client/pages/auth/RequestPasswordReset.tsx",
component: import { RequestPasswordReset } from "@src/client/pages/auth/RequestPasswordReset.tsx",
}
route HomeRoute { path: "/", to: MainPage }
page MainPage {
authRequired: true,
component: import Main from "@client/pages/Main.jsx"
component: import Main from "@src/client/pages/Main.jsx"
}
route AboutRoute { path: "/about", to: AboutPage }
page AboutPage {
component: import About from "@client/pages/About.jsx"
component: import About from "@src/client/pages/About.jsx"
}
route ProfileRoute { path: "/profile", to: ProfilePage }
page ProfilePage {
authRequired: true,
component: import { ProfilePage } from "@client/pages/ProfilePage.tsx"
component: import { ProfilePage } from "@src/client/pages/ProfilePage.tsx"
}
// Page for viewing a specific task
@ -113,84 +109,84 @@ page ProfilePage {
route TaskRoute { path: "/task/:id", to: TaskPage }
page TaskPage {
authRequired: true,
component: import Task from "@client/pages/Task.tsx"
component: import Task from "@src/client/pages/Task.tsx"
}
// --------- Queries --------- //
query getTasks {
fn: import { getTasks } from "@server/queries.js",
fn: import { getTasks } from "@src/server/queries.js",
entities: [Task]
}
api fooBar {
fn: import { fooBar } from "@server/apis.js",
middlewareConfigFn: import { fooBarMiddlewareFn } from "@server/apis.js",
fn: import { fooBar } from "@src/server/apis.js",
middlewareConfigFn: import { fooBarMiddlewareFn } from "@src/server/apis.js",
entities: [Task],
// ALL here let's our CORS work. If we did GET, we would need an apiNamespace over it with CORS.
httpRoute: (ALL, "/foo/bar")
}
apiNamespace bar {
middlewareConfigFn: import { barNamespaceMiddlewareFn } from "@server/apis.js",
middlewareConfigFn: import { barNamespaceMiddlewareFn } from "@src/server/apis.js",
path: "/bar"
}
api barBaz {
fn: import { barBaz } from "@server/apis.js",
fn: import { barBaz } from "@src/server/apis.js",
auth: false,
entities: [Task],
httpRoute: (GET, "/bar/baz")
}
api webhookCallback {
fn: import { webhookCallback } from "@server/apis.js",
middlewareConfigFn: import { webhookCallbackMiddlewareFn } from "@server/apis.js",
fn: import { webhookCallback } from "@src/server/apis.js",
middlewareConfigFn: import { webhookCallbackMiddlewareFn } from "@src/server/apis.js",
httpRoute: (POST, "/webhook/callback"),
auth: false
}
query getNumTasks {
fn: import { getNumTasks } from "@server/queries.js",
fn: import { getNumTasks } from "@src/server/queries.js",
entities: [Task],
auth: false
}
query getTask {
fn: import { getTask } from "@server/queries.js",
fn: import { getTask } from "@src/server/queries.js",
entities: [Task]
}
query getDate {
fn: import { getDate } from "@server/queries.js"
fn: import { getDate } from "@src/server/queries.js"
}
// --------- Actions --------- //
action createTask {
fn: import { createTask } from "@server/actions.js",
fn: import { createTask } from "@src/server/actions.js",
entities: [Task]
}
action updateTaskIsDone {
fn: import { updateTaskIsDone } from "@server/actions.js",
fn: import { updateTaskIsDone } from "@src/server/actions.js",
entities: [Task]
}
action deleteCompletedTasks {
fn: import { deleteCompletedTasks } from "@server/actions.js",
fn: import { deleteCompletedTasks } from "@src/server/actions.js",
entities: [Task]
}
action toggleAllTasks {
fn: import { toggleAllTasks } from "@server/actions.js",
fn: import { toggleAllTasks } from "@src/server/actions.js",
entities: [Task]
}
job mySpecialJob {
executor: PgBoss,
perform: {
fn: import { foo } from "@server/jobs/bar.js",
fn: import { foo } from "@src/server/jobs/bar.js",
executorOptions: {
pgBoss: {=json { "retryLimit": 1 } json=}
}
@ -201,7 +197,7 @@ job mySpecialJob {
job mySpecialScheduledJob {
executor: PgBoss,
perform: {
fn: import { foo } from "@server/jobs/bar.js"
fn: import { foo } from "@src/server/jobs/bar.js"
},
schedule: {
cron: "0 * * * *",

View File

@ -0,0 +1,34 @@
// =============================== IMPORTANT =================================
//
// This file is only used for Wasp IDE support. You can change it to configure
// your IDE checks, but none of these options will affect the TypeScript
// compiler. Proper TS compiler configuration in Wasp is coming soon :)
{
"compilerOptions": {
// JSX support
"jsx": "preserve",
"strict": true,
// Allow default imports.
"esModuleInterop": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"types": [
// This is needed to properly support Vitest testing with jest-dom matchers.
// Types for jest-dom are not recognized automatically and Typescript complains
// about missing types e.g. when using `toBeInTheDocument` and other matchers.
"@testing-library/jest-dom"
],
// Since this TS config is used only for IDE support and not for
// compilation, the following directory doesn't exist. We need to specify
// it to prevent this error:
// https://stackoverflow.com/questions/42609768/typescript-error-cannot-write-file-because-it-would-overwrite-input-file
"outDir": "phantom",
},
"exclude": [
"phantom"
],
}

View File

@ -0,0 +1,7 @@
import { defineConfig } from "vite";
export default defineConfig({
server: {
open: false,
},
});