Skip to content

Commit

Permalink
Merge branch 'feature/52-nextjs-v13-backend-view-newsletter' into fea…
Browse files Browse the repository at this point in the history
…ture/53-nextjs-v13-frontend-view-newsletter
  • Loading branch information
tednguyendev committed Jun 13, 2023
2 parents 9ec4ec7 + ebfad61 commit fe0f1f7
Show file tree
Hide file tree
Showing 28 changed files with 4,520 additions and 4,552 deletions.
8,736 changes: 4,368 additions & 4,368 deletions nextjs-12/yarn.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions nextjs-13/src/app/api/v1/me/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ describe('GET /v1/me', () => {
appHandler.mockImplementation((req, callback) => callback(user));
dbClientMock.user.findUnique.mockResolvedValue(user);

const res = await GET({});
const body = await res.json();
const response = await GET({});
const body = await response.json();

expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
expect(body.user).toMatchObject<User>({
id: '1',
name: expect.any(String),
Expand Down
40 changes: 22 additions & 18 deletions nextjs-13/src/app/api/v1/newsletter/[id]/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ describe('DELETE /v1/newsletter/:id', () => {
});

describe('newsletter exists', () => {
it('delete the newsletter', async () => {
const res = await DELETE({}, { params: { id: newsletter.id } });
it('deletes the newsletter', async () => {
const response = await DELETE({}, { params: { id: newsletter.id } });

expect(deleteNewsletter).toHaveBeenCalledWith(newsletter.id, user.id);
expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
});
});

Expand All @@ -41,11 +41,11 @@ describe('DELETE /v1/newsletter/:id', () => {
});

it('returns error', async () => {
const res = await DELETE({}, { params: { id: newsletter.id } });
const responseBody = await res.json();
const response = await DELETE({}, { params: { id: newsletter.id } });
const responseBody = await response.json();

expect(deleteNewsletter).toHaveBeenCalledWith(newsletter.id, user.id);
expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Newsletter not exists',
});
Expand Down Expand Up @@ -73,11 +73,13 @@ describe('PUT /v1/newsletter/:id', () => {
});

describe('newsletter exists', () => {
it('delete the newsletter', async () => {
const res = await PUT(requestBody, { params: { id: newsletter.id } });
it('updates the newsletter', async () => {
const response = await PUT(requestBody, {
params: { id: newsletter.id },
});

expect(updateNewsletter).toHaveBeenCalledWith(args);
expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
});
});

Expand All @@ -87,11 +89,13 @@ describe('PUT /v1/newsletter/:id', () => {
});

it('returns error', async () => {
const res = await PUT(requestBody, { params: { id: newsletter.id } });
const responseBody = await res.json();
const response = await PUT(requestBody, {
params: { id: newsletter.id },
});
const responseBody = await response.json();

expect(updateNewsletter).toHaveBeenCalledWith(args);
expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Newsletter not exists',
});
Expand All @@ -105,11 +109,11 @@ describe('GET /v1/newsletter/:id', () => {
const newsletter = newsletterFactory;
findNewsletter.mockResolvedValue(newsletter);

const res = await GET({}, { params: { id: newsletter.id } });
const responseBody = await res.json();
const response = await GET({}, { params: { id: newsletter.id } });
const responseBody = await response.json();

expect(findNewsletter).toHaveBeenCalledWith(newsletter.id);
expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
expect(responseBody.record).toMatchObject({
id: newsletter.id,
name: expect.any(String),
Expand All @@ -124,11 +128,11 @@ describe('GET /v1/newsletter/:id', () => {
it('returns error', async () => {
findNewsletter.mockResolvedValue(null);

const res = await GET({}, { params: { id: '1' } });
const responseBody = await res.json();
const response = await GET({}, { params: { id: '1' } });
const responseBody = await response.json();

expect(findNewsletter).toHaveBeenCalledWith('1');
expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Newsletter not exists',
});
Expand Down
18 changes: 9 additions & 9 deletions nextjs-13/src/app/api/v1/newsletter/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ describe('POST /v1/newsletter', () => {

createNewsletter.mockResolvedValue(newsletter);

const res = await POST(requestBody);
const responseBody = await res.json();
const response = await POST(requestBody);
const responseBody = await response.json();

expect(createNewsletter).toHaveBeenCalledWith({
name: newsletter.name,
content: newsletter.content,
user: { connect: { id: user.id } },
});
expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
expect(responseBody.newsletter).toMatchObject<Newsletter>({
id: newsletterAttributes.id,
name: expect.any(String),
Expand Down Expand Up @@ -82,15 +82,15 @@ describe('POST /v1/newsletter', () => {
throw new Prisma.PrismaClientValidationError();
});

const res = await POST(requestBody);
const responseBody = await res.json();
const response = await POST(requestBody);
const responseBody = await response.json();

expect(createNewsletter).toHaveBeenCalledWith({
name: null,
content: content,
user: { connect: { id: user.id } },
});
expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: invalidParamsMessage,
});
Expand All @@ -106,11 +106,11 @@ describe('GET /v1/newsletter', () => {
appHandler.mockImplementation((req, callback) => callback(user, {}));
queryNewsletters.mockResolvedValue([newsletter]);

const res = await GET({});
const responseBody = await res.json();
const response = await GET({});
const responseBody = await response.json();

expect(queryNewsletters).toHaveBeenCalledWith(user.id);
expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
expect(responseBody.records[0]).toMatchObject<Newsletter>({
id: newsletterAttributes.id,
name: expect.any(String),
Expand Down
22 changes: 11 additions & 11 deletions nextjs-13/src/app/api/v1/newsletter/send/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ describe('POST /v1/newsletter/send', () => {
callback(user, requestBody)
);

const res = await POST(requestBody);
const responseBody = await res.json();
const response = await POST(requestBody);
const responseBody = await response.json();

expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Invalid email',
});
Expand All @@ -60,10 +60,10 @@ describe('POST /v1/newsletter/send', () => {
callback(user, requestBody)
);

const res = await POST(requestBody);
const responseBody = await res.json();
const response = await POST(requestBody);
const responseBody = await response.json();

expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Invalid newsletters',
});
Expand All @@ -88,10 +88,10 @@ describe('POST /v1/newsletter/send', () => {

countNewsletters.mockResolvedValue(0);

const res = await POST(requestBody);
const responseBody = await res.json();
const response = await POST(requestBody);
const responseBody = await response.json();

expect(res.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(response.status).toBe(StatusCodes.UNPROCESSABLE_ENTITY);
expect(responseBody).toMatchObject({
message: 'Invalid newsletters',
});
Expand All @@ -113,9 +113,9 @@ describe('POST /v1/newsletter/send', () => {

countNewsletters.mockResolvedValue(data.ids.length);

const res = await POST(requestBody);
const response = await POST(requestBody);

expect(res.status).toBe(StatusCodes.OK);
expect(response.status).toBe(StatusCodes.OK);
expect(sendMailQueue.add).toHaveBeenCalledWith('sendMail', {
ids: data.ids,
to: data.email,
Expand Down
2 changes: 1 addition & 1 deletion nextjs-13/src/app/auth/sign-in/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const AuthSignInPage = () => {
<Head>
<title>Sign in | NextNewsletter 🚀</title>
</Head>
<h4>NextNewsletter 🚀</h4>
<h4 className="title">NextNewsletter 🚀</h4>
<button
className="btn"
data-testid="loginButton"
Expand Down
4 changes: 2 additions & 2 deletions nextjs-13/src/app/newsletter/[id]/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ describe('ViewNewsletter', () => {
expect(screen.getByTestId('clip-loader')).toBeInTheDocument();
});

it('NOT renders NewsletterDetail', async () => {
it('does NOT render NewsletterDetail', async () => {
render(<ViewNewsletter />);

expect(screen.queryByTestId('newsletter')).not.toBeVisible();
});
});

describe('giving NOT fetching data', () => {
it('NOT renders ClipLoader', async () => {
it('does NOT render ClipLoader', async () => {
render(<ViewNewsletter />);

await waitFor(() => {
Expand Down
6 changes: 3 additions & 3 deletions nextjs-13/src/app/newsletter/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const ViewNewsletter = () => {

async function fetchRecords() {
try {
const res = await requestManager('GET', `v1/newsletter/${id}`);
const response = await requestManager('GET', `v1/newsletter/${id}`);

return res.record;
return response.record;
} catch (error) {
redirect('/auth/sign-in');
}
Expand All @@ -32,7 +32,7 @@ const ViewNewsletter = () => {

return (
<div className="view-newsletter" data-testid="view-newsletter">
<Suspense fallback={<ClipLoader loading={true} size={150} />}>
<Suspense fallback={<ClipLoader loading={true} size={75} />}>
<NewsletterDetail promise={promise} />
</Suspense>
</div>
Expand Down
4 changes: 2 additions & 2 deletions nextjs-13/src/app/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ describe('Home', () => {
expect(screen.getByTestId('clip-loader')).toBeInTheDocument();
});

it('NOT renders ListNewsletter', async () => {
it('does NOT render ListNewsletter', async () => {
render(<Home />);

expect(screen.queryByTestId('list-newsletter')).not.toBeVisible();
});
});

describe('giving NOT fetching data', () => {
it('NOT renders ClipLoader', async () => {
it('does NOT render ClipLoader', async () => {
render(<Home />);

await waitFor(() => {
Expand Down
6 changes: 3 additions & 3 deletions nextjs-13/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const Home = () => {
const [promise, setPromise] = useState();

async function fetchRecords() {
const res = await requestManager('GET', 'v1/newsletter');
const response = await requestManager('GET', 'v1/newsletter');

return res.records;
return response.records;
}

async function getData() {
Expand Down Expand Up @@ -53,7 +53,7 @@ const Home = () => {
<div className="home">
<div>
<h3>Your Newsletters</h3>
<Suspense fallback={<ClipLoader loading={true} size={150} />}>
<Suspense fallback={<ClipLoader loading={true} size={75} />}>
<ListNewsletter
promise={promise}
getData={getData}
Expand Down
19 changes: 12 additions & 7 deletions nextjs-13/src/app/send/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ const SendNewsletter = () => {
const [email, setEmail] = useState('');

async function fetchRecords() {
const res = await requestManager('GET', 'v1/newsletter');
const response = await requestManager('GET', 'v1/newsletter');

return res.records;
return response.records;
}

async function getData() {
Expand Down Expand Up @@ -66,10 +66,12 @@ const SendNewsletter = () => {
<div>
<h3 data-testid="title">Your Newsletters</h3>
{loading ? (
<ClipLoader loading={loading} size={150} />
<ClipLoader loading={loading} size={75} />
) : (
<form onSubmit={handleSubmit}>
<label htmlFor="email">Email</label>
<form className="newsletter-form" onSubmit={handleSubmit}>
<label className="newsletter-label" htmlFor="email">
Email
</label>
<br />

<input
Expand All @@ -78,14 +80,17 @@ const SendNewsletter = () => {
required
value={email}
onChange={(event) => setEmail(event.target.value)}
className="text-input"
placeholder={'Enter email'}
/>
<br />

<label htmlFor="newsletters">Newsletters</label>
<label className="newsletter-label" htmlFor="newsletters">
Newsletters
</label>
<br />

<Suspense fallback={<ClipLoader loading={true} size={150} />}>
<Suspense fallback={<ClipLoader loading={true} size={75} />}>
<MultiSelectWrapper
promise={promise}
selected={selected}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const CreateOrUpdateNewsletterModal = ({
{loading ? (
<ClipLoader
loading={loading}
size={150}
size={75}
className="ReactModalPortal__spinner"
/>
) : (
Expand Down
2 changes: 1 addition & 1 deletion nextjs-13/src/components/Dropdown/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('Dropdown', () => {
});

describe('given the menu is NOT displayed', () => {
it('does NOT shows sign out button', async () => {
it('does NOT show sign out button', async () => {
render(<Dropdown />);

expect(screen.queryByText('Sign out')).not.toBeInTheDocument();
Expand Down
2 changes: 1 addition & 1 deletion nextjs-13/src/components/Header/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Header', () => {
});

describe('given without a user', () => {
it('does NOT renders the user name', () => {
it('does NOT render the user name', () => {
renderHeader({});

const header = screen.getByTestId('appHeader');
Expand Down
Loading

0 comments on commit fe0f1f7

Please sign in to comment.