Skip to content

Commit

Permalink
Actions: fix bad action result for actions with empty return value (#…
Browse files Browse the repository at this point in the history
…11813)

* fix: correctly handle empty action response

* fix(test): add logout button test

* chore: changeset
  • Loading branch information
bholmesdev committed Aug 22, 2024
1 parent 4db5c74 commit 3f7630a
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/selfish-pianos-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes unexpected `undefined` value when calling an action from the client without a return value.
8 changes: 8 additions & 0 deletions packages/astro/e2e/actions-blog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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/'));
});
});
9 changes: 7 additions & 2 deletions packages/astro/e2e/fixtures/actions-blog/src/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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',
Expand Down
16 changes: 16 additions & 0 deletions packages/astro/e2e/fixtures/actions-blog/src/components/Logout.tsx
Original file line number Diff line number Diff line change
@@ -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>
);
}
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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>
Expand Down
4 changes: 3 additions & 1 deletion packages/astro/templates/actions.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit 3f7630a

Please sign in to comment.