3
2
2023-08-25
(C) Questetra, Inc. (MIT License)
This item sends bulk email to the contacts in the specified lists and/or segments on SendGrid.
この工程は、SendGrid のリストやセグメントに含まれる宛先に、メールを一斉送信します。
https://support.questetra.com/bpmn-icons/service-task-sendgrid-email-send-bulk/
https://support.questetra.com/ja/bpmn-icons/service-task-sendgrid-email-send-bulk/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADBUlEQVRYR8WXS08TURTH/5cWBeXZ
ipHFjBh3JIYSdKELYePGZCYS4jMxtiauwU+gJm40JpYPYKhxodEoj+4R4lYrjQsXimKrUhKRNxNC
22vuTMcZ5s50psLgbCY5c++c3zn33PMg+M8PqUh/MnMOFN0gJAKgCQB7s2cKwCIoZe8JyOKo1/+6
AwwvNCG42g9KB0AIU+r+ULoIQuLI1w2it3mx3IbyAGPfo0DxoWfFVk0qCGKQxBEnCGeAZDYOoN/d
XA8rKI1DFm/arbQHSGYSALnm4dfel1CagCzGrBt4ABfL+w7V4lhDNae4LkiwmqecPKsU8Ci7pssH
IQkD5kVbAdiZEzpUzqzJUy04HdrLLfm4mse9z8uc/OzBWlxMzZvktNccEwYAi/bAyle3gHMCSC1t
ouvNHAfwpDOEq+9/G3IWmIX6I/rtMACS2dsAbrkd6rYBNAV3IAlMHwyAsQy7u427AsC8IIvNBgDL
cCDDbsrZ9x3yAAAtFjQP2ET+DXE/zrTUcEztddVorani5OO/NvBNySNICIIECBCCKgJMr+Vxf3rF
zjb1RmgAY9kJEHSbVz3vCuN8ay238ct6AUfHZzn565Mt6Anzt2Mkp6D3rfkWlLZSTEIWenQPzAA4
7AfAq5yCPjsAVsAkoVMH4DLITnngxayCC+9sPMCslQTiO8Czn+u4nDLlAbObTQC+HcHTH+u4Yk5E
BkAakhBxDMKXx8OINOzhgq1IKeY2ipz8UmoeoycOcPLhnIK7n/gUDUsQcqV3qCOEWJp3XaV5oExu
MV1Dm0TkP4A5Eam5YGsq9hWA0iXIotreORYjXwFsi5FWjmf0guQbALO+UN/Gl2P1GIyG5EF7I8LV
AS6G2vYFwLof6/NheRPX0wse6plTQ6Jv3clmlMf52wfon3avKQV9DEmMWpl2py03BZ13ALVPUEex
hJdOyfbwWcARRP9tMNH/qI1mA6XRzLVlU7epitXRLL690cxqlpYxe0ARAVGH047SkjQo2Bg2BdCJ
chZXdgQeLtV2l/wBk2V1MIOcaTsAAAAASUVORK5CYII=
{
// 認証設定を準備
const auth = httpClient.createAuthSettingToken('SendGrid API Key', 'sendgrid-1234567');
configs.putObject('conf_Auth', auth);
setDataItem('Categories', 1, 'STRING_TEXTAREA', categories);
configs.put('conf_SenderId', senderId);
setDataItem('ListIds', 2, 'STRING_TEXTAREA', listIds);
setDataItem('SegmentIds', 3, 'STRING_TEXTAREA', segmentIds);
setDataItem('UnsubscribeGroupId', 4, 'STRING_TEXTFIELD', unsubscribeGroupId);
setDataItem('DesignId', 5, 'STRING_TEXTFIELD', designId);
// ID を保存するデータ項目を作成し、設定
const idDef = setDataItem('SingleSendId', 11, 'STRING_TEXTFIELD', '事前文字列');
// URL を保存するデータ項目を作成し、設定
const urlDef = setDataItem('SingleSendUrl', 12, 'STRING_TEXTFIELD', '事前文字列');
return {idDef, urlDef};
};
/**
* データ項目を作成し、config にセットする
* @param name config 名の conf_ 以降
* @param index
* @param type
* @param value
* @param 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);
}
};
/**
* 指定個数のデータを改行区切りにした文字列を生成する
* @param num
* @return string
*/
const createListString = (num) => {
let string = '';
for (let i = 0; i < num; i++) {
string += `item${i}\n`;
}
return string;
};
/**
* 指定の長さの文字列を作成
* @param length
* @return string
*/
const createString = (length) => {
const sourceStr = 'abcdefghijklmnopqrstuvwxyz';
const string = sourceStr.repeat(Math.floor(length / sourceStr.length))
+ sourceStr.slice(0, length % sourceStr.length);
return string;
}
/**
* カテゴリの個数が多すぎる(文字型データ項目)
*/
test('Too many Categories - set by STRING', () => {
const categoriesStr = createListString(MAX_CATEGORY_NUM + 1);
prepareConfigs(categoriesStr, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
assertError(main, `The maximum number of Categories is ${MAX_CATEGORY_NUM}.`);
});
/**
* カテゴリに ASCII 文字以外を含む(文字型データ項目)
*/
test('Categories include invalid characters - set by STRING', () => {
prepareConfigs('categoryあ', '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
assertError(main, 'Categories cannot include non-ascii characters.');
});
/**
* 長すぎるカテゴリを含む(文字型データ項目)
*/
test('Category is loo long - set by STRING', () => {
const categoriesStr = createListString(MAX_CATEGORY_NUM - 1) + createString(MAX_CATEGORY_LENGTH + 1);
prepareConfigs(categoriesStr, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
assertError(main, `Each category must be within ${MAX_CATEGORY_LENGTH} characters.`);
});
/**
* カテゴリの指定が重複(文字型データ項目)
*/
test('Same category is set multiple times - set by STRING', () => {
const categoriesStr = createListString(MAX_CATEGORY_NUM - 1) + 'item1';
prepareConfigs(categoriesStr, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
assertError(main, 'The same category is set multiple times.');
});
/**
* 送信者 ID が空
*/
test('Sender ID is blank', () => {
prepareConfigs(null, '', 'list1\nlist2', 'segment1\nsegment2', '123', 'design1');
assertError(main, 'Sender ID is blank.');
});
/**
* 送信者 ID が整数でない
*/
test('Sender ID is not integer', () => {
prepareConfigs(null, 'invalidId', 'list1\nlist2', 'segment1\nsegment2', '123', 'design1');
assertError(main, 'Sender ID must be integer.');
});
/**
* 配信停止グループ ID が空(文字型データ項目)
*/
test('Unsubscribe Group ID is blank - set by STRING', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', null, 'design1');
assertError(main, 'Unsubscribe Group ID is blank.');
});
/**
* 配信停止グループ ID が整数でない(文字型データ項目)
*/
test('Unsubscribe Group ID is not integer - set by STRING', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', 'invalidId', 'design1');
assertError(main, 'Unsubscribe Group ID must be integer.');
});
/**
* リスト ID とセグメント ID がどちらも空(文字型データ項目)
*/
test('No List IDs or Segment IDs - set by STRING', () => {
prepareConfigs(null, '123', null, null, '456', 'design1');
assertError(main, 'No List IDs or Segment IDs.');
});
/**
* リスト ID の個数が多すぎる(文字型データ項目)
*/
test('Too many List IDs - set by STRING', () => {
const listIdsStr = createListString(MAX_LIST_ID_NUM + 1);
prepareConfigs(null, '123', listIdsStr, null, '456', 'design1');
assertError(main, `The maximum number of List IDs is ${MAX_LIST_ID_NUM}.`);
});
/**
* セグメント ID の個数が多すぎる(文字型データ項目)
*/
test('Too many Segment IDs - set by STRING', () => {
const segmentIdsStr = createListString(MAX_SEGMENT_ID_NUM + 1);
prepareConfigs(null, '123', null, segmentIdsStr, '456', 'design1');
assertError(main, `The maximum number of Segment IDs is ${MAX_SEGMENT_ID_NUM}.`);
});
/**
* デザイン ID が空(文字型データ項目)
*/
test('Design ID is blank - set by STRING', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', null);
assertError(main, 'Design ID is blank.');
});
/**
* Single Send のドラフトを作成する API リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.contentType
* @param request.body
* @param categories
* @param senderId
* @param listIds
* @param segmentIds
* @param unsubscribeGroupId
* @param designId
* @param subject
* @param htmlContent
* @param plainContent
*/
const assertCreateRequest = ({url, method, contentType, body}, categories, senderId, listIds, segmentIds, unsubscribeGroupId, designId, subject, htmlContent, plainContent) => {
expect(url).toEqual('https://api.sendgrid.com/v3/marketing/singlesends');
expect(method).toEqual('POST');
expect(contentType).toEqual('application/json');
const bodyObj = JSON.parse(body);
expect(bodyObj.name).toEqual(`Questetra-m${processInstance.getProcessModelInfoId()}-p${processInstance.getProcessInstanceId()}`);
expect(bodyObj.categories).toEqual(categories);
expect(bodyObj.send_to.list_ids).toEqual(listIds);
expect(bodyObj.send_to.segment_ids).toEqual(segmentIds);
expect(bodyObj.email_config.sender_id).toEqual(senderId);
expect(bodyObj.email_config.suppression_group_id).toEqual(unsubscribeGroupId);
expect(bodyObj.email_config.design_id).toEqual(designId);
expect(bodyObj.email_config.subject).toEqual(subject);
expect(bodyObj.email_config.html_content).toEqual(htmlContent);
expect(bodyObj.email_config.plain_content).toEqual(plainContent);
if (plainContent !== undefined) {
expect(bodyObj.email_config.generate_plain_content).toEqual(false);
}
};
/**
* Single Send のドラフトを作成する API リクエストでエラー
*/
test('Fail to create Single Send', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
httpClient.setRequestHandler((request) => {
assertCreateRequest(request, [], 123, ['list1', 'list2'], ['segment1', 'segment2'], 456, 'design1', undefined, undefined, undefined);
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError(main, 'Failed to create single send. status: 400');
});
/**
* Single Send の送信予約をする API リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.contentType
* @param request.body
* @param singleSendId
* @param sendAt
*/
const assertScheduleRequest = ({url, method, contentType, body}, singleSendId, sendAt) => {
expect(url).toEqual(`https://api.sendgrid.com/v3/marketing/singlesends/${singleSendId}/schedule`);
expect(method).toEqual('PUT');
expect(contentType).toEqual('application/json');
const bodyObj = JSON.parse(body);
expect(bodyObj.send_at).toEqual(sendAt);
};
/**
* Single Send の送信予約をする API リクエストでエラー
*/
test('Fail to schedule Single Send', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 123, ['list1', 'list2'], ['segment1', 'segment2'], 456, 'design1', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend1"}');
}
assertScheduleRequest(request, 'singleSend1', 'now');
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError(main, 'Failed to schedule single send. status: 400, singleSendId: singleSend1');
});
/**
* 成功
* デザイン ID で指定
* カテゴリ指定なし
* 送信日時指定なし
*/
test('Succeed - Content set by design ID, no categories, no schduled datetime', () => {
const {idDef, urlDef} = prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 123, ['list1', 'list2'], ['segment1', 'segment2'], 456, 'design1', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend1"}');
}
assertScheduleRequest(request, 'singleSend1', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend1');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend1/stats');
});
/**
* 送信日時を設定
* @param timestamp
*/
const setSendAt = (timestamp) => {
const def = engine.createDataDefinition('送信日時', 3, 'q_sendAt', 'DATETIME');
if (timestamp !== null) {
engine.setData(def, timestamp);
}
configs.putObject('conf_SendAt', def);
}
/**
* 送信日時が選択されているのに、値が空
*/
test('Scheduled Datetime is null', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
setSendAt(null);
assertError(main, 'Scheduled Datetime is selected but its data is null.');
});
/**
* 送信日時が過去
*/
test('Scheduled Datetime has passed', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
const timestamp = new com.questetra.bpms.util.AddableTimestamp().addMinutes(-1);
setSendAt(timestamp);
assertError(main, 'Scheduled Datetime must be future.');
});
/**
* 成功
* デザイン ID で指定
* リストのみ指定し、セグメント指定なし
* カテゴリ指定あり
* 送信日時指定あり
*/
test('Succeed - Content set by design ID, no segments, with categories, with schduled datetime', () => {
const {idDef, urlDef} = prepareConfigs('category1\ncategory2\ncategory3', '1', 'list1', null, '4', 'design2');
const timestamp = new com.questetra.bpms.util.AddableTimestamp().addMinutes(3);
setSendAt(timestamp);
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, ['category1', 'category2', 'category3'], 1, ['list1'], [], 4, 'design2', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend2"}');
}
assertScheduleRequest(request, 'singleSend2', dateFormatter.format('UTC', "yyyy-MM-dd'T'HH:mm:ss'Z'", timestamp));
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend2');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend2/stats');
});
/**
* 成功
* デザイン ID で指定
* セグメントのみ指定し、リスト指定なし
* カテゴリ指定あり
* 送信日時指定なし
* データ項目に保存しない
*/
test('Succeed - Content set by design ID, no lists, with categories, no schduled datetime, not save', () => {
const {idDef, urlDef} = prepareConfigs('category1', '1000', null, 'segment1', '4000', 'design3');
configs.put('conf_SingleSendId', '');
configs.put('conf_SingleSendUrl', '');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, ['category1'], 1000, [], ['segment1'], 4000, 'design3', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend3"}');
}
assertScheduleRequest(request, 'singleSend3', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('事前文字列');
expect(engine.findData(urlDef)).toEqual('事前文字列');
});
/**
* 成功
* デザイン ID で指定
* カテゴリ、リスト ID、セグメント ID を最大個数指定し、API リクエストの確認を省略
*/
test('Succeed - Maximum number of categories, listIds and segmentIds', () => {
const categoriesStr = createListString(MAX_CATEGORY_NUM - 1) + createString(MAX_CATEGORY_LENGTH);
const listIdsStr = createListString(MAX_LIST_ID_NUM);
const segmentIdsStr = createListString(MAX_SEGMENT_ID_NUM);
const {idDef, urlDef} = prepareConfigs(categoriesStr, '1', listIdsStr, segmentIdsStr, '4', 'design2');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
// API リクエストの確認を省略
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend1"}');
}
assertScheduleRequest(request, 'singleSend1', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend1');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend1/stats');
});
/**
* 「デザインを使用せず、件名と本文を直接指定する」がオンなのに、デザイン ID が文字型データ項目で指定されている
*/
test('Design ID is set by STRING while hasUniqueContent is enabled', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', null); // 値が null でもエラー
configs.putObject('conf_HasUniqueContent', true);
assertError(main, 'Design ID is set while "Configure the subject and content without using Design" is enabled.');
});
/**
* 本文を直接指定
* @param subject
* @param htmlContent
* @param plainContent
*/
const setUniqueContent = (subject, htmlContent, plainContent) => {
configs.putObject('conf_HasUniqueContent', true);
configs.put('conf_DesignId', '');
configs.put('conf_Subject', subject);
configs.put('conf_HtmlContent', htmlContent);
configs.put('conf_PlainContent', plainContent);
}
/**
* 「デザインを使用せず、件名と本文を直接指定する」がオンなのに、件名が空
*/
test('Subject is blank', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'dummyDesignId');
setUniqueContent('', 'メールの HTML 本文', '');
assertError(main, 'Subject is blank.');
});
/**
* 「デザインを使用せず、件名と本文を直接指定する」がオンなのに、HTML 本文が空
*/
test('HTML Content is Blank', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'dummyDesignId');
setUniqueContent('メールの件名', '', '');
assertError(main, 'HTML Content is blank.');
});
/**
* 成功
* 件名、本文を直接指定
* プレーンテキストメールの本文は指定なし
*/
test('Succeed - Has unique content, without plain text content', () => {
const {idDef, urlDef} = prepareConfigs(null, '1', 'list1', null, '4', 'dummyDesignId');
const subject = 'メールの件名';
const htmlContent = 'HTML メールの本文\nこれは HTML メールの本文です';
setUniqueContent(subject, htmlContent, '');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 1, ['list1'], [], 4, undefined, subject, htmlContent, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend4"}');
}
assertScheduleRequest(request, 'singleSend4', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend4');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend4/stats');
});
/**
* 成功
* 件名、本文を直接指定
* プレーンテキストメールの本文の指定あり
*/
test('Succeed - Has unique content, with plain text content', () => {
const {idDef, urlDef} = prepareConfigs(null, '1', 'list1', null, '4', 'dummyDesignId');
const subject = 'メールの件名';
const htmlContent = 'HTML メールの 本文\nこれは HTML メールの本文です';
const plainContent = 'プレーンテキストメールの本文\nこれはプレーンテキストメールの本文です';
setUniqueContent(subject, htmlContent, plainContent);
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 1, ['list1'], [], 4, undefined, subject, htmlContent, plainContent);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend5"}');
}
assertScheduleRequest(request, 'singleSend5', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend5');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend5/stats');
});
/**
* 設定を固定値で上書き
* @param senderId
* @param unsubscribeGroupId
* @param designId
*/
const updateConfigsWithFixedValues = (unsubscribeGroupId, designId) => {
configs.put('conf_UnsubscribeGroupId', unsubscribeGroupId);
configs.put('conf_DesignId', designId);
};
/**
* デザイン ID が空(固定値)
*/
test('Design ID is blank - set as fixed value', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', 'dummyId', 'dummyId');
updateConfigsWithFixedValues('456', '');
assertError(main, 'Design ID is blank.');
});
/**
* 「デザインを使用せず、件名と本文を直接指定する」がオンなのに、デザイン ID が固定値で指定されている
*/
test('Design ID is set as fixed value while hasUniqueContent is enabled', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', 'dummyId', 'dummyId');
updateConfigsWithFixedValues('456', 'design1');
configs.putObject('conf_HasUniqueContent', true);
assertError(main, 'Design ID is set while "Configure the subject and content without using Design" is enabled.');
});
/**
* 成功
* 配信停止グループ ID、デザイン ID を固定値で指定
*/
test('Succeed - Unsubscribe Group ID and Design ID are set as fixed value', () => {
const {idDef, urlDef} = prepareConfigs(null, '123', 'list1', null, 'dummyId', 'dummyId');
updateConfigsWithFixedValues('456', 'design1');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 123, ['list1'], [], 456, 'design1', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend11"}');
}
assertScheduleRequest(request, 'singleSend11', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend11');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend11/stats');
});
/**
* 選択型データ設定用のオブジェクトを作成
* @param prefix
* @param num
* @return selects
*/
const prepareSelects = (prefix, num) => {
const selects = new java.util.ArrayList();
for (let i = 0; i < num; i++) {
const item = engine.createItem(`${prefix}${i+1}`, `${prefix}${i+1} を選択`);
selects.add(item);
}
return selects;
};
/**
* カテゴリの個数が多すぎる(選択型データ項目)
*/
test('Too many Categories - set by SELECT', () => {
prepareConfigs('dummy', '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
setDataItem('Categories', 21, 'SELECT_CHECKBOX', prepareSelects('category_', MAX_CATEGORY_NUM + 1));
assertError(main, `The maximum number of Categories is ${MAX_CATEGORY_NUM}.`);
});
/**
* カテゴリに ASCII 文字以外を含む(選択型データ項目)
*/
test('Categories include invalid characters - set by SELECT', () => {
prepareConfigs('dummy', '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
const categories = prepareSelects('category_', 3);
const invalidCategory = 'catえgory';
categories.set(1, engine.createItem(invalidCategory, `${invalidCategory} を選択`));
setDataItem('Categories', 21, 'SELECT_CHECKBOX', categories);
assertError(main, 'Categories cannot include non-ascii characters.');
});
/**
* 長すぎるカテゴリを含む(選択型データ項目)
*/
test('Category is loo long - set by SELECT', () => {
prepareConfigs('dummy', '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'design1');
const categories = prepareSelects('category_', 3);
const longCategory = createString(MAX_CATEGORY_LENGTH + 1);
categories.set(1, engine.createItem(longCategory, `${longCategory} を選択`));
setDataItem('Categories', 21, 'SELECT_CHECKBOX', categories);
assertError(main, `Each category must be within ${MAX_CATEGORY_LENGTH} characters.`);
});
/**
* 配信停止グループ ID が未選択(選択型データ項目)
*/
test('Unsubscribe Group ID is not selected - set by SELECT', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', 'dummy', 'design1');
setDataItem('UnsubscribeGroupId', 23, 'SELECT_SINGLE', new java.util.ArrayList());
assertError(main, 'Unsubscribe Group ID is not selected.');
});
/**
* 配信停止グループ ID が整数でない(選択型データ項目)
*/
test('Unsubscribe Group ID is not integer - set by SELECT', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '123', 'design1');
setDataItem('UnsubscribeGroupId', 23, 'SELECT_SINGLE', prepareSelects('invalidId', 1));
assertError(main, 'Unsubscribe Group ID must be integer.');
});
/**
* リスト ID とセグメント ID がどちらも未選択(選択型データ項目)
*/
test('No List IDs or Segment IDs - set by SELECT', () => {
prepareConfigs(null, '123', 'dummy', 'dummy', '456', 'design1');
setDataItem('ListIds', 24, 'SELECT_CHECKBOX', new java.util.ArrayList());
setDataItem('SegmentIds', 25, 'SELECT_CHECKBOX', new java.util.ArrayList());
assertError(main, 'No List IDs or Segment IDs.');
});
/**
* リスト ID の個数が多すぎる(選択型データ項目)
*/
test('Too many List IDs - set by SELECT', () => {
prepareConfigs(null, '123', 'dummy', null, '456', 'design1');
setDataItem('ListIds', 24, 'SELECT_CHECKBOX', prepareSelects('list_', MAX_LIST_ID_NUM + 1));
assertError(main, `The maximum number of List IDs is ${MAX_LIST_ID_NUM}.`);
});
/**
* セグメント ID の個数が多すぎる(選択型データ項目)
*/
test('Too many Segment IDs - set by SELECT', () => {
prepareConfigs(null, '123', null, 'dummy', '456', 'design1');
setDataItem('SegmentIds', 25, 'SELECT_CHECKBOX', prepareSelects('segment_', MAX_SEGMENT_ID_NUM + 1));
assertError(main, `The maximum number of Segment IDs is ${MAX_SEGMENT_ID_NUM}.`);
});
/**
* デザイン ID が未選択(選択型データ項目)
*/
test('Design ID is not selected - set by SELECT', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'dummy');
setDataItem('DesignId', 26, 'SELECT_SINGLE', new java.util.ArrayList());
assertError(main, 'Design ID is not selected.');
});
/**
* 「デザインを使用せず、件名と本文を直接指定する」がオンなのに、デザイン ID が選択型データ項目で指定されている
*/
test('Design ID is set by SELECT while hasUniqueContent is enabled', () => {
prepareConfigs(null, '123', 'list1\nlist2', 'segment1\nsegment2', '456', 'dummy');
setDataItem('DesignId', 26, 'SELECT_SINGLE', new java.util.ArrayList()); // 未選択でもエラー
configs.putObject('conf_HasUniqueContent', true);
assertError(main, 'Design ID is set while "Configure the subject and content without using Design" is enabled.');
});
/**
* 成功
* データ項目で指定できるものは、すべて選択型データ項目で指定
* デザイン ID で指定
* カテゴリ指定なし
* リスト ID のみ指定
* 送信日時指定なし
*/
test('Succeed - Configured by SELECT, content set by design ID, no categories, no schduled datetime', () => {
// 認証設定を準備
const auth = httpClient.createAuthSettingToken('SendGrid API Key', 'sendgrid-1234567');
configs.putObject('conf_Auth', auth);
const idDef = setDataItem('SingleSendId', 11, 'STRING_TEXTFIELD', '事前文字列');
const urlDef = setDataItem('SingleSendUrl', 12, 'STRING_TEXTFIELD', '事前文字列');
setDataItem('Categories', 21, 'SELECT_CHECKBOX', new java.util.ArrayList());
configs.put('conf_SenderId', '123');
setDataItem('ListIds', 22, 'SELECT_CHECKBOX', prepareSelects('list', 2));
setDataItem('SegmentIds', 23, 'SELECT_CHECKBOX', new java.util.ArrayList());
setDataItem('UnsubscribeGroupId', 24, 'SELECT_SINGLE', prepareSelects('', 1)); // 整数にするため、prefix を空に
setDataItem('DesignId', 25, 'SELECT_SINGLE', prepareSelects('design', 1));
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, [], 123, ['list1', 'list2'], [], 1, 'design1', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend1"}');
}
assertScheduleRequest(request, 'singleSend1', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend1');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend1/stats');
});
/**
* 成功
* データ項目で指定できるものは、すべて選択型データ項目で指定
* デザイン ID で指定
* カテゴリ指定あり
* セグメント ID のみ指定
* 送信日時指定なし
*/
test('Succeed - Configured by SELECT, content set by design ID, with categories, no schduled datetime', () => {
// 認証設定を準備
const auth = httpClient.createAuthSettingToken('SendGrid API Key', 'sendgrid-1234567');
configs.putObject('conf_Auth', auth);
const idDef = setDataItem('SingleSendId', 11, 'STRING_TEXTFIELD', '事前文字列');
const urlDef = setDataItem('SingleSendUrl', 12, 'STRING_TEXTFIELD', '事前文字列');
setDataItem('Categories', 21, 'SELECT_CHECKBOX', prepareSelects('category', 3));
configs.put('conf_SenderId', '123');
setDataItem('ListIds', 22, 'SELECT_CHECKBOX', new java.util.ArrayList());
setDataItem('SegmentIds', 23, 'SELECT_CHECKBOX', prepareSelects('segment', 2));
setDataItem('UnsubscribeGroupId', 24, 'SELECT_SINGLE', prepareSelects('', 1)); // 整数にするため、prefix を空に
setDataItem('DesignId', 25, 'SELECT_SINGLE', prepareSelects('design', 1));
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertCreateRequest(request, ['category1', 'category2', 'category3'], 123, [], ['segment1', 'segment2'],
1, 'design1', undefined, undefined, undefined);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', '{"id": "singleSend2"}');
}
assertScheduleRequest(request, 'singleSend2', 'now');
return httpClient.createHttpResponse(200, 'application/json', '{}');
});
main();
// データ項目の値をチェック
expect(engine.findData(idDef)).toEqual('singleSend2');
expect(engine.findData(urlDef)).toEqual('https://mc.sendgrid.com/single-sends/singleSend2/stats');
});
]]>