2023-07-31
(C) Questetra, Inc. (MIT License)
3
2
This item monitors the progress of a Sign Request on Box Sign until its completion.
File ID of the signed document can be saved when all the signers have signed.
この工程は、Box Sign の署名リクエストの進捗を、リクエストが完了するまで確認し続けます。署名者全員が署名を終えると、署名済みドキュメントのファイル ID を保存できます。
https://support.questetra.com/bpmn-icons/service-task-box-sign-request-monitor/
https://support.questetra.com/ja/bpmn-icons/service-task-box-sign-request-monitor/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEBElEQVRYR82Xb2jbRRjHP/fL2jXJ
0qSd65x11aK0YgJWZUwEWZ0DfSNaHYKKmgykbP7pH/SVghvCkIlb6kREwfyGOougbgxB2Yt1oGwg
aietdOJoV21ty2ob26xdm+TkLsufJr+2Sdtt3pv8uDx3z+ee+z53zwmucRMF+ff/9ijEtwB1IDwI
9QtIOkGOA50I0UHIezTfeRcH8Pd64GITyGaE8OQ1sVQwIgiONsxqBTZvWxjA3+UHDuTtONuNBjEC
mLcfmY9gfgB/dxBBU14rXsxIyiCmr8XKzBog0GWCeG6xeQv6X2JiegPZY3IBVnLlOVtCG6a3ObN7
LoDacyFCBa2sUGMpGjI1kQbQao/0Lllw+YJoYTqrk9mRAdC9G8Eb+c6zLDvJHkzvbjVHGiDQpXLX
nZw4tOMGyp02Hjn457J8WQ5WUTB9ZWkAdcIJ+XWm8XCwFkexwLWrZ+UB9OmZ0EIiAhbKH2lLAKzZ
eaUAEhmRAAh0dYBQZ3yqKQDnaoPDp8PUVZXo/pM9EV75Ylh/77q/jO2bSlmz2mBgLErjoUHad95I
Z/80re0Jmw+e3UD1dcU8uP+8RRTlSUK++ssA3X3ATdkA61y2nIE/9k7Rd2GWx+4uxWZkAP8bo9Ru
YAho+XyIUruNNxsqiMzE8bxgEUV1gZneO5MAMtuTioACUM7e+W4Uj8Pg5W1rdV9cwvSsxPx+nNPn
LvLStnI2VdsZi8TwOGyMTsY0nNth493j/9DSPmSto5BXLAigsmDLW7388MeUnuDVh9ay74n1+vvI
zxM0vJfOkNGDtdiLDH7pn+beW+3a5kRPhK37rMJ/mScDIGcLBvfXsM61isrWs4xMxPSIpza7+ayx
Un8rbTz94UBqZX8fqNFp+82vkzTc5dL9n54K88xHaZu5YZBnCPnq5hXhqdequecWO2rPH3j7PBvc
qzjWVEXN9cV6HhVmJbwvf5rgcGMlT2526y1wldiYiUl9wKhtUHp4/8TYIiK0SMP6WgdfvbiRMqeN
yKU4NkNQUiToH51lcDyq4aIxtMjcdoOpGYkSkrJpOz6qt6OxvowLkzEqms7mAsjMNLQ4iNSIrbc5
2bu9QqdSNC7pHrjEjo8H+GssyifPV3JfjQNHscFQOMqeoyPsfXw9vw/P8HBbv3b4bWsVG8uL8L5+
zgIg8yBSf2cdxdayXaleGSbk0+Xd/+gyUtexiPRlXkgrtd4s9YeRzptzr2NldU0LkiTmlS3JUnVA
0t3VK0qRhwj5VJk/p12lsjxdAeUPoDWhCpW4KtFTlVJhwpRhpOFf2sMkpQn9NGtGyOb8QZRj/TQL
Lu9plr1c/TiV9QipHqUeEHckTOQZYBwpOkF0LLTiwragsHgvyfo/g3CBMFgjn40AAAAASUVORK5C
YII=
{
configs.put('conf_OAuth2', 'Box Sign');
setDataItem('RequestId', 1, 'STRING_TEXTFIELD', requestId);
const statusDef = setDataItem('Status', 2, 'STRING_TEXTFIELD', '事前文字列');
const notSignedDef = setDataItem('NotSigned', 3, 'STRING_TEXTAREA', '事前文字列');
const signedDef = setDataItem('Signed', 4, 'STRING_TEXTAREA', '事前文字列');
const declinedDef = setDataItem('Declined', 5, 'STRING_TEXTFIELD', '事前文字列');
const signedFileIdDef = setDataItem('SignedFileId', 6, 'STRING_TEXTFIELD', '事前文字列');
const logFileIdDef = setDataItem('LogFileId', 7, 'STRING_TEXTFIELD', '事前文字列');
return {
statusDef,
notSignedDef,
signedDef,
declinedDef,
signedFileIdDef,
logFileIdDef,
};
};
/**
* データ項目を作成し、config にセットする
* @param name config 名の conf_ 以降
* @param index
* @param type
* @param value
* @returns dataDef
*/
const setDataItem = (name, index, type, value) => {
const dataDef = engine.createDataDefinition(name, index, `q_${name}`, type);
engine.setData(dataDef, value);
configs.putObject(`conf_${name}`, dataDef);
return dataDef;
};
/**
* 異常系のテスト
* @param func
* @param errorMsg
*/
const assertError = (func, errorMsg) => {
try {
func();
fail();
} catch (e) {
expect(e.toString()).toEqual(errorMsg);
}
};
/**
* 署名リクエスト ID が空
*/
test('Sign Request ID is blank', () => {
prepareConfigs(null);
assertError(main, 'Sign Request ID is blank.');
});
/**
* 署名リクエストを取得する API リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param requestId
*/
const assertRequest = ({url, method}, requestId) => {
expect(url).toEqual(`https://api.box.com/2.0/sign_requests/${requestId}`);
expect(method).toEqual('GET');
};
/**
* 署名リクエストを取得する API リクエストでエラー
*/
test('Fail to get sign request', () => {
const requestId = 'request-id-1';
prepareConfigs(requestId);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError(main, 'Failed to get Sign Request. status: 400');
});
/**
* 署名リクエスト取得 API のレスポンス文字列を生成
* @param status
* @param signers
* @param signedFileId
* @param logFileId
* @returns signRequestResponseString
*/
const createSignRequestResponse = (status, signers, signedFileId, logFileId) => {
const signRequest = {
status,
signers,
signing_log: null
};
Object.assign(signRequest, {
sign_files: {
files: [
{
id: signedFileId
}
]
}
});
if (logFileId !== null) {
Object.assign(signRequest, {
signing_log: {
id: logFileId
}
});
}
return JSON.stringify(signRequest);
};
/**
* 署名リクエスト取得 API のレスポンスに設定する署名者オブジェクトを生成
* @param email
* @param role
* @param decision
* @returns signer
*/
const createSigner = (email, role, decision) => {
const signer = {
email,
role,
signer_decision: null
};
if (decision !== null) {
Object.assign(signer, {
signer_decision: {
type: decision
}
});
}
return signer;
};
/**
* データ項目の値を確認
* @param dataDefs
* @param status
* @param notSigned
* @param signed
* @param declined
* @param signedFileId
* @param logFileId
*/
const assertData = (dataDefs, status, notSigned, signed, declined, signedFileId, logFileId) => {
expect(engine.findData(dataDefs.statusDef)).toEqual(status);
expect(engine.findData(dataDefs.notSignedDef)).toEqual(notSigned);
expect(engine.findData(dataDefs.signedDef)).toEqual(signed);
expect(engine.findData(dataDefs.declinedDef)).toEqual(declined);
expect(engine.findData(dataDefs.signedFileIdDef)).toEqual(signedFileId);
expect(engine.findData(dataDefs.logFileIdDef)).toEqual(logFileId);
}
/**
* 成功
* 1 回目で署名リクエストのステータスが signed の場合
*/
test('Succeed - Signed in main()', () => {
const requestId = 'request-id-1';
const dataDefs = prepareConfigs(requestId);
const signers = [];
signers.push(createSigner('sender@example.com', 'final_copy_reader', null)); // 署名者でない
signers.push(createSigner('signer1@example.com', 'signer', 'signed'));
signers.push(createSigner('signer2@example.com', 'approver', 'signed'));
signers.push(createSigner('signer3@example.com', 'signer', 'signed'));
const responseStr = createSignRequestResponse('signed', signers, 'signedFileId1', 'logFileId1');
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStr);
});
expect(main()).toEqual(undefined);
assertData(dataDefs, 'signed', '', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', 'signedFileId1', 'logFileId1');
});
/**
* 成功
* 1 回目で署名リクエストのステータスが error_converting の場合
*/
test('Succeed - Error_converting in main()', () => {
const requestId = 'request-id-2';
const dataDefs = prepareConfigs(requestId);
const signers = [];
signers.push(createSigner('signer1@example.com', 'signer', null));
const responseStr = createSignRequestResponse('error_converting', signers, 'signedFileId2', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStr);
});
expect(main()).toEqual(undefined);
assertData(dataDefs, 'error_converting', 'signer1@example.com', '', '', '事前文字列', '事前文字列');
});
/**
* 成功
* 6 回目で署名リクエストのステータスが signed の場合(5 つの処理中ステータスのテスト)
*/
test('Succeed - Signed in proceed()', () => {
const requestId = 'request-id-2';
const dataDefs = prepareConfigs(requestId);
// 1 回目の確認(ステータス: converting)
const signersNoneSigned = [];
signersNoneSigned.push(createSigner('sender@example.com', 'final_copy_reader', null));
signersNoneSigned.push(createSigner('signer1@example.com', 'signer', null));
signersNoneSigned.push(createSigner('signer2@example.com', 'approver', null));
signersNoneSigned.push(createSigner('signer3@example.com', 'signer', null));
const responseStrConverting = createSignRequestResponse('converting', signersNoneSigned, 'signedFileId2', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrConverting);
});
expect(main()).toEqual(false);
assertData(dataDefs, 'converting', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', '', '事前文字列', '事前文字列');
// 2 回目の確認(ステータス: created)
const responseStrCreated = createSignRequestResponse('created', signersNoneSigned, 'signedFileId2', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrCreated);
});
expect(proceed()).toEqual(false);
assertData(dataDefs, 'created', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', '', '事前文字列', '事前文字列');
// 3 回目の確認(ステータス: sent)
const responseStrSent = createSignRequestResponse('sent', signersNoneSigned, 'signedFileId2', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrSent);
});
expect(proceed()).toEqual(false);
assertData(dataDefs, 'sent', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', '', '事前文字列', '事前文字列');
// 4 回目の確認(ステータス: viewed)
const signersSomeSigned = [];
signersSomeSigned.push(createSigner('sender@example.com', 'final_copy_reader', null));
signersSomeSigned.push(createSigner('signer1@example.com', 'signer', 'signed'));
signersSomeSigned.push(createSigner('signer2@example.com', 'approver', 'signed'));
signersSomeSigned.push(createSigner('signer3@example.com', 'signer', null));
const responseStrViewed = createSignRequestResponse('viewed', signersSomeSigned, 'signedFileId2', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrViewed);
});
expect(proceed()).toEqual(false);
assertData(dataDefs, 'viewed', 'signer3@example.com', 'signer1@example.com\nsigner2@example.com', '', '事前文字列', '事前文字列');
// 5 回目の確認(ステータス: finalizing)
const signersAllSigned = [];
signersAllSigned.push(createSigner('sender@example.com', 'final_copy_reader', null));
signersAllSigned.push(createSigner('signer1@example.com', 'signer', 'signed'));
signersAllSigned.push(createSigner('signer2@example.com', 'approver', 'signed'));
signersAllSigned.push(createSigner('signer3@example.com', 'signer', 'signed'));
const responseStrFinalizing = createSignRequestResponse('finalizing', signersAllSigned, null, null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrFinalizing);
});
expect(proceed()).toEqual(false);
assertData(dataDefs, 'finalizing', '', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', '事前文字列', '事前文字列');
// 6 回目の確認(ステータス: signed)
const responseStrSigned = createSignRequestResponse('signed', signersAllSigned, 'signedFileId2', 'logFileId2');
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrSigned);
});
expect(proceed()).toEqual(undefined);
assertData(dataDefs, 'signed', '', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', 'signedFileId2', 'logFileId2');
});
/**
* 成功
* 2 回目で署名リクエストのステータスが declined の場合
*/
test('Succeed - Declined in proceed()', () => {
const requestId = 'request-id-3';
const dataDefs = prepareConfigs(requestId);
// 1 回目の確認(ステータス: converting)
const signersNoneSigned = [];
signersNoneSigned.push(createSigner('signer1@example.com', 'signer', null));
signersNoneSigned.push(createSigner('signer2@example.com', 'signer', null));
signersNoneSigned.push(createSigner('signer3@example.com', 'signer', null));
const responseStrConverting = createSignRequestResponse('converting', signersNoneSigned, 'signedFileId3', null);
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrConverting);
});
expect(main()).toEqual(false);
assertData(dataDefs, 'converting', 'signer1@example.com\nsigner2@example.com\nsigner3@example.com', '', '', '事前文字列', '事前文字列');
// 2 回目の確認(ステータス: declined)
const signersDeclined = [];
signersDeclined.push(createSigner('signer1@example.com', 'signer', null));
signersDeclined.push(createSigner('signer2@example.com', 'signer', 'declined'));
signersDeclined.push(createSigner('signer3@example.com', 'signer', 'signed'));
const responseStrDeclined = createSignRequestResponse('declined', signersDeclined, 'signedFileId3', 'logFileId3');
httpClient.setRequestHandler((request) => {
assertRequest(request, requestId);
return httpClient.createHttpResponse(200, 'application/json', responseStrDeclined);
});
expect(proceed()).toEqual(undefined);
assertData(dataDefs, 'declined', 'signer1@example.com', 'signer3@example.com', 'signer2@example.com', '事前文字列', 'logFileId3'); // 署名済みファイルの ID は保存されない
});
]]>