Skip to content

Commit bbabf5d

Browse files
authored
Merge pull request #239 from twilio-labs/fix/orderReadyNotificationLanguage
fix: pass event.language when sending order-ready notification
2 parents f034be7 + 4809b80 commit bbabf5d

30 files changed

Lines changed: 408 additions & 182 deletions

File tree

.env.example

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ TWILIO_ACCOUNT_SID=
99
TWILIO_AUTH_TOKEN=FOR_SIGNATURE_VERIFICATION
1010
TWILIO_API_KEY=
1111
TWILIO_API_SECRET=
12-
TWILIO_PHONE_NUMBER=
1312
TWILIO_MESSAGING_SERVICE_SID=
1413
TWILIO_SYNC_SERVICE_SID=
1514
TWILIO_VERIFY_SERVICE_SID=

.github/workflows/deploy.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ jobs:
3131
TWILIO_AUTH_TOKEN: ${{ secrets.TWILIO_AUTH_TOKEN }}
3232
TWILIO_API_KEY: ${{ secrets.TWILIO_API_KEY }}
3333
TWILIO_API_SECRET: ${{ secrets.TWILIO_API_SECRET }}
34-
TWILIO_PHONE_NUMBER: ${{ vars.TWILIO_PHONE_NUMBER }}
3534
TWILIO_MESSAGING_SERVICE_SID: ${{ vars.TWILIO_MESSAGING_SERVICE_SID }}
3635
TWILIO_SYNC_SERVICE_SID: ${{ vars.TWILIO_SYNC_SERVICE_SID }}
3736
TWILIO_VERIFY_SERVICE_SID: ${{ vars.TWILIO_VERIFY_SERVICE_SID }}
@@ -62,7 +61,6 @@ jobs:
6261
TWILIO_AUTH_TOKEN=$TWILIO_AUTH_TOKEN
6362
TWILIO_API_KEY=$TWILIO_API_KEY
6463
TWILIO_API_SECRET=$TWILIO_API_SECRET
65-
TWILIO_PHONE_NUMBER=$TWILIO_PHONE_NUMBER
6664
TWILIO_MESSAGING_SERVICE_SID=$TWILIO_MESSAGING_SERVICE_SID
6765
TWILIO_SYNC_SERVICE_SID=$TWILIO_SYNC_SERVICE_SID
6866
TWILIO_VERIFY_SERVICE_SID=$TWILIO_VERIFY_SERVICE_SID

