Continuing the tutorial.

This commit is contained in:
2022-04-21 17:11:22 -04:00
parent 0c47db9001
commit bb1638b38e
18 changed files with 221 additions and 11 deletions

View File

@@ -21,8 +21,10 @@ const Routes = () => {
<Route path="/posts" page={PostPostsPage} name="posts" /> <Route path="/posts" page={PostPostsPage} name="posts" />
</Set> </Set>
<Set wrap={BlogLayout}> <Set wrap={BlogLayout}>
<Route path="/article/{id:Int}" page={ArticlePage} name="article" />
<Route path="/about" page={AboutPage} name="about" /> <Route path="/about" page={AboutPage} name="about" />
<Route path="/" page={HomePage} name="home" /> <Route path="/" page={HomePage} name="home" />
<Route path="/contact" page={ContactPage} name="contact" />
</Set> </Set>
<Route notfound page={NotFoundPage} /> <Route notfound page={NotFoundPage} />
</Router> </Router>

View File

@@ -0,0 +1,17 @@
import { Link, routes } from '@redwoodjs/router';
const Article = ({article}) => {
return (
<article>
<header>
<h2>
<Link to={routes.article({ id: article.id })}>{article.title}</Link>
</h2>
</header>
<div>{article.body}</div>
<div>Posted at: {article.createdAt}</div>
</article>
)
}
export default Article

View File

@@ -0,0 +1,7 @@
import Article from './Article'
export const generated = () => {
return <Article />
}
export default { title: 'Components/Article' }

View File

@@ -0,0 +1,14 @@
import { render } from '@redwoodjs/testing/web'
import Article from './Article'
// Improve this test with help from the Redwood Testing Doc:
// https://redwoodjs.com/docs/testing#testing-components
describe('Article', () => {
it('renders successfully', () => {
expect(() => {
render(<Article />)
}).not.toThrow()
})
})

View File

@@ -0,0 +1,24 @@
import Article from 'src/components/Article';
export const QUERY = gql`
query FindArticleQuery($id: Int!) {
article: post(id: $id) {
id
title
body
createdAt
}
}
`
export const Loading = () => <div>Loading...</div>
export const Empty = () => <div>Empty</div>
export const Failure = ({ error }) => (
<div style={{ color: 'red' }}>Error: {error.message}</div>
)
export const Success = ({ article }) => {
return <Article article={article} />
}

View File

@@ -0,0 +1,6 @@
// Define your own mock data here:
export const standard = () => ({
article: {
id: 42,
},
})

View File

@@ -0,0 +1,20 @@
import { Loading, Empty, Failure, Success } from './ArticleCell'
import { standard } from './ArticleCell.mock'
export const loading = () => {
return Loading ? <Loading /> : null
}
export const empty = () => {
return Empty ? <Empty /> : null
}
export const failure = () => {
return Failure ? <Failure error={new Error('Oh no')} /> : null
}
export const success = () => {
return Success ? <Success {...standard()} /> : null
}
export default { title: 'Cells/ArticleCell' }

View File

@@ -0,0 +1,41 @@
import { render } from '@redwoodjs/testing/web'
import { Loading, Empty, Failure, Success } from './ArticleCell'
import { standard } from './ArticleCell.mock'
// Generated boilerplate tests do not account for all circumstances
// and can fail without adjustments, e.g. Float and DateTime types.
// Please refer to the RedwoodJS Testing Docs:
// https://redwoodjs.com/docs/testing#testing-cells
// https://redwoodjs.com/docs/testing#jest-expect-type-considerations
describe('ArticleCell', () => {
it('renders Loading successfully', () => {
expect(() => {
render(<Loading />)
}).not.toThrow()
})
it('renders Empty successfully', async () => {
expect(() => {
render(<Empty />)
}).not.toThrow()
})
it('renders Failure successfully', async () => {
expect(() => {
render(<Failure error={new Error('Oh no')} />)
}).not.toThrow()
})
// When you're ready to test the actual output of your component render
// you could test that, for example, certain text is present:
//
// 1. import { screen } from '@redwoodjs/testing/web'
// 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument()
it('renders Success successfully', async () => {
expect(() => {
render(<Success article={standard().article} />)
}).not.toThrow()
})
})

View File

@@ -1,3 +1,5 @@
import Article from 'src/components/Article';
export const QUERY = gql` export const QUERY = gql`
query ArticlesQuery { query ArticlesQuery {
articles: posts { articles: posts {
@@ -19,16 +21,10 @@ export const Failure = ({ error }) => (
export const Success = ({ articles }) => { export const Success = ({ articles }) => {
return ( return (
<ul> <>
{articles.map((article) => ( {articles.map((article) => (
<article key={article.id}> <Article key={article.id} article={article} />
<header>
<h2>{article.title}</h2>
</header>
<p>{article.body}</p>
<div>Created at: {article.createdAt}</div>
</article>
))} ))}
</ul> </>
) )
} }

View File

@@ -5,6 +5,7 @@ import {
Label, Label,
TextField, TextField,
Submit, Submit,
TextAreaField
} from '@redwoodjs/forms' } from '@redwoodjs/forms'
const PostForm = (props) => { const PostForm = (props) => {
@@ -48,7 +49,7 @@ const PostForm = (props) => {
Body Body
</Label> </Label>
<TextField <TextAreaField
name="body" name="body"
defaultValue={props.post?.body} defaultValue={props.post?.body}
className="rw-input" className="rw-input"

View File

@@ -14,6 +14,9 @@ const BlogLayout = ({ children }) => {
<li> <li>
<Link to={routes.about()}>About</Link> <Link to={routes.about()}>About</Link>
</li> </li>
<li>
<Link to={routes.contact()}>Contact Us</Link>
</li>
</ul> </ul>
</nav> </nav>
</header> </header>

View File

@@ -15,7 +15,7 @@ const PostsLayout = ({ children }) => {
<div className="rw-button-icon">+</div> New Post <div className="rw-button-icon">+</div> New Post
</Link> </Link>
</header> </header>
<main className="rw-main">{children}</main> <main className="rw-main" style={{marginLeft: 'auto', marginRight: 'auto', width: '50%'}}>{children}</main>
</div> </div>
) )
} }

View File

@@ -0,0 +1,13 @@
import { MetaTags } from '@redwoodjs/web'
import ArticleCell from 'src/components/ArticleCell';
const ArticlePage = ({id}) => {
return (
<>
<MetaTags title="Article" description="Article page" />
<ArticleCell id={id} />
</>
)
}
export default ArticlePage

View File

@@ -0,0 +1,7 @@
import ArticlePage from './ArticlePage'
export const generated = () => {
return <ArticlePage />
}
export default { title: 'Pages/ArticlePage' }

View File

@@ -0,0 +1,14 @@
import { render } from '@redwoodjs/testing/web'
import ArticlePage from './ArticlePage'
// Improve this test with help from the Redwood Testing Doc:
// https://redwoodjs.com/docs/testing#testing-pages-layouts
describe('ArticlePage', () => {
it('renders successfully', () => {
expect(() => {
render(<ArticlePage />)
}).not.toThrow()
})
})

View File

@@ -0,0 +1,24 @@
import { MetaTags } from '@redwoodjs/web'
import { Form, TextField, Submit, TextAreaField } from '@redwoodjs/forms'
const ContactPage = () => {
const onSubmit = (data) => {
console.log(data)
}
return (
<>
<MetaTags title="Contact" description="Contact page" />
<Form onSubmit={onSubmit}>
<label htmlFor="name">Name</label>
<TextField name="name" validation={{required: true}} />
<label htmlFor="email">Email</label>
<TextField name="email" validation={{required: true}} />
<label htmlFor="message">Message</label>
<TextAreaField name="message" validation={{required: true}} />
<Submit>Save</Submit>
</Form>
</>
)
}
export default ContactPage

View File

@@ -0,0 +1,7 @@
import ContactPage from './ContactPage'
export const generated = () => {
return <ContactPage />
}
export default { title: 'Pages/ContactPage' }

View File

@@ -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(<ContactPage />)
}).not.toThrow()
})
})