diff --git a/.changesets/11755.md b/.changesets/11755.md new file mode 100644 index 000000000000..c0802c308dfb --- /dev/null +++ b/.changesets/11755.md @@ -0,0 +1,5 @@ +- fix(cli): Allow common custom scaffold template files (#11755) by @esteban-url + +Adds the ability to generate test, stories and mock files when custom scaffold templates are in use. + +Adds initial tests, stories and mocks to the generator they can generated by using the flags `--tests` and `--stories` diff --git a/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.mock.ts b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.mock.ts new file mode 100644 index 000000000000..420e723ce7ac --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.mock.ts @@ -0,0 +1,10 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contact: { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.stories.tsx new file mode 100644 index 000000000000..93034e7224bd --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import Contact from './Contact' + +const meta: Meta = { + component: Contact, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.test.tsx b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.test.tsx new file mode 100644 index 000000000000..9ec1c38395c9 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contact/Contact.test.tsx @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import Contact from './Contact' +import { standard } from './Contact.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Contact', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.mock.ts b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.mock.ts new file mode 100644 index 000000000000..420e723ce7ac --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.mock.ts @@ -0,0 +1,10 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contact: { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.stories.tsx new file mode 100644 index 000000000000..fc6c14684400 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './ContactCell' +import { standard } from './ContactCell.mock' + +const meta: Meta = { + title: 'Cells/ContactCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.test.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.test.tsx new file mode 100644 index 000000000000..6317dd1220cf --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactCell/ContactCell.test.tsx @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './ContactCell' +import { standard } from './ContactCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('ContactCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.mock.ts b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.mock.ts new file mode 100644 index 000000000000..420e723ce7ac --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.mock.ts @@ -0,0 +1,10 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contact: { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.stories.tsx new file mode 100644 index 000000000000..0fc1a74b473e --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import ContactForm from './ContactForm' + +const meta: Meta = { + component: ContactForm, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.test.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.test.tsx new file mode 100644 index 000000000000..52d42ded4975 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactForm/ContactForm.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ContactForm from './ContactForm' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('ContactForm', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.mock.ts b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.mock.ts new file mode 100644 index 000000000000..c4e4f2b5cef5 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.mock.ts @@ -0,0 +1,19 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contacts: [ + { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, + { + __typename: 'Contact', + id: 43, + name: 'String', + email: 'String', + message: 'String', + }, + ], +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.stories.tsx new file mode 100644 index 000000000000..8f0f0911c0b3 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import Contacts from './Contacts' + +const meta: Meta = { + component: Contacts, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.test.tsx b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.test.tsx new file mode 100644 index 000000000000..acb994246964 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/Contacts/Contacts.test.tsx @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import Contacts from './Contacts' +import { standard } from './Contacts.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Contacts', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.mock.ts b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.mock.ts new file mode 100644 index 000000000000..c4e4f2b5cef5 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.mock.ts @@ -0,0 +1,19 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contacts: [ + { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, + { + __typename: 'Contact', + id: 43, + name: 'String', + email: 'String', + message: 'String', + }, + ], +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.stories.tsx new file mode 100644 index 000000000000..1fa33a5488e5 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Empty, Failure, Success } from './ContactsCell' +import { standard } from './ContactsCell.mock' + +const meta: Meta = { + title: 'Cells/ContactsCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const empty: StoryObj = { + render: (args) => { + return Empty ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.test.tsx b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.test.tsx new file mode 100644 index 000000000000..d151074d6147 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/ContactsCell/ContactsCell.test.tsx @@ -0,0 +1,30 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Empty, Success } from './ContactsCell' +import { standard } from './ContactsCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('ContactsCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders empty successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.mock.ts b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.mock.ts new file mode 100644 index 000000000000..420e723ce7ac --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.mock.ts @@ -0,0 +1,10 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contact: { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.stories.tsx new file mode 100644 index 000000000000..809bf4c5dd38 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './EditContactCell' +import { standard } from './EditContactCell.mock' + +const meta: Meta = { + title: 'Cells/EditContactCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.test.tsx b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.test.tsx new file mode 100644 index 000000000000..65c656db83d0 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/EditContactCell/EditContactCell.test.tsx @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './EditContactCell' +import { standard } from './EditContactCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('EditContactCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.mock.ts b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.mock.ts new file mode 100644 index 000000000000..420e723ce7ac --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.mock.ts @@ -0,0 +1,10 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + contact: { + __typename: 'Contact', + id: 42, + name: 'String', + email: 'String', + message: 'String', + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.stories.tsx b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.stories.tsx new file mode 100644 index 000000000000..65ec426af8aa --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import NewContact from './NewContact' + +const meta: Meta = { + component: NewContact, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.test.tsx b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.test.tsx new file mode 100644 index 000000000000..b6c8e4a656a5 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Contact/NewContact/NewContact.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import NewContact from './NewContact' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('NewContact', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.mock.ts b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.mock.ts new file mode 100644 index 000000000000..e5bf9518cc57 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.mock.ts @@ -0,0 +1,17 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + post: { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String10', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.stories.tsx b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.stories.tsx new file mode 100644 index 000000000000..e93f1b911d69 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './EditPostCell' +import { standard } from './EditPostCell.mock' + +const meta: Meta = { + title: 'Cells/EditPostCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.test.tsx b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.test.tsx new file mode 100644 index 000000000000..b5527b040444 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/EditPostCell/EditPostCell.test.tsx @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './EditPostCell' +import { standard } from './EditPostCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('EditPostCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.mock.ts b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.mock.ts new file mode 100644 index 000000000000..e5bf9518cc57 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.mock.ts @@ -0,0 +1,17 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + post: { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String10', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.stories.tsx b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.stories.tsx new file mode 100644 index 000000000000..37c504847772 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import NewPost from './NewPost' + +const meta: Meta = { + component: NewPost, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.test.tsx b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.test.tsx new file mode 100644 index 000000000000..ba36770127e4 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/NewPost/NewPost.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import NewPost from './NewPost' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('NewPost', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/Post/Post.mock.ts b/__fixtures__/test-project/web/src/components/Post/Post/Post.mock.ts new file mode 100644 index 000000000000..e5bf9518cc57 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Post/Post.mock.ts @@ -0,0 +1,17 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + post: { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String10', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Post/Post/Post.stories.tsx b/__fixtures__/test-project/web/src/components/Post/Post/Post.stories.tsx new file mode 100644 index 000000000000..febfce8ac487 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Post/Post.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import Post from './Post' + +const meta: Meta = { + component: Post, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Post/Post/Post.test.tsx b/__fixtures__/test-project/web/src/components/Post/Post/Post.test.tsx new file mode 100644 index 000000000000..1ca979644b68 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Post/Post.test.tsx @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import Post from './Post' +import { standard } from './Post.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Post', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.mock.ts b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.mock.ts new file mode 100644 index 000000000000..e5bf9518cc57 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.mock.ts @@ -0,0 +1,17 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + post: { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String10', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.stories.tsx b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.stories.tsx new file mode 100644 index 000000000000..df2621ec5f17 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.stories.tsx @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './PostCell' +import { standard } from './PostCell.mock' + +const meta: Meta = { + title: 'Cells/PostCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.test.tsx b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.test.tsx new file mode 100644 index 000000000000..daa1c411bddf --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostCell/PostCell.test.tsx @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './PostCell' +import { standard } from './PostCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('PostCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.mock.ts b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.mock.ts new file mode 100644 index 000000000000..e5bf9518cc57 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.mock.ts @@ -0,0 +1,17 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + post: { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String10', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.stories.tsx b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.stories.tsx new file mode 100644 index 000000000000..50c6776e5221 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import PostForm from './PostForm' + +const meta: Meta = { + component: PostForm, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.test.tsx b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.test.tsx new file mode 100644 index 000000000000..b46f8508fca5 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostForm/PostForm.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import PostForm from './PostForm' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('PostForm', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/Posts/Posts.mock.ts b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.mock.ts new file mode 100644 index 000000000000..9f3bbd24f0a9 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.mock.ts @@ -0,0 +1,33 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + posts: [ + { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String11', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, + { + __typename: 'Post', + id: 43, + title: 'String', + body: 'String', + author: { + create: { + email: 'String25', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, + ], +}) diff --git a/__fixtures__/test-project/web/src/components/Post/Posts/Posts.stories.tsx b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.stories.tsx new file mode 100644 index 000000000000..23461e24a2ba --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.stories.tsx @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import Posts from './Posts' + +const meta: Meta = { + component: Posts, + tags: ['autodocs'], +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/components/Post/Posts/Posts.test.tsx b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.test.tsx new file mode 100644 index 000000000000..095858b544d7 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/Posts/Posts.test.tsx @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import Posts from './Posts' +import { standard } from './Posts.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Posts', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.mock.ts b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.mock.ts new file mode 100644 index 000000000000..9f3bbd24f0a9 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.mock.ts @@ -0,0 +1,33 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + posts: [ + { + __typename: 'Post', + id: 42, + title: 'String', + body: 'String', + author: { + create: { + email: 'String11', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, + { + __typename: 'Post', + id: 43, + title: 'String', + body: 'String', + author: { + create: { + email: 'String25', + hashedPassword: 'String', + fullName: 'String', + salt: 'String', + }, + }, + }, + ], +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.stories.tsx b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.stories.tsx new file mode 100644 index 000000000000..6827f5f5c804 --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Empty, Failure, Success } from './PostsCell' +import { standard } from './PostsCell.mock' + +const meta: Meta = { + title: 'Cells/PostsCell', + tags: ['autodocs'], +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const empty: StoryObj = { + render: (args) => { + return Empty ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.test.tsx b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.test.tsx new file mode 100644 index 000000000000..a9ee8429adca --- /dev/null +++ b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.test.tsx @@ -0,0 +1,30 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Empty, Success } from './PostsCell' +import { standard } from './PostsCell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('PostsCell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders empty successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.tsx b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.tsx index d7db11c51d06..9c31b1d7c72d 100644 --- a/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.tsx +++ b/__fixtures__/test-project/web/src/components/Post/PostsCell/PostsCell.tsx @@ -17,6 +17,10 @@ export const QUERY: TypedDocumentNode = gql` body authorId createdAt + author { + id + # Add the author fields you need here + } } } ` diff --git a/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.stories.tsx new file mode 100644 index 000000000000..545d4c7eee3b --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import ContactPage from './ContactPage' + +const meta: Meta = { + component: ContactPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.test.tsx b/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.test.tsx new file mode 100644 index 000000000000..dca2e65cde0f --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/ContactPage/ContactPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ContactPage from './ContactPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('ContactPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.stories.tsx new file mode 100644 index 000000000000..d71e49216424 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import ContactsPage from './ContactsPage' + +const meta: Meta = { + component: ContactsPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.test.tsx b/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.test.tsx new file mode 100644 index 000000000000..ec408cc8ee99 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/ContactsPage/ContactsPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ContactsPage from './ContactsPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('ContactsPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.stories.tsx new file mode 100644 index 000000000000..29383e96d71a --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import EditContactPage from './EditContactPage' + +const meta: Meta = { + component: EditContactPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.test.tsx b/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.test.tsx new file mode 100644 index 000000000000..d09d3330ec51 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/EditContactPage/EditContactPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import EditContactPage from './EditContactPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('EditContactPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.stories.tsx new file mode 100644 index 000000000000..362827b65d8f --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import NewContactPage from './NewContactPage' + +const meta: Meta = { + component: NewContactPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.test.tsx b/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.test.tsx new file mode 100644 index 000000000000..dfd89d5f97a0 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Contact/NewContactPage/NewContactPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import NewContactPage from './NewContactPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('NewContactPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.stories.tsx new file mode 100644 index 000000000000..396336fa5537 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import EditPostPage from './EditPostPage' + +const meta: Meta = { + component: EditPostPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.test.tsx b/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.test.tsx new file mode 100644 index 000000000000..0dd982b3d9ec --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/EditPostPage/EditPostPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import EditPostPage from './EditPostPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('EditPostPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.stories.tsx new file mode 100644 index 000000000000..9cbbc87ac8ae --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import NewPostPage from './NewPostPage' + +const meta: Meta = { + component: NewPostPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.test.tsx b/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.test.tsx new file mode 100644 index 000000000000..e204183f335e --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/NewPostPage/NewPostPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import NewPostPage from './NewPostPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('NewPostPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.stories.tsx new file mode 100644 index 000000000000..439e99f05d9b --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import PostPage from './PostPage' + +const meta: Meta = { + component: PostPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.test.tsx b/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.test.tsx new file mode 100644 index 000000000000..52d67ee9e5ea --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/PostPage/PostPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import PostPage from './PostPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('PostPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.stories.tsx b/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.stories.tsx new file mode 100644 index 000000000000..54005d2a10d2 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import PostsPage from './PostsPage' + +const meta: Meta = { + component: PostsPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.test.tsx b/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.test.tsx new file mode 100644 index 000000000000..d26d6d174493 --- /dev/null +++ b/__fixtures__/test-project/web/src/pages/Post/PostsPage/PostsPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import PostsPage from './PostsPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('PostsPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/destroy/scaffold/scaffold.js b/packages/cli/src/commands/destroy/scaffold/scaffold.js index 62703aadf282..949a7b07d59d 100644 --- a/packages/cli/src/commands/destroy/scaffold/scaffold.js +++ b/packages/cli/src/commands/destroy/scaffold/scaffold.js @@ -114,7 +114,7 @@ export const tasks = ({ model, path, tests, nestScaffoldByModel }) => export const handler = async ({ model: modelArg }) => { recordTelemetryAttributes({ - command: 'destory scaffold', + command: 'destroy scaffold', }) const { model, path } = splitPathAndModel(modelArg) try { diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffold.test.js.snap b/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffold.test.js.snap index 90187e50c576..73c804804e35 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffold.test.js.snap +++ b/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffold.test.js.snap @@ -198,6 +198,15 @@ export const QUERY = gql\` upvotes metadata hugeNumber + favorites { + id + # Add the favorites fields you need here + } + + tag { + id + # Add the tag fields you need here + } } } \` @@ -266,6 +275,118 @@ export default ScaffoldLayout " `; +exports[`custom templates > creates a service 1`] = ` +"import type { + QueryResolvers, + MutationResolvers, + PostRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const posts: QueryResolvers['posts'] = () => { + return db.post.findMany() +} + +export const post: QueryResolvers['post'] = ({ id }) => { + return db.post.findUnique({ + where: { id }, + }) +} + +export const createPost: MutationResolvers['createPost'] = ({ input }) => { + return db.post.create({ + data: input, + }) +} + +export const updatePost: MutationResolvers['updatePost'] = ({ id, input }) => { + return db.post.update({ + data: input, + where: { id }, + }) +} + +export const deletePost: MutationResolvers['deletePost'] = ({ id }) => { + return db.post.delete({ + where: { id }, + }) +} + +export const Post: PostRelationResolvers = { + favorites: (_obj, { root }) => { + return db.post.findUnique({ where: { id: root?.id } }).favorites() + }, + tag: (_obj, { root }) => { + return db.post.findUnique({ where: { id: root?.id } }).tag() + }, +} +" +`; + +exports[`custom templates > creates a service test 1`] = ` +"import type { Post } from '@prisma/client' + +import { posts, post, createPost, updatePost, deletePost } from './posts' +import type { StandardScenario } from './posts.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('posts', () => { + scenario('returns all posts', async (scenario: StandardScenario) => { + const result = await posts() + + expect(result.length).toEqual(Object.keys(scenario.post).length) + }) + + scenario('returns a single post', async (scenario: StandardScenario) => { + const result = await post({ id: scenario.post.one.id }) + + expect(result).toEqual(scenario.post.one) + }) + + scenario('creates a post', async () => { + const result = await createPost({ + input: { + title: 'String', + slug: 'String1234567', + author: 'String', + body: 'String', + metadata: { foo: 'bar' }, + }, + }) + + expect(result.title).toEqual('String') + expect(result.slug).toEqual('String1234567') + expect(result.author).toEqual('String') + expect(result.body).toEqual('String') + expect(result.metadata).toEqual({ foo: 'bar' }) + }) + + scenario('updates a post', async (scenario: StandardScenario) => { + const original = (await post({ id: scenario.post.one.id })) as Post + const result = await updatePost({ + id: original.id, + input: { title: 'String2' }, + }) + + expect(result.title).toEqual('String2') + }) + + scenario('deletes a post', async (scenario: StandardScenario) => { + const original = (await deletePost({ id: scenario.post.one.id })) as Post + const result = await post({ id: original.id }) + + expect(result).toEqual(null) + }) +}) +" +`; + exports[`custom templates > creates an sdl 1`] = ` "export const schema = gql\` type Post { @@ -1682,6 +1803,15 @@ export const QUERY = gql\` upvotes metadata hugeNumber + favorites { + id + # Add the favorites fields you need here + } + + tag { + id + # Add the tag fields you need here + } } } \` @@ -3524,6 +3654,15 @@ export const QUERY: TypedDocumentNode = gql\` upvotes metadata hugeNumber + favorites { + id + # Add the favorites fields you need here + } + + tag { + id + # Add the tag fields you need here + } } } \` diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffoldNoNest.test.js.snap b/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffoldNoNest.test.js.snap index d2a5999ec2ab..0a39ad3cfe4d 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffoldNoNest.test.js.snap +++ b/packages/cli/src/commands/generate/scaffold/__tests__/__snapshots__/scaffoldNoNest.test.js.snap @@ -1049,6 +1049,15 @@ export const QUERY = gql\` upvotes metadata hugeNumber + favorites { + id + # Add the favorites fields you need here + } + + tag { + id + # Add the tag fields you need here + } } } \` @@ -2425,6 +2434,15 @@ export const QUERY: TypedDocumentNode = gql\` upvotes metadata hugeNumber + favorites { + id + # Add the favorites fields you need here + } + + tag { + id + # Add the tag fields you need here + } } } \` diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffold.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffold.test.js index 29a6f85150c3..6e70d41bb96b 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffold.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffold.test.js @@ -40,7 +40,6 @@ describe('in javascript (default) mode', () => { files = await scaffold.files({ ...getDefaultArgs(defaults), model: 'Post', - tests: true, nestScaffoldByModel: true, }) }) @@ -299,7 +298,6 @@ describe('in javascript (default) mode', () => { scaffold.files({ ...getDefaultArgs(defaults), model: 'NoEditableField', - tests: true, nestScaffoldByModel: true, }), ).rejects.toThrow( @@ -461,7 +459,6 @@ describe('in typescript mode', () => { ...getDefaultArgs(defaults), model: 'Post', typescript: true, - tests: true, nestScaffoldByModel: true, }) }) @@ -876,12 +873,84 @@ describe('custom templates', () => { 'redwood.toml': '', 'web/generators/scaffold/pages/EditNamePage.tsx.template': 'export default function CustomEditPage() { return null }', + 'web/generators/scaffold/pages/EditNamePage.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/pages/EditNamePage.test.tsx.template': + "it('renders page successfully', () => {})", 'web/generators/scaffold/pages/NewNamePage.tsx.template': 'export default function CustomNewPage() { return null }', + 'web/generators/scaffold/pages/NewNamePage.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/pages/NewNamePage.test.tsx.template': + "it('renders page successfully', () => {})", 'web/generators/scaffold/pages/NamePage.tsx.template': 'export default function CustomPage() { return null }', + 'web/generators/scaffold/pages/NamePage.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/pages/NamePage.test.tsx.template': + "it('renders page successfully', () => {})", 'web/generators/scaffold/pages/NamesPage.tsx.template': 'export default function CustomPluralPage() { return null }', + 'web/generators/scaffold/pages/NamesPage.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/pages/NamesPage.test.tsx.template': + "it('renders page successfully', () => {})", + 'web/generators/scaffold/components/EditNameCell.tsx.template': + 'export const Success = () => null', + 'web/generators/scaffold/components/EditNameCell.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/EditNameCell.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/EditNameCell.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/NameCell.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/NameCell.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/NameCell.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/NameCell.tsx.template': + 'export const Success = () => null', + 'web/generators/scaffold/components/NameForm.tsx.template': + 'export default function ${singularPascalName}Form() { return null }', + 'web/generators/scaffold/components/NameForm.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/NameForm.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/NameForm.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/Names.tsx.template': + 'export default function ${singularPascalName}List() { return null }', + 'web/generators/scaffold/components/Names.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/Names.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/Names.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/NamesCell.tsx.template': + 'export const Success = () => null', + 'web/generators/scaffold/components/NamesCell.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/NamesCell.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/NamesCell.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/NewName.tsx.template': + 'export default function New${singularPascalName}() { return null }', + 'web/generators/scaffold/components/NewName.mock.tsx.template': + 'export const standard = () => ({})', + 'web/generators/scaffold/components/NewName.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/NewName.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', + 'web/generators/scaffold/components/Name.tsx.template': + 'export default function ${singularPascalName}() { return null }', + 'web/generators/scaffold/components/Name.mock.ts.template': + 'export const standard = () => ({ custom: "" })', + 'web/generators/scaffold/components/Name.test.tsx.template': + "it('renders component successfully', () => {})", + 'web/generators/scaffold/components/Name.stories.tsx.template': + 'const customMeta = {}\nexport default customMeta\nexport const Primary = {}', }, process.env.RWJS_CWD, ) @@ -890,8 +959,10 @@ describe('custom templates', () => { force: false, model: 'Post', typescript: true, - tests: true, nestScaffoldByModel: true, + tests: true, + stories: true, + serviceTests: true, }) }) @@ -900,8 +971,8 @@ describe('custom templates', () => { process.env.RWJS_CWD = originalRwjsCwd }) - test('returns exactly 19 files', () => { - expect(Object.keys(tsFiles).length).toEqual(19) + test('returns exactly 48 files', () => { + expect(Object.keys(tsFiles).length).toEqual(48) }) test('creates an Edit page', async () => { @@ -964,6 +1035,60 @@ describe('custom templates', () => { `) }) + test('creates a Show page story', async () => { + expect( + tsFiles[ + path.normalize( + '/path/to/project/web/src/pages/Post/PostPage/PostPage.stories.tsx', + ) + ], + ).toMatchInlineSnapshot(` + "const customMeta = {} + export default customMeta + export const Primary = {} + " + `) + }) + + test('creates a Show page test', async () => { + expect( + tsFiles[ + path.normalize( + '/path/to/project/web/src/pages/Post/PostPage/PostPage.test.tsx', + ) + ], + ).toMatchInlineSnapshot(` + "it('renders page successfully', () => {}) + " + `) + }) + + test('creates a test for the index component', async () => { + expect( + tsFiles[ + path.normalize( + '/path/to/project/web/src/components/Post/Post/Post.test.tsx', + ) + ], + ).toMatchInlineSnapshot(` + "it('renders component successfully', () => {}) + " + `) + }) + + test('creates mocks for the index component', async () => { + expect( + tsFiles[ + path.normalize( + '/path/to/project/web/src/components/Post/Post/Post.mock.ts', + ) + ], + ).toMatchInlineSnapshot(` + "export const standard = () => ({ custom: '' }) + " + `) + }) + // SDL // (Including this in the test just to make sure we're testing at least one // api-side file) @@ -974,6 +1099,24 @@ describe('custom templates', () => { ).toMatchSnapshot() }) + // Service + + test('creates a service', () => { + expect( + tsFiles[ + path.normalize('/path/to/project/api/src/services/posts/posts.ts') + ], + ).toMatchSnapshot() + }) + + test('creates a service test', () => { + expect( + tsFiles[ + path.normalize('/path/to/project/api/src/services/posts/posts.test.ts') + ], + ).toMatchSnapshot() + }) + // Layout // (Including this in the test just to make sure we're testing at least one // web-side file that we don't have a custom template for) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldNoNest.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldNoNest.test.js index abbfb05f6fba..d3060e6a92a4 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldNoNest.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldNoNest.test.js @@ -22,7 +22,6 @@ describe('in javascript (default) mode', () => { files = await scaffold.files({ ...getDefaultArgs(defaults), model: 'Post', - tests: true, nestScaffoldByModel: false, }) }) @@ -303,7 +302,6 @@ describe('in typescript mode', () => { ...getDefaultArgs(defaults), model: 'Post', typescript: true, - tests: true, nestScaffoldByModel: false, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPath.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPath.test.js index be52063bcaaf..4457e4bbbb0a 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPath.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPath.test.js @@ -22,7 +22,6 @@ describe('admin/post', () => { filesLower = await scaffold.files({ model: 'Post', path: 'admin', - tests: true, nestScaffoldByModel: true, }) }) @@ -353,7 +352,6 @@ describe('Admin/Post', () => { filesUpper = await scaffold.files({ model: 'Post', path: 'Admin', - tests: true, nestScaffoldByModel: true, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMulti.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMulti.test.js index 2f65d0a0a645..60a3eaf3d221 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMulti.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMulti.test.js @@ -22,7 +22,6 @@ describe('admin/pages/post', () => { filesNestedLower = await scaffold.files({ model: 'Post', path: 'admin/pages', - tests: true, nestScaffoldByModel: true, }) }) @@ -363,7 +362,6 @@ describe('Admin/Pages/Post/Post', () => { filesNestedUpper = await scaffold.files({ model: 'Post', path: 'Admin/Pages', - tests: true, nestScaffoldByModel: true, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiNoNest.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiNoNest.test.js index 538995b4aaa2..86e45613461b 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiNoNest.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiNoNest.test.js @@ -22,7 +22,6 @@ describe('admin/pages/post', () => { filesNestedLower = await scaffold.files({ model: 'Post', path: 'admin/pages', - tests: true, nestScaffoldByModel: false, }) }) @@ -355,7 +354,6 @@ describe('Admin/Pages/Post/Post', () => { filesNestedUpper = await scaffold.files({ model: 'Post', path: 'Admin/Pages', - tests: true, nestScaffoldByModel: false, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiword.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiword.test.js index 0d79faa24e19..8e3da6ca4858 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiword.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiword.test.js @@ -22,7 +22,6 @@ describe('AdminPages/Post', () => { filesMultiwordUpper = await scaffold.files({ model: 'Post', path: 'AdminPages', - tests: true, nestScaffoldByModel: true, }) }) @@ -363,7 +362,6 @@ describe('admin-pages/Post', () => { filesMultiwordDash = await scaffold.files({ model: 'Post', path: 'admin-pages', - tests: true, nestScaffoldByModel: true, }) }) @@ -704,7 +702,6 @@ describe('admin_pages/Post', () => { filesMultiwordUnderscore = await scaffold.files({ model: 'Post', path: 'admin_pages', - tests: true, nestScaffoldByModel: true, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiwordNoNest.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiwordNoNest.test.js index fe0d4c7b7c82..5c51cecfe048 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiwordNoNest.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathMultiwordNoNest.test.js @@ -22,7 +22,6 @@ describe('AdminPages/Post', () => { filesMultiwordUpper = await scaffold.files({ model: 'Post', path: 'AdminPages', - tests: true, nestScaffoldByModel: false, }) }) @@ -355,7 +354,6 @@ describe('admin-pages/Post', () => { filesMultiwordDash = await scaffold.files({ model: 'Post', path: 'admin-pages', - tests: true, nestScaffoldByModel: false, }) }) @@ -688,7 +686,6 @@ describe('admin_pages/Post', () => { filesMultiwordUnderscore = await scaffold.files({ model: 'Post', path: 'admin_pages', - tests: true, nestScaffoldByModel: false, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathNoNest.test.js b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathNoNest.test.js index c246c191b291..afd37fb75a25 100644 --- a/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathNoNest.test.js +++ b/packages/cli/src/commands/generate/scaffold/__tests__/scaffoldPathNoNest.test.js @@ -22,7 +22,6 @@ describe('admin/Post', () => { filesLower = await scaffold.files({ model: 'Post', path: 'admin', - tests: true, nestScaffoldByModel: false, }) }) @@ -351,7 +350,6 @@ describe('Admin/Post', () => { filesUpper = await scaffold.files({ model: 'Post', path: 'Admin', - tests: true, nestScaffoldByModel: false, }) }) diff --git a/packages/cli/src/commands/generate/scaffold/scaffold.js b/packages/cli/src/commands/generate/scaffold/scaffold.js index ed0beb58da06..092770e827ac 100644 --- a/packages/cli/src/commands/generate/scaffold/scaffold.js +++ b/packages/cli/src/commands/generate/scaffold/scaffold.js @@ -43,6 +43,7 @@ import { files as sdlFiles, builder as sdlBuilder } from '../sdl/sdl' import { files as serviceFiles, builder as serviceBuilder, + buildScenario, } from '../service/service' // note a better way to do this is in https://github.com/redwoodjs/redwood/pull/3783/files @@ -142,11 +143,13 @@ export const files = async ({ docs, model: name, path: scaffoldPath = '', - tests = true, + tests, typescript = false, tailwind = false, force = false, nestScaffoldByModel, + stories, + serviceTests = true, }) => { const model = await getSchema(name) if (typeof nestScaffoldByModel === 'undefined') { @@ -167,8 +170,10 @@ export const files = async ({ name, pascalScaffoldPath, typescript, + tests, nestScaffoldByModel, templateStrings, + stories, )), ...(await sdlFiles({ ...getDefaultArgs(sdlBuilder), @@ -181,7 +186,7 @@ export const files = async ({ name, crud: true, relations: relationsForModel(model), - tests, + tests: serviceTests || tests, typescript, })), ...(await assetFiles(name, tailwind)), @@ -192,7 +197,9 @@ export const files = async ({ pascalScaffoldPath, typescript, nestScaffoldByModel, + tests, templateStrings, + stories, )), } } @@ -436,6 +443,7 @@ const modelRelatedVariables = (model) => { editableColumns, listFormattersImports, formattersImports, + relations, } } @@ -496,7 +504,9 @@ const pageFiles = async ( pascalScaffoldPath = '', generateTypescript, nestScaffoldByModel = true, + tests, templateStrings, + stories, ) => { const pluralName = pascalcase(pluralize(name)) const singularName = pascalcase(singularize(name)) @@ -507,24 +517,39 @@ const pageFiles = async ( let fileList = {} - const pages = fs.readdirSync( - customOrDefaultTemplatePath({ - side: 'web', - generator: 'scaffold', - templatePath: 'pages', - }), - ) + const pages = fs + .readdirSync( + customOrDefaultTemplatePath({ + side: 'web', + generator: 'scaffold', + templatePath: 'pages', + }), + ) + .filter((c) => { + if (!tests && /\.test\./.test(c)) { + return false + } + + if (!stories && /\.stories\./.test(c)) { + return false + } + + return true + }) for (const page of pages) { // Sanitize page names const outputPageName = page .replace(/Names/, pluralName) .replace(/Name/, singularName) + .replace(/\.ts\.template/, generateTypescript ? '.ts' : '.js') .replace(/\.tsx\.template/, generateTypescript ? '.tsx' : '.jsx') const finalFolder = (nestScaffoldByModel ? singularName + '/' : '') + - outputPageName.replace(/\.[jt]sx?/, '') + outputPageName + .replace(/(?:\.test|\.mock|\.stories)(?=\.ts|\.js)/, '') + .replace(/\.[jt]sx?/, '') const outputPath = path.join( getPaths().web.pages, @@ -556,12 +581,44 @@ const pageFiles = async ( return fileList } +/** + * Builds mock data for a given model. + * + * @param {Object} model - The model object containing information about the model. + * @param {string} model.name - The name of the model. + * @param {Array} model.fields - The fields of the model. + * @param {boolean} model.fields[].isId - Indicates if the field is an ID field. + * @param {string} model.fields[].type - The type of the field. + * @returns {Promise>} A promise that resolves to an array of mock data objects. + */ +const buildMockData = async (model) => { + const singularName = pascalcase(singularize(model.name)) + const camelName = camelcase(singularName) + const scenario = await buildScenario(singularName) + const idType = getIdType(model) + const intMockIdValues = [42, 43, 44] + + const mockIdValues = + idType === 'String' + ? intMockIdValues.map((value) => `'${value}'`) + : intMockIdValues + + // this assumes scenario will only have two objects + return Object.entries(scenario[camelName]).map(([_key, value], index) => ({ + __typename: singularName, + id: mockIdValues[index], + ...value.data, + })) +} + const componentFiles = async ( name, pascalScaffoldPath = '', generateTypescript, + tests, nestScaffoldByModel = true, templateStrings, + stories, ) => { const pluralName = pascalcase(pluralize(name)) const singularName = pascalcase(singularize(name)) @@ -572,23 +629,42 @@ const componentFiles = async ( const intForeignKeys = intForeignKeysForModel(model) let fileList = {} - const components = fs.readdirSync( - customOrDefaultTemplatePath({ - side: 'web', - generator: 'scaffold', - templatePath: 'components', - }), - ) + const components = fs + .readdirSync( + customOrDefaultTemplatePath({ + side: 'web', + generator: 'scaffold', + templatePath: 'components', + }), + ) + .filter((c) => { + if (!tests && /\.test\./.test(c)) { + return false + } + + if (!stories && /\.stories\./.test(c)) { + return false + } + + if (!stories && !tests && /\.mock\./.test(c)) { + return false + } + + return true + }) for (const component of components) { const outputComponentName = component .replace(/Names/, pluralName) .replace(/Name/, singularName) + .replace(/\.ts\.template/, generateTypescript ? '.ts' : '.js') .replace(/\.tsx\.template/, generateTypescript ? '.tsx' : '.jsx') const finalFolder = (nestScaffoldByModel ? singularName + '/' : '') + - outputComponentName.replace(/\.[jt]sx?/, '') + outputComponentName + .replace(/(?:\.test|\.mock|\.stories)(?=\.ts|\.js)/, '') + .replace(/\.[jt]sx?/, '') const outputPath = path.join( getPaths().web.components, @@ -617,6 +693,7 @@ const componentFiles = async ( useClientDirective, ...templateStrings, ...modelRelatedVariables(model), + mockData: await buildMockData(model), }, ) @@ -770,6 +847,15 @@ export const builder = (yargs) => { description: 'Generate test files', type: 'boolean', }) + .option('serviceTests', { + description: 'Generate test files for the service', + type: 'boolean', + default: true, + }) + .option('stories', { + description: 'Generate storybook files', + type: 'boolean', + }) .option('tailwind', { description: 'Generate TailwindCSS version of scaffold.css (automatically set to `true` if TailwindCSS config exists)', @@ -802,6 +888,8 @@ export const tasks = ({ typescript, javascript, tailwind, + stories, + serviceTests, }) => { return new Listr( [ @@ -817,6 +905,8 @@ export const tasks = ({ javascript, tailwind, force, + stories, + serviceTests, }) return writeFilesTask(f, { overwriteExisting: force }) }, @@ -869,10 +959,18 @@ export const handler = async ({ tailwind, docs = false, rollback, + stories, + serviceTests = true, }) => { if (tests === undefined) { tests = getConfig().generate.tests } + if (stories === undefined) { + stories = getConfig().generate.stories + } + if (serviceTests === undefined) { + serviceTests = getConfig().generate.serviceTests + } recordTelemetryAttributes({ command: 'generate scaffold', force, @@ -881,6 +979,8 @@ export const handler = async ({ tailwind, docs, rollback, + stories, + serviceTests, }) const { model, path } = splitPathAndModel(modelArg) @@ -897,6 +997,8 @@ export const handler = async ({ tests, typescript, tailwind, + stories, + serviceTests, }) if (rollback && !force) { prepareForRollback(t) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.mock.ts.template new file mode 100644 index 000000000000..ceb5273831c9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${camelName}: <%= JSON.stringify(mockData[0], null, 2) %> +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.stories.tsx.template new file mode 100644 index 000000000000..6d79f769ea0b --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.stories.tsx.template @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './Edit${pascalName}Cell' +import { standard } from './Edit${pascalName}Cell.mock' + +const meta: Meta = { + title: 'Cells/Edit${pascalName}Cell', + tags: ['autodocs'] +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + } +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + } +} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.test.tsx.template new file mode 100644 index 000000000000..ad5da441a20e --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/EditNameCell.test.tsx.template @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './Edit${pascalName}Cell' +import { standard } from './Edit${pascalName}Cell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('Edit${pascalName}Cell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Name.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/Name.mock.ts.template new file mode 100644 index 000000000000..ceb5273831c9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Name.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${camelName}: <%= JSON.stringify(mockData[0], null, 2) %> +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Name.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/Name.stories.tsx.template new file mode 100644 index 000000000000..5311ada81bbd --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Name.stories.tsx.template @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import ${pascalName} from './${pascalName}' + +const meta: Meta = { + component: ${pascalName}, + tags: ['autodocs'] +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Name.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/Name.test.tsx.template new file mode 100644 index 000000000000..b8aaa1284276 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Name.test.tsx.template @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import ${pascalName} from './${pascalName}' +import { standard } from './${pascalName}.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('${pascalName}', () => { + it('renders successfully', () => { + expect(() => { + render(<${pascalName} ${camelName}={standard().${camelName}} />) + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.mock.ts.template new file mode 100644 index 000000000000..245bdfc6f2f9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${camelName}: <%= JSON.stringify(mockData[0], null, 2) %> + }) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.stories.tsx.template new file mode 100644 index 000000000000..4a4e345f4869 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.stories.tsx.template @@ -0,0 +1,29 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Failure, Success } from './${pascalName}Cell' +import { standard } from './${pascalName}Cell.mock' + +const meta: Meta = { + title: 'Cells/${pascalName}Cell', + tags: ['autodocs'] +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + } +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + } +} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.test.tsx.template new file mode 100644 index 000000000000..56b514100535 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameCell.test.tsx.template @@ -0,0 +1,25 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Success } from './${pascalName}Cell' +import { standard } from './${pascalName}Cell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('${pascalName}Cell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.mock.ts.template new file mode 100644 index 000000000000..245bdfc6f2f9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${camelName}: <%= JSON.stringify(mockData[0], null, 2) %> + }) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.stories.tsx.template new file mode 100644 index 000000000000..220d95f8a0f9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.stories.tsx.template @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import ${pascalName}Form from './${pascalName}Form' + +const meta: Meta = { + component: ${pascalName}Form, + tags: ['autodocs'] +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.test.tsx.template new file mode 100644 index 000000000000..d24ad720a1bb --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NameForm.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ${pascalName}Form from './${pascalName}Form' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('${pascalName}Form', () => { + it('renders successfully', () => { + expect(() => { + render(<${pascalName}Form />) + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Names.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/Names.mock.ts.template new file mode 100644 index 000000000000..4253b27e8e90 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Names.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${pluralCamelName}: <%= JSON.stringify(mockData, null, 2) %>, + }) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Names.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/Names.stories.tsx.template new file mode 100644 index 000000000000..ff6ef5e9e697 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Names.stories.tsx.template @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import ${pluralPascalName} from './${pluralPascalName}' + +const meta: Meta = { + component: ${pluralPascalName}, + tags: ['autodocs'] +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/Names.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/Names.test.tsx.template new file mode 100644 index 000000000000..f06bb23c3320 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/Names.test.tsx.template @@ -0,0 +1,15 @@ +import { render } from '@redwoodjs/testing/web' + +import ${pluralPascalName} from './${pluralPascalName}' +import { standard } from './${pluralPascalName}.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('${pluralPascalName}', () => { + it('renders successfully', () => { + expect(() => { + render(<${pluralPascalName} ${pluralCamelName}={standard().${pluralCamelName}} />) + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.mock.ts.template new file mode 100644 index 000000000000..4253b27e8e90 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${pluralCamelName}: <%= JSON.stringify(mockData, null, 2) %>, + }) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.stories.tsx.template new file mode 100644 index 000000000000..8e07ab5cd1cd --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.stories.tsx.template @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Empty, Failure, Success } from './${pascalName}sCell' +import { standard } from './${pascalName}sCell.mock' + +const meta: Meta = { + title: 'Cells/${pascalName}sCell', + tags: ['autodocs'] +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + } +} + +export const empty: StoryObj = { + render: (args) => { + return Empty ? : <> + } +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + } +} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.test.tsx.template new file mode 100644 index 000000000000..01b817869aab --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.test.tsx.template @@ -0,0 +1,30 @@ +import { render } from '@redwoodjs/testing/web' + +import { Loading, Failure, Empty, Success } from './${pluralPascalName}Cell' +import { standard } from './${pluralPascalName}Cell.mock' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('${pluralPascalName}Cell', () => { + it('renders loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders failure successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders empty successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.tsx.template index 23c15e94bdae..f0d5113b22b3 100644 --- a/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.tsx.template +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NamesCell.tsx.template @@ -15,7 +15,12 @@ export const QUERY: TypedDocumentNode< > = gql` query Find${pluralPascalName} { ${pluralCamelName} {<% columns.forEach(column => { %> - <%= column.name %><% }) %> + <%= column.name %><% }) %><% relations.forEach(relation => { %> + ${relation} { + id + # Add the ${relation} fields you need here + } + <% }) %> } } ` diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NewName.mock.ts.template b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.mock.ts.template new file mode 100644 index 000000000000..245bdfc6f2f9 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.mock.ts.template @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + ${camelName}: <%= JSON.stringify(mockData[0], null, 2) %> + }) diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NewName.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.stories.tsx.template new file mode 100644 index 000000000000..a3ccd6e603ae --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.stories.tsx.template @@ -0,0 +1,26 @@ +// Pass props to your component by passing an `args` object to your story +// +// ```tsx +// export const Primary: Story = { +// args: { +// propName: propValue +// } +// } +// ``` +// +// See https://storybook.js.org/docs/react/writing-stories/args. + +import type { Meta, StoryObj } from '@storybook/react' + +import New${pascalName} from './New${pascalName}' + +const meta: Meta = { + component: New${pascalName}, + tags: ['autodocs'] +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/components/NewName.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.test.tsx.template new file mode 100644 index 000000000000..01a8f809b2a1 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/components/NewName.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import New${pascalName} from './New${pascalName}' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-components + +describe('New${pascalName}', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.stories.tsx.template new file mode 100644 index 000000000000..f3bc948f67a7 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.stories.tsx.template @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import Edit${pascalName}Page from './Edit${pascalName}Page' + +const meta: Meta = { + component: Edit${pascalName}Page, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.test.tsx.template new file mode 100644 index 000000000000..0079b96d0840 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/EditNamePage.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import Edit${pascalName}Page from './Edit${pascalName}Page' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('Edit${pascalName}Page', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.stories.tsx.template new file mode 100644 index 000000000000..69427f309a36 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.stories.tsx.template @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import ${pascalName}Page from './${pascalName}Page' + +const meta: Meta = { + component: ${pascalName}Page, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.test.tsx.template new file mode 100644 index 000000000000..40375b95b3f3 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NamePage.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ${pascalName}Page from './${pascalName}Page' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('${pascalName}Page', () => { + it('renders successfully', () => { + expect(() => { + render(<${pascalName}Page ${idName}="42" />) + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.stories.tsx.template new file mode 100644 index 000000000000..5b28d1a2b6d7 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.stories.tsx.template @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import ${pluralPascalName}Page from './${pluralPascalName}Page' + +const meta: Meta = { + component: ${pluralPascalName}Page, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.test.tsx.template new file mode 100644 index 000000000000..522857f384e1 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NamesPage.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ${pluralPascalName}Page from './${pluralPascalName}Page' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('${pluralPascalName}Page', () => { + it('renders successfully', () => { + expect(() => { + render(<${pluralPascalName}Page />) + }).not.toThrow() + }) +}) diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.stories.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.stories.tsx.template new file mode 100644 index 000000000000..edb8eb407c2e --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.stories.tsx.template @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import New${pascalName}Page from './New${pascalName}Page' + +const meta: Meta = { + component: New${pascalName}Page, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.test.tsx.template b/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.test.tsx.template new file mode 100644 index 000000000000..c3cb8c18d323 --- /dev/null +++ b/packages/cli/src/commands/generate/scaffold/templates/pages/NewNamePage.test.tsx.template @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import New${pascalName}Page from './New${pascalName}Page' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('New${pascalName}Page', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/tasks/test-project/codemods/mockValueSuffix.js b/tasks/test-project/codemods/mockValueSuffix.js new file mode 100644 index 000000000000..7a6441760819 --- /dev/null +++ b/tasks/test-project/codemods/mockValueSuffix.js @@ -0,0 +1,17 @@ +const stringWithSuffixRegex = /String\d+$/ + +export default (file, api) => { + const j = api.jscodeshift + const root = j(file.source) + + // Replaces the randomly generated value with a consistent one + return root + .find(j.Literal, { type: 'StringLiteral' }) + .forEach((obj) => { + const stringValue = obj.value.value + if (stringWithSuffixRegex.test(stringValue)) { + obj.value.value = `String${obj.value.loc.start.line}` + } + }) + .toSource() +} diff --git a/tasks/test-project/tui-tasks.js b/tasks/test-project/tui-tasks.js index 5958f4633b1a..e999460abf66 100644 --- a/tasks/test-project/tui-tasks.js +++ b/tasks/test-project/tui-tasks.js @@ -23,7 +23,7 @@ const RW_FRAMEWORK_PATH = path.join(__dirname, '../../') function fullPath(name, { addExtension } = { addExtension: true }) { if (addExtension) { - if (name.startsWith('api')) { + if (name.startsWith('api') || name.endsWith('.mock')) { name += '.ts' } else if (name.startsWith('web')) { name += '.tsx' @@ -736,11 +736,44 @@ export default DoublePage` task: async () => { await generateScaffold('post') - // Replace the random numbers in the scenario with consistent values + // Replace the random numbers in the scenario and mocks with consistent + // values await applyCodemod( 'scenarioValueSuffix.js', fullPath('api/src/services/posts/posts.scenarios'), ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('api/src/services/posts/posts.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/EditPostCell/EditPostCell.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/NewPost/NewPost.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/Post/Post.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/PostCell/PostCell.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/PostForm/PostForm.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/Posts/Posts.mock'), + ) + await applyCodemod( + 'mockValueSuffix.js', + fullPath('web/src/components/Post/PostsCell/PostsCell.mock'), + ) await exec(`yarn rwfw project:copy`, [], execaOptions) },