Skip to content

Commit

Permalink
feat: Add /_fake/update_action_attempt (#207)
Browse files Browse the repository at this point in the history
* Add /_fake/update_action_attempt, update action_attempt zod schema

* Add test

* ci: Format code

* Don't allow updating action_type

* ci: Generate code

* Update the endpoint to accept a union of successful and failed action attempt payload, update the test

* Format

---------

Co-authored-by: Seam Bot <[email protected]>
  • Loading branch information
andrii-balitskyi and seambot authored Jul 17, 2024
1 parent f8b6b00 commit e6b60f6
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/lib/zod/action_attempt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ export const action_attempt = z.discriminatedUnion("status", [
z.object({
status: z.literal("success"),
action_type: z.string(),
action_attempt_id: z.string().uuid(),
action_attempt_id: z.string(),
result: z.any(),
error: z.null(),
}),
z.object({
status: z.literal("pending"),
action_type: z.string(),
action_attempt_id: z.string().uuid(),
action_attempt_id: z.string(),
result: z.null(),
error: z.null(),
}),
z.object({
status: z.literal("error"),
action_type: z.string(),
action_attempt_id: z.string().uuid(),
action_attempt_id: z.string(),
result: z.null(),
error: z.object({
type: z.string(),
Expand Down
45 changes: 45 additions & 0 deletions src/pages/api/_fake/update_action_attempt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { NotFoundException } from "nextlove"
import { z } from "zod"

import { withRouteSpec } from "lib/middleware/with-route-spec.ts"

export default withRouteSpec({
auth: "none",
methods: ["PATCH", "POST"],
jsonBody: z.union([
z.object({
status: z.literal("success"),
action_attempt_id: z.string(),
result: z.any(),
}),
z.object({
status: z.literal("error"),
action_attempt_id: z.string(),
error: z.object({
type: z.string(),
message: z.string(),
}),
}),
]),
jsonResponse: z.object({}),
} as const)(async (req, res) => {
const { action_attempt_id, ...action_attempt_update_payload } = req.body

const action_attempt = req.db.action_attempts.find(
(a) => a.action_attempt_id === action_attempt_id,
)

if (action_attempt == null) {
throw new NotFoundException({
type: "action_attempt_not_found",
message: "Action attempt not found",
})
}

req.db.updateActionAttempt({
action_attempt_id,
...action_attempt_update_payload,
})

res.status(200).json({})
})
24 changes: 24 additions & 0 deletions src/route-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,30 @@ export type Routes = {
ok: boolean
}
}
"/_fake/update_action_attempt": {
route: "/_fake/update_action_attempt"
method: "PATCH" | "POST"
queryParams: {}
jsonBody:
| {
status: "success"
action_attempt_id: string
result?: any
}
| {
status: "error"
action_attempt_id: string
error: {
type: string
message: string
}
}
commonParams: {}
formData: {}
jsonResponse: {
ok: boolean
}
}
"/access_codes/create": {
route: "/access_codes/create"
method: "POST"
Expand Down
60 changes: 60 additions & 0 deletions test/api/_fake/update_action_attempt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import test, { type ExecutionContext } from "ava"

import {
getTestServer,
type SimpleAxiosError,
} from "fixtures/get-test-server.ts"

test("PATCH /_fake/update_action_attempt", async (t: ExecutionContext) => {
const { axios, db, seed } = await getTestServer(t)

const {
data: {
action_attempt: { action_attempt_id },
},
} = await axios.post(
"/locks/lock_door",
{
device_id: seed.ws2.device1_id,
},
{
headers: {
Authorization: `Bearer ${seed.ws2.cst}`,
},
},
)

const payload = {
action_attempt_id,
status: "success" as const,
result: {},
}

const { status } = await axios.patch("/_fake/update_action_attempt", payload)

t.is(status, 200)

const updated_action_attempt = db.action_attempts.find(
(a) => a.action_attempt_id === action_attempt_id,
)

t.truthy(updated_action_attempt)
t.is(updated_action_attempt?.status, "success")
t.deepEqual(updated_action_attempt?.result, {})
})

test("PATCH /_fake/update_action_attempt - invalid action_attempt_id", async (t: ExecutionContext) => {
const { axios } = await getTestServer(t)

const payload = {
action_attempt_id: "non-existent-action-attempt-id",
status: "success" as const,
result: {},
}

const err = await t.throwsAsync<SimpleAxiosError>(
async () => await axios.patch("/_fake/update_action_attempt", payload),
)

t.is(err?.status, 404)
})

0 comments on commit e6b60f6

Please sign in to comment.