DEPLOYMENT.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ TWILIO_API_SECRET="xxxxx"
2626
TWILIO_VERIFY_SERVICE_SID="VAxxxxx"
2727
TWILIO_SYNC_SERVICE_SID="ISxxxxx"
2828
TWILIO_MESSAGING_SERVICE_SID="MGxxxxx"
29-
TWILIO_PHONE_NUMBER="+15551234567"
3029
```
3130

3231
The deploy script uses `.env.local` for both build-time values, such as `NEXT_PUBLIC_*`, and runtime environment variables.

__tests__/e2e/browse-events.spec.ts

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { test, expect, type Page } from "@playwright/test";
22
import { Privilege } from "@/proxy";
3+
import { createEvent, deleteIfExists } from "../global-setup";
34

45
test.describe("[no login]", () => {
56
test("should not be navigable", async ({ page }) => {
@@ -64,10 +65,6 @@ test.describe("[mixologist]", () => {
6465
});
6566

6667
test.describe("[admin]", () => {
67-
// These tests mutate the shared "test-event" fixture (item selection, mode);
68-
// run them in order rather than in parallel to avoid clobbering each other.
69-
test.describe.configure({ mode: "serial" });
70-
7168
test("should be navigable to an existing event", async ({
7269
page,
7370
context,
@@ -132,41 +129,69 @@ test.describe("[admin]", () => {
132129
test("should not be able to select more than 9 menu items + navigate to smoothie", async ({
133130
page,
134131
context,
135-
}) => {
136-
await context.addCookies([
137-
{
138-
name: "privilege",
139-
value: Privilege.ADMIN,
140-
url: "http://localhost:3000",
141-
},
142-
]);
143-
await context.setExtraHTTPHeaders({
144-
Authorization: `Basic ${btoa(process.env.ADMIN_LOGIN || ":")}`,
145-
});
146-
147-
await page.goto("http://localhost:3000/event/test-event");
148-
149-
await page.waitForTimeout(2000);
150-
151-
// TestEvent starts with 1 item selected (Espresso); select 9 more unselected
152-
// items to reach the 10-item cap. Scoped to the literal aria-pressed="false"
153-
// attribute (not the role=button pressed filter) — Chromium's accessibility
154-
// tree reports pressed:false by default for any plain button, which would
155-
// otherwise also match the header's "Log out" button and toast dismiss buttons.
156-
const unselectedItem = page.locator('button[aria-pressed="false"]');
157-
for (let i = 0; i < 9; i++) {
132+
}, testInfo) => {
133+
// This test mutates item selection and mode, unlike its siblings which only
134+
// read "test-event" — give it a private event (keyed by parallelIndex, with
135+
// its own display name) so it never clobbers the shared fixture other spec
136+
// files depend on, and doesn't produce a duplicate "TestEvent" heading on
137+
// the home page while other tests are concurrently asserting against it.
138+
const slug = `test-event-menu-cap-${testInfo.parallelIndex}`;
139+
// Event names are capped at 20 chars by the API (src/app/api/event/route.ts).
140+
// Must not contain "TestEvent" as a substring — other tests query
141+
// getByRole(..., { name: "TestEvent" }) without exact:true, which matches
142+
// on substring, so any name merely starting with "TestEvent" still collides.
143+
const name = `MenuCapEvent${testInfo.parallelIndex}`;
144+
const baseURL = testInfo.project.use.baseURL || "http://localhost:3000";
145+
await deleteIfExists(baseURL, slug);
146+
const response = await createEvent(baseURL, slug, name);
147+
expect(response.status).toBe(201);
148+
149+
try {
150+
await context.addCookies([
151+
{
152+
name: "privilege",
153+
value: Privilege.ADMIN,
154+
url: "http://localhost:3000",
155+
},
156+
]);
157+
await context.setExtraHTTPHeaders({
158+
Authorization: `Basic ${btoa(process.env.ADMIN_LOGIN || ":")}`,
159+
});
160+
161+
await page.goto(`http://localhost:3000/event/${slug}`);
162+
163+
// Wait for the freshly-created event's menu to actually be rendered
164+
// (Espresso pre-selected) rather than a fixed sleep, since a brand-new
165+
// event's Sync data may take longer to propagate under concurrent load.
166+
await expect(
167+
page.getByRole("button", { name: "Espresso Strong black coffee" }),
168+
).toHaveAttribute("aria-pressed", "true");
169+
170+
// TestEvent starts with 1 item selected (Espresso); select 9 more unselected
171+
// items to reach the 10-item cap. Scoped to the literal aria-pressed="false"
172+
// attribute (not the role=button pressed filter) — Chromium's accessibility
173+
// tree reports pressed:false by default for any plain button, which would
174+
// otherwise also match the header's "Log out" button and toast dismiss buttons.
175+
const unselectedItem = page.locator('button[aria-pressed="false"]');
176+
for (let i = 0; i < 9; i++) {
177+
await unselectedItem.first().click();
178+
// Wait for this click's selection save to land before firing the
179+
// next — the save is a fire-and-forget PUT, and rapid unawaited
180+
// requests can complete out of order under latency, regressing the
181+
// count if a later click's save is overtaken by an earlier one.
182+
await expect(page.getByText(`${i + 2} of 10 items selected`)).toBeVisible();
183+
}
184+
185+
// selecting an 11th item should be blocked
158186
await unselectedItem.first().click();
159-
}
187+
await expect(
188+
page.getByText("Cannot select more items", { exact: true }),
189+
).toBeVisible();
160190

161-
await expect(page.getByText("10 of 10 items selected")).toBeVisible();
162-
163-
// selecting an 11th item should be blocked
164-
await unselectedItem.first().click();
165-
await expect(
166-
page.getByText("Cannot select more items", { exact: true }),
167-
).toBeVisible();
168-
169-
await page.getByText("Smoothie").click();
191+
await page.getByText("Smoothie").click();
192+
} finally {
193+
await deleteIfExists(baseURL, slug);
194+
}
170195
});
171196

172197
test("should show warning for inactive number", async ({ page, context }) => {

__tests__/global-setup.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import { expect, type FullConfig } from "@playwright/test";
22
import Axios from "axios";
33

4-
async function deleteIfExists(baseURL: string) {
4+
export async function deleteIfExists(baseURL: string, slug: string = "test-event") {
55
try {
6-
await Axios.delete(`${baseURL}/api/event/test-event`, {
6+
await Axios.delete(`${baseURL}/api/event/${slug}`, {
77
headers: {
88
"Content-Type": "application/json",
99
Authorization: `Basic ${btoa(process.env.ADMIN_LOGIN || ":")}`,
@@ -12,12 +12,16 @@ async function deleteIfExists(baseURL: string) {
1212
} catch (e) {}
1313
}
1414

15-
async function createEvent(baseURL: string) {
15+
export async function createEvent(
16+
baseURL: string,
17+
slug: string = "test-event",
18+
name: string = "TestEvent",
19+
) {
1620
return Axios.post(
1721
`${baseURL}/api/event`,
1822
{
19-
name: "TestEvent",
20-
slug: "test-event",
23+
name,
24+
slug,
2125
state: "OPEN",
2226
senders: ["+4915199999999", "whatsapp:+447700161860"],
2327
selection: {

deploy.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ secret_keys=(
189189
TWILIO_API_KEY
190190
TWILIO_API_SECRET
191191
TWILIO_AUTH_TOKEN
192-
TWILIO_PHONE_NUMBER
193192
TWILIO_MESSAGING_SERVICE_SID
194193
TWILIO_SYNC_SERVICE_SID
195194
TWILIO_VERIFY_SERVICE_SID

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"license": "MIT",
66
"scripts": {
7-
"dev": "next dev",
7+
"dev": "env NODE_OPTIONS=--require=dotenv/config DOTENV_CONFIG_PATH=./.env.local DOTENV_CONFIG_OVERRIDE=true next dev",
88
"build": "next build",
99
"start": "next start",
1010
"lint": "next lint",

playwright.config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ export default defineConfig({
2121
forbidOnly: !!process.env.CI,
2222
/* Retry on CI only */
2323
retries: process.env.CI ? 2 : 0,
24-
/* Opt out of parallel tests on CI. */
25-
workers: process.env.CI ? 1 : undefined,
24+
workers: process.env.CI ? 4 : undefined,
2625
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
2726
reporter: "html",
2827
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */

sample.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ TWILIO_ACCOUNT_SID=
99
TWILIO_AUTH_TOKEN=FOR_SIGNATURE_VERIFICATION
1010
TWILIO_API_KEY=
1111
TWILIO_API_SECRET=
12-
TWILIO_PHONE_NUMBER=
1312
TWILIO_MESSAGING_SERVICE_SID=
1413
TWILIO_SYNC_SERVICE_SID=
1514
TWILIO_VERIFY_SERVICE_SID=

src/app/(layout-free)/event/[slug]/kiosk/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
77
<div className="min-h-screen flex flex-col">
88
<Header number="ABC" mode="barista" />
99
<Toaster />
10-
<main className="px-24 pt-16">{children}</main>
10+
<main className="px-4 pt-6 md:px-24 md:pt-16">{children}</main>
1111
{/* Use these parameters to adapt to a different screen size */}
1212
</div>
1313
);

0 commit comments

Comments
 (0)