Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ import { ChangeBlockSettingsDialog } from './dialogs/change-block-settings-dialo
import { ApproveUpdateVcDocumentDialogComponent } from './dialogs/approve-update-vc-document-dialog/approve-update-vc-document-dialog.component'
import { AddDocumentDialog } from './dialogs/add-document-dialog/add-document-dialog.component';
import { MockDialog } from './dialogs/mock-dialog/mock-dialog.component';
import { PolicyTestAutomationPopupComponent } from './policy-viewer/policy-test-automation/policy-test-automation-popup.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -318,7 +319,8 @@ import { MockDialog } from './dialogs/mock-dialog/mock-dialog.component';
AddDocumentDialog,
ChangeBlockSettingsDialog,
ApproveUpdateVcDocumentDialogComponent,
MockDialog
MockDialog,
PolicyTestAutomationPopupComponent
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { RequestDocumentBlockDialog } from '../request-document-block/dialog/req
import { SchemaRulesService } from 'src/app/services/schema-rules.service';
import { prepareVcData } from 'src/app/modules/common/models/prepare-vc-data';
import { PolicyStatus } from '@guardian/interfaces';
import { PolicyTestAutomationDraftService } from '../../policy-test-automation/policy-test-automation-draft.service';

interface IRequestDocumentAddonData {
readonly: boolean;
Expand Down Expand Up @@ -92,7 +93,8 @@ export class RequestDocumentBlockAddonComponent
private fb: UntypedFormBuilder,
private dialogService: DialogService,
private router: Router,
private changeDetectorRef: ChangeDetectorRef
private changeDetectorRef: ChangeDetectorRef,
private policyTestDraft: PolicyTestAutomationDraftService
) {
super(policyEngineService, profile, wsService);
this.dataForm = this.fb.group({});
Expand Down Expand Up @@ -203,14 +205,25 @@ export class RequestDocumentBlockAddonComponent
if (this.dataForm.valid) {
const data = this.dataForm.getRawValue();
prepareVcData(data);
const payload = {
document: data,
ref: this.ref?.id,
};

if (this.dryRun && this.policyTestDraft.draft.captureNextFormSubmit) {
this.policyTestDraft.captureInput({
policyId: this.policyId,
blockId: this.id,
blockType: 'requestDocumentBlockAddon',
...payload
});
}

this.dialogRef.close();
this.dialogRef = null;
this.loading = true;
this.policyEngineService
.setBlockData(this.id, this.policyId, {
document: data,
ref: this.ref?.id,
})
.setBlockData(this.id, this.policyId, payload)
.subscribe(
// tslint:disable-next-line:no-empty
() => { },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { autosaveValueChanged, getMinutesAgoStream } from 'src/app/utils/autosav
import { RelayerAccountsService } from 'src/app/services/relayer-accounts.service';
import { AttachedFile } from 'src/app/modules/common/policy-comments/attached-file';
import { IPFSService } from 'src/app/services/ipfs.service';
import { PolicyTestAutomationDraftService } from '../../../policy-test-automation/policy-test-automation-draft.service';

@Component({
selector: 'request-document-block-dialog',
Expand Down Expand Up @@ -115,6 +116,7 @@ export class RequestDocumentBlockDialog {
private indexedDb: IndexedDbRegistryService,
private tablePersist: TablePersistenceService,
private ipfsService: IPFSService,
private policyTestDraft: PolicyTestAutomationDraftService,
) {
this.parent = this.config.data;
this.dataForm = this.fb.group({});
Expand Down Expand Up @@ -294,15 +296,26 @@ export class RequestDocumentBlockDialog {

const evidence = this.enableAdditionalData ? this.buildEvidence() : undefined;

const payload = {
document: data,
ref: this.docRef,
draft,
draftId,
relayerAccount: this.getRelayerAccount(),
...(evidence?.length ? { evidence } : {})
};

if (this.dryRun && !draft && this.policyTestDraft.draft.captureNextFormSubmit) {
this.policyTestDraft.captureInput({
policyId: this.policyId,
blockId: this.id,
blockType: 'requestDocumentBlock',
...payload
});
}

this.policyEngineService
.setBlockData(this.id, this.policyId, {
document: data,
ref: this.docRef,
draft: draft,
draftId: draftId,
relayerAccount: this.getRelayerAccount(),
...(evidence?.length ? { evidence } : {})
})
.setBlockData(this.id, this.policyId, payload)
.subscribe(() => {
setTimeout(() => {
this.loading = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PolicyStatus } from '@guardian/interfaces';
import { RelayerAccountsService } from 'src/app/services/relayer-accounts.service';
import { AttachedFile } from 'src/app/modules/common/policy-comments/attached-file';
import { IPFSService } from 'src/app/services/ipfs.service';
import { PolicyTestAutomationDraftService } from '../../policy-test-automation/policy-test-automation-draft.service';

interface IRequestDocumentData {
readonly: boolean;
Expand Down Expand Up @@ -150,6 +151,7 @@ export class RequestDocumentBlockComponent
private indexedDb: IndexedDbRegistryService,
private tablePersist: TablePersistenceService,
private ipfsService: IPFSService,
private policyTestDraft: PolicyTestAutomationDraftService,
) {
super(policyEngineService, profile, wsService);
this.dataForm = this.fb.group({});
Expand Down Expand Up @@ -419,17 +421,28 @@ export class RequestDocumentBlockComponent

const evidence = this.enableAdditionalData ? this.buildEvidence() : undefined;

const payload = {
document: data,
ref: this.ref,
draft,
draftId: this.draftId,
relayerAccount: this.getRelayerAccount(),
...(evidence?.length ? { evidence } : {})
};

if (this.dryRun && !draft && this.policyTestDraft.draft.captureNextFormSubmit) {
this.policyTestDraft.captureInput({
policyId: this.policyId,
blockId: this.id,
blockType: 'requestDocumentBlock',
...payload
});
}

let requestSucceeded = false;

this.policyEngineService
.setBlockData(this.id, this.policyId, {
document: data,
ref: this.ref,
draft,
draftId: this.draftId,
relayerAccount: this.getRelayerAccount(),
...(evidence?.length ? { evidence } : {})
})
.setBlockData(this.id, this.policyId, payload)
.pipe(
finalize(async () => {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

export interface PolicyTestInputAnchor {
policyId: string;
blockId: string;
blockType?: string;
title?: string;
ref?: unknown;
document: unknown;
draft?: boolean;
draftId?: string | null;
relayerAccount?: unknown;
evidence?: { dataType: 'message' | 'file'; data: string }[];
capturedAt: string;
}

export interface PolicyTestOutputAnchor {
type: 'vc' | 'vp' | 'schema' | string;
id: string;
title?: string;
document?: unknown;
source?: {
policyId?: string;
documentId?: string;
schemaId?: string;
messageId?: string;
rowId?: string;
blockId?: string;
blockType?: string;
inputCapturedAt?: string;
};
capturedAt: string;
}

export interface PolicyTestAutomationDraft {
captureNextFormSubmit: boolean;
input: PolicyTestInputAnchor | null;
outputs: PolicyTestOutputAnchor[];
name: string;
description: string;
readyToSave: boolean;
}

const createInitialDraft = (): PolicyTestAutomationDraft => ({
captureNextFormSubmit: false,
input: null,
outputs: [],
name: '',
description: '',
readyToSave: false
});

@Injectable({ providedIn: 'root' })
export class PolicyTestAutomationDraftService {
private readonly draftSubject = new BehaviorSubject<PolicyTestAutomationDraft>(createInitialDraft());
public readonly draft$ = this.draftSubject.asObservable();

public get draft(): PolicyTestAutomationDraft {
return this.draftSubject.value;
}

public setCaptureNextFormSubmit(value: boolean): void {
const draft = this.draft;
if (value && draft.input) {
return;
}
this.update({ captureNextFormSubmit: value });
}

public captureInput(input: Omit<PolicyTestInputAnchor, 'capturedAt'>): void {
if (this.draft.input) {
return;
}
this.update({
captureNextFormSubmit: false,
input: {
...this.clone(input),
capturedAt: new Date().toISOString()
}
});
}

public discardInput(): void {
this.update({ input: null, captureNextFormSubmit: false });
}

public addOutput(output: Omit<PolicyTestOutputAnchor, 'capturedAt'>): void {
const exists = this.draft.outputs.some((item) => {
return item.type === output.type && item.id === output.id;
});
if (exists) {
return;
}
this.update({
outputs: [
...this.draft.outputs,
{ ...this.clone(output), capturedAt: new Date().toISOString() }
],
readyToSave: false
});
}

public discardOutput(type: string, id: string): void {
this.update({
outputs: this.draft.outputs.filter((item) => item.type !== type || item.id !== id),
readyToSave: false
});
}

public confirmOutputFromInput(): void {
const input = this.draft.input;
if (!input) {
return;
}
this.addOutput({
type: input.blockType || 'input',
id: [
input.policyId,
input.blockId,
input.capturedAt
].join(':'),
title: input.title || 'Confirmed output',
document: input.document,
source: {
policyId: input.policyId,
blockId: input.blockId,
blockType: input.blockType,
inputCapturedAt: input.capturedAt
}
});
this.update({
input: null,
captureNextFormSubmit: false,
readyToSave: false
});
}

public setMetadata(name: string, description: string): void {
this.update({ name, description });
}

public markReadyToSave(): boolean {
const readyToSave = !!this.draft.input && this.draft.outputs.length > 0;
this.update({ readyToSave });
return readyToSave;
}

public hasInput(): boolean {
return !!this.draft.input;
}

public hasOutputs(): boolean {
return this.draft.outputs.length > 0;
}

public shouldWarnBeforeStop(): boolean {
return this.hasInput() && !this.hasOutputs();
}

public getRecordMetadata(): { version: 1; name?: string; description?: string; input?: PolicyTestInputAnchor; outputs?: PolicyTestOutputAnchor[] } | null {
if (!this.draft.input || !this.draft.outputs.length) {
return null;
}
return {
version: 1,
name: this.draft.name || undefined,
description: this.draft.description || undefined,
input: this.draft.input,
outputs: this.draft.outputs
};
}

public reset(): void {
this.draftSubject.next(createInitialDraft());
}

private update(patch: Partial<PolicyTestAutomationDraft>): void {
this.draftSubject.next({
...this.draft,
...patch
});
}

private clone<T>(value: T): T {
return JSON.parse(JSON.stringify(value));
}
}
Loading
Loading