generated from bisco/codex-bootstrap
Merge branch 'fix/checkin-frontend-url' into develop
This commit is contained in:
@@ -7,11 +7,11 @@ from django.conf import settings
|
|||||||
from .models import Reservation
|
from .models import Reservation
|
||||||
|
|
||||||
|
|
||||||
CHECK_IN_PREVIEW_PATH = "/api/check-ins/preview/"
|
CHECK_IN_PAGE_PATH = "/check-in"
|
||||||
|
|
||||||
|
|
||||||
def build_check_in_preview_url(raw_check_in_token):
|
def build_check_in_preview_url(raw_check_in_token):
|
||||||
return f"{settings.SITE_BASE_URL}{CHECK_IN_PREVIEW_PATH}?token={raw_check_in_token}"
|
return f"{settings.SITE_BASE_URL}{CHECK_IN_PAGE_PATH}?token={raw_check_in_token}"
|
||||||
|
|
||||||
|
|
||||||
def generate_check_in_qr_png(raw_check_in_token):
|
def generate_check_in_qr_png(raw_check_in_token):
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ class ReservationAdminTests(TestCase):
|
|||||||
self.assertEqual(reservation.status, Reservation.Status.CONFIRMED)
|
self.assertEqual(reservation.status, Reservation.Status.CONFIRMED)
|
||||||
self.assertIsNotNone(confirmation_token.used_at)
|
self.assertIsNotNone(confirmation_token.used_at)
|
||||||
self.assertContains(response, "Reservation confirmed manually")
|
self.assertContains(response, "Reservation confirmed manually")
|
||||||
self.assertContains(response, "/api/check-ins/preview/?token=")
|
self.assertContains(response, "/check-in?token=")
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
ReservationToken.objects.filter(
|
ReservationToken.objects.filter(
|
||||||
reservation=reservation,
|
reservation=reservation,
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class BookingApiTests(APITestCase):
|
|||||||
self.assertEqual(response.data["party_size"], reservation.party_size)
|
self.assertEqual(response.data["party_size"], reservation.party_size)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
response.data["qr_code_url"].startswith(
|
response.data["qr_code_url"].startswith(
|
||||||
"https://tickets.azionelab.example/api/check-ins/preview/?token="
|
"https://tickets.azionelab.example/check-in?token="
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertNotIn(raw_token, response.data["qr_code_url"])
|
self.assertNotIn(raw_token, response.data["qr_code_url"])
|
||||||
@@ -257,7 +257,7 @@ class BookingApiTests(APITestCase):
|
|||||||
self.assertEqual(response.data["reservation_id"], reservation.id)
|
self.assertEqual(response.data["reservation_id"], reservation.id)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
response.data["qr_code_url"].startswith(
|
response.data["qr_code_url"].startswith(
|
||||||
"https://tickets.azionelab.example/api/check-ins/preview/?token="
|
"https://tickets.azionelab.example/check-in?token="
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertTrue(response.data["qr_code_image"].startswith("data:image/png;base64,"))
|
self.assertTrue(response.data["qr_code_image"].startswith("data:image/png;base64,"))
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ class BookingServiceTests(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
result.qr_code_url.startswith(
|
result.qr_code_url.startswith(
|
||||||
"https://tickets.azionelab.example/api/check-ins/preview/?token="
|
"https://tickets.azionelab.example/check-in?token="
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.assertTrue(result.qr_code_image.startswith("data:image/png;base64,"))
|
self.assertTrue(result.qr_code_image.startswith("data:image/png;base64,"))
|
||||||
@@ -282,7 +282,7 @@ class BookingServiceTests(TestCase):
|
|||||||
self.assertGreater(len(qr_code_image), len("data:image/png;base64,"))
|
self.assertGreater(len(qr_code_image), len("data:image/png;base64,"))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
build_check_in_preview_url(raw_check_in_token),
|
build_check_in_preview_url(raw_check_in_token),
|
||||||
"https://tickets.azionelab.example/api/check-ins/preview/?token=opaque-check-in-token",
|
"https://tickets.azionelab.example/check-in?token=opaque-check-in-token",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_qr_code_is_not_generated_for_pending_reservation(self):
|
def test_qr_code_is_not_generated_for_pending_reservation(self):
|
||||||
@@ -430,7 +430,7 @@ class BookingServiceTests(TestCase):
|
|||||||
self.assertEqual(result.check_in_token.purpose, ReservationToken.Purpose.CHECK_IN)
|
self.assertEqual(result.check_in_token.purpose, ReservationToken.Purpose.CHECK_IN)
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
result.qr_code_url.startswith(
|
result.qr_code_url.startswith(
|
||||||
"https://tickets.azionelab.example/api/check-ins/preview/?token="
|
"https://tickets.azionelab.example/check-in?token="
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -462,7 +462,7 @@ class BookingServiceTests(TestCase):
|
|||||||
self.assertEqual(result.reservation, reservation)
|
self.assertEqual(result.reservation, reservation)
|
||||||
self.assertEqual(result.check_in_token.purpose, ReservationToken.Purpose.CHECK_IN)
|
self.assertEqual(result.check_in_token.purpose, ReservationToken.Purpose.CHECK_IN)
|
||||||
self.assertTrue(result.qr_code_image.startswith("data:image/png;base64,"))
|
self.assertTrue(result.qr_code_image.startswith("data:image/png;base64,"))
|
||||||
self.assertIn("/api/check-ins/preview/?token=", result.qr_code_url)
|
self.assertIn("/check-in?token=", result.qr_code_url)
|
||||||
|
|
||||||
def create_reservation(self, **overrides):
|
def create_reservation(self, **overrides):
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { RouterLink } from '@angular/router';
|
import { ActivatedRoute, RouterLink } from '@angular/router';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
@@ -326,6 +326,7 @@ type BarcodeDetectorConstructor = new (options?: { formats?: string[] }) => Barc
|
|||||||
export class CheckInPlaceholderPageComponent {
|
export class CheckInPlaceholderPageComponent {
|
||||||
private readonly destroyRef = inject(DestroyRef);
|
private readonly destroyRef = inject(DestroyRef);
|
||||||
private readonly formBuilder = inject(FormBuilder);
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
|
private readonly route = inject(ActivatedRoute);
|
||||||
private readonly showsApi = inject(ShowsApiService);
|
private readonly showsApi = inject(ShowsApiService);
|
||||||
private readonly barcodeDetectorCtor = (globalThis as { BarcodeDetector?: BarcodeDetectorConstructor }).BarcodeDetector;
|
private readonly barcodeDetectorCtor = (globalThis as { BarcodeDetector?: BarcodeDetectorConstructor }).BarcodeDetector;
|
||||||
private readonly scannerSupported =
|
private readonly scannerSupported =
|
||||||
@@ -358,6 +359,12 @@ export class CheckInPlaceholderPageComponent {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.destroyRef.onDestroy(() => this.stopScanner());
|
this.destroyRef.onDestroy(() => this.stopScanner());
|
||||||
|
const tokenFromQuery = this.route.snapshot.queryParamMap.get('token')?.trim() ?? '';
|
||||||
|
if (tokenFromQuery) {
|
||||||
|
this.tokenForm.controls.token.setValue(tokenFromQuery);
|
||||||
|
this.tokenForm.controls.token.markAsTouched();
|
||||||
|
this.preview();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected preview(): void {
|
protected preview(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user