mirror of
https://github.com/withastro/astro.git
synced 2025-01-06 22:10:10 -05:00
Actions: fix bad action result for actions with empty return value (#11813)
* fix: correctly handle empty action response * fix(test): add logout button test * chore: changeset
This commit is contained in:
parent
4db5c74dd1
commit
3f7630afd6
6 changed files with 42 additions and 3 deletions
5
.changeset/selfish-pianos-notice.md
Normal file
5
.changeset/selfish-pianos-notice.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes unexpected `undefined` value when calling an action from the client without a return value.
|
|
@ -125,4 +125,12 @@ test.describe('Astro Actions - Blog', () => {
|
|||
await expect(comments).toBeVisible();
|
||||
await expect(comments).toContainText(body);
|
||||
});
|
||||
|
||||
test('Logout action redirects', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/blog/first-post/'));
|
||||
|
||||
const logoutButton = page.getByTestId('logout-button');
|
||||
await logoutButton.click();
|
||||
await expect(page).toHaveURL(astro.resolveUrl('/blog/'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,11 +3,16 @@ import { ActionError, defineAction, z } from 'astro:actions';
|
|||
import { getCollection } from 'astro:content';
|
||||
|
||||
export const server = {
|
||||
logout: defineAction({
|
||||
handler: async () => {
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
},
|
||||
}),
|
||||
blog: {
|
||||
like: defineAction({
|
||||
input: z.object({ postId: z.string() }),
|
||||
handler: async ({ postId }) => {
|
||||
await new Promise((r) => setTimeout(r, 1000));
|
||||
await new Promise((r) => setTimeout(r, 500));
|
||||
|
||||
const { likes } = await db
|
||||
.update(Likes)
|
||||
|
@ -30,7 +35,7 @@ export const server = {
|
|||
body: z.string().min(10),
|
||||
}),
|
||||
handler: async ({ postId, author, body }) => {
|
||||
if (!(await getCollection('blog')).find(b => b.id === postId)) {
|
||||
if (!(await getCollection('blog')).find((b) => b.id === postId)) {
|
||||
throw new ActionError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'Post not found',
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { actions } from 'astro:actions';
|
||||
import { navigate } from 'astro:transitions/client';
|
||||
|
||||
export function Logout() {
|
||||
return (
|
||||
<button
|
||||
data-testid="logout-button"
|
||||
onClick={async () => {
|
||||
const { error } = await actions.logout();
|
||||
if (!error) navigate('/blog/');
|
||||
}}
|
||||
>
|
||||
Logout
|
||||
</button>
|
||||
);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
---
|
||||
import { type CollectionEntry, getCollection, getEntry } from 'astro:content';
|
||||
import BlogPost from '../../layouts/BlogPost.astro';
|
||||
import { Logout } from '../../components/Logout';
|
||||
import { db, eq, Comment, Likes } from 'astro:db';
|
||||
import { Like } from '../../components/Like';
|
||||
import { PostComment } from '../../components/PostComment';
|
||||
|
@ -39,6 +40,8 @@ const commentPostIdOverride = Astro.url.searchParams.get('commentPostIdOverride'
|
|||
<BlogPost {...post.data}>
|
||||
<Like postId={post.id} initial={initialLikes?.likes ?? 0} client:load />
|
||||
|
||||
<Logout client:load />
|
||||
|
||||
<form>
|
||||
<input type="hidden" name="like" />
|
||||
<button type="submit" aria-label="get-request">Like GET request</button>
|
||||
|
|
|
@ -93,7 +93,9 @@ async function handleAction(param, path, context) {
|
|||
body,
|
||||
headers,
|
||||
});
|
||||
if (rawResult.status === 204) return;
|
||||
if (rawResult.status === 204) {
|
||||
return deserializeActionResult({ type: 'empty', status: 204 });
|
||||
}
|
||||
|
||||
return deserializeActionResult({
|
||||
type: rawResult.ok ? 'data' : 'error',
|
||||
|
|
Loading…
Reference in a new issue