Skip to content

Commit 53de317

Browse files
committed
fix(platform): fix import for responders without history
1 parent 9dd6905 commit 53de317

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

e2e/tests/export_import.spec.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ test.describe('Data Export and Import', () => {
453453
const UUID_CERT_TEMPLATE = '019568f0-0000-7000-8000-000000000104';
454454
const UUID_PK = '019568f0-0000-7000-8000-000000000105';
455455
const UUID_RESPONDER = '019568f0-0000-7000-8000-000000000106';
456+
const UUID_RESPONDER_NO_HISTORY = '019568f0-0000-7000-8000-000000000109';
456457
const UUID_RESP_HISTORY = '019568f0-0000-7000-8000-000000000116';
457458
const UUID_PAGE_TRACKER = '019568f0-0000-7000-8000-000000000107';
458459
const UUID_PAGE_REV = '019568f0-0000-7000-8000-000000000117';
@@ -637,6 +638,17 @@ test.describe('Data Export and Import', () => {
637638
},
638639
],
639640
},
641+
{
642+
id: UUID_RESPONDER_NO_HISTORY,
643+
name: 'import-test-responder-no-history',
644+
location: { pathType: '=', path: '/import-resp-no-hist' },
645+
method: 'POST',
646+
enabled: true,
647+
settings: { requestsToTrack: 5, statusCode: 204 },
648+
createdAt: 1577836800,
649+
updatedAt: 1577836800,
650+
// No history field — simulates export of a responder with empty history.
651+
},
640652
],
641653
pageTrackers: [
642654
{
@@ -716,7 +728,7 @@ test.describe('Data Export and Import', () => {
716728
expect(preview.summary.scripts.total).toBe(1);
717729
expect(preview.summary.secrets.total).toBe(1);
718730
expect(preview.summary.secrets.total).toBe(1);
719-
expect(preview.summary.responders.total).toBe(1);
731+
expect(preview.summary.responders.total).toBe(2);
720732
expect(preview.summary.certificateTemplates.total).toBe(1);
721733
expect(preview.summary.privateKeys.total).toBe(1);
722734
expect(preview.summary.contentSecurityPolicies.total).toBe(1);
@@ -733,7 +745,10 @@ test.describe('Data Export and Import', () => {
733745
selections: {
734746
scripts: [{ sourceId: UUID_SCRIPT, action: 'import' }],
735747
secrets: [{ sourceId: UUID_SECRET, action: 'import' }],
736-
responders: [{ sourceId: UUID_RESPONDER, action: 'import' }],
748+
responders: [
749+
{ sourceId: UUID_RESPONDER, action: 'import' },
750+
{ sourceId: UUID_RESPONDER_NO_HISTORY, action: 'import' },
751+
],
737752
certificateTemplates: [{ sourceId: UUID_CERT_TEMPLATE, action: 'import' }],
738753
privateKeys: [{ sourceId: UUID_PK, action: 'import' }],
739754
contentSecurityPolicies: [{ sourceId: UUID_CSP, action: 'import' }],
@@ -749,7 +764,7 @@ test.describe('Data Export and Import', () => {
749764
expect(importResult.results.settings.imported).toBe(1);
750765
expect(importResult.results.scripts.imported).toBe(1);
751766
expect(importResult.results.secrets.imported).toBe(1);
752-
expect(importResult.results.responders.imported).toBe(1);
767+
expect(importResult.results.responders.imported).toBe(2);
753768
expect(importResult.results.certificateTemplates.imported).toBe(1);
754769
expect(importResult.results.privateKeys.imported).toBe(1);
755770
expect(importResult.results.contentSecurityPolicies.imported).toBe(1);
@@ -831,6 +846,25 @@ test.describe('Data Export and Import', () => {
831846
expect(importedResponder.settings.script).toContain('context.secrets.IMPORT_SECRET');
832847
expect(importedResponder.settings.secrets).toEqual({ type: 'all' });
833848

849+
// ── Step 7f-2: Validate no-history responder config ──────────────────
850+
const importedResponderNoHistory = responders.find(
851+
(r: { name: string }) => r.name === 'import-test-responder-no-history',
852+
);
853+
expect(importedResponderNoHistory).toBeDefined();
854+
expect(importedResponderNoHistory.location).toEqual({ pathType: '=', path: '/import-resp-no-hist' });
855+
expect(importedResponderNoHistory.method).toBe('POST');
856+
expect(importedResponderNoHistory.enabled).toBe(true);
857+
expect(importedResponderNoHistory.settings.statusCode).toBe(204);
858+
expect(importedResponderNoHistory.settings.requestsToTrack).toBe(5);
859+
860+
// Validate that the no-history responder has empty history.
861+
const noHistoryRes = await page.request.get(
862+
`/api/utils/webhooks/responders/${encodeURIComponent(importedResponderNoHistory.id)}/history`,
863+
);
864+
expect(noHistoryRes.ok()).toBeTruthy();
865+
const noHistory = await noHistoryRes.json();
866+
expect(noHistory).toHaveLength(0);
867+
834868
// ── Step 7g: Validate imported responder history ────────────────────
835869
const historyRes = await page.request.get(
836870
`/api/utils/webhooks/responders/${encodeURIComponent(importedResponder.id)}/history`,

src/users/user_data/export/types.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub struct UserDataExportData {
6262
pub struct ExportedResponder {
6363
#[serde(flatten)]
6464
pub responder: Responder,
65-
#[serde(skip_serializing_if = "Vec::is_empty")]
65+
#[serde(default, skip_serializing_if = "Vec::is_empty")]
6666
pub history: Vec<ExportedResponderRequest>,
6767
}
6868

@@ -409,6 +409,23 @@ mod tests {
409409
assert!(json.get("history").is_none());
410410
}
411411

412+
#[test]
413+
fn deserialize_exported_responder_without_history() {
414+
let json = json!({
415+
"id": "00000000-0000-0000-0000-000000000000",
416+
"name": "resp-no-history",
417+
"location": { "pathType": "=", "path": "/test" },
418+
"method": "GET",
419+
"enabled": true,
420+
"settings": { "statusCode": 200 },
421+
"createdAt": 1577836800,
422+
"updatedAt": 1590969600
423+
});
424+
let exported: ExportedResponder = serde_json::from_value(json).unwrap();
425+
assert_eq!(exported.responder.name, "resp-no-history");
426+
assert!(exported.history.is_empty());
427+
}
428+
412429
#[test]
413430
fn serialize_exported_responder_request() {
414431
let req = ExportedResponderRequest {

0 commit comments

Comments
 (0)