2024-04-12
(C) Questetra, Inc. (MIT License)
3
2
This item adds a new list item to the specified list on Microsoft Lists.
この工程は、Microsoft Lists の指定リストに、新しいリストアイテムを 1 件追加します。
https://support.questetra.com/bpmn-icons/service-task-microsoft-lists-listitem-add/
https://support.questetra.com/ja/bpmn-icons/service-task-microsoft-lists-listitem-add/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABFlJREFUWEfF
l3tsU3UUx7/nrqVlbPiAZbjhhhLCdAYXxKBolKi49VZ0+KiKYbgIoa1mwbJuREKCJurWLghlrh1O
EFgwARPjY+0GkqB/CD7+mDMb8lhSjchkKDKY69b1HtLbdbCtt/dmML1/3dyex+c8fud3SvifH9Lq
v6Fw881hXeRxgJcw406AbiHiDFmfcZaBLoDaCTigj6R8tarF8bcW26oAHz5Znd4fEd4C82tEpNNi
lJkHAfIMsuHNskBZTzIdRQAGk090rwShCqBMLY5HyzBzF0GosPrXNRKIE9lQBKgT3U4CqkFQzVJS
OAYzwWFvcm7RBLDvuX0p53qDO4ioZDxRK+kwsGV6am65Zb8lcrXMmOjqzO61BLx3PZ3HbTHw+uhM
jADwiTVLJJKaCSRMDABLBEG0NZW3xO0PA+xcvMkYmpIaTNZwt86fhQfXPAqQelv8e74Xn1V+PDYO
xpm+8ymzHUccfdEfhy15Rdd6EL2rFHnOgttQuKEY39QewO+tv8piUkQCS1eam4SYOSLC895S7Hyh
NqG5q0sha0SPnFd0/0FEMxJpxJ0frPoCwe9OaapOyW4bdpd4E8syzlj95dnRoykD1Jmq7yNBOJJI
OnteDpa+bcHJwx043fabJudRoUWrH8EOi0dRniXpfnug8mgMwOyuIqAykXTRxmLcNHMaLp7tgaAT
kJmXhdM/jQRhSQIJI/t2ZkEuthdvVgYAqu1NzvUxANF1mIgeTiRt2rgMnd+ewIlD7TBOnYxnt65A
Y+l21Uy8vPdVfLT8fWUA5q/t/orFcYBfiGjufwxw3O6vyJMBvKLrHxDdoASQNS8H4dAAhBQBxvTJ
6L8UUs2AIc0I39IaZTnmCzZ/xY1DGXCHiGBQAgj+0IljzW1Iy0hHsetFTSVYscuKPSt9mgGCRMjV
BrAcjaX1qhlQA2DmKyWoE91HibBQCUCfOgndJ7swKc2IOQ/lod3fqgqQby5AwzNbtTWhV3T7QFij
BGBIN+Kv4DnojXrc/sAcHD/UkRQg77F89F/qVx5EselXb/M7rXIP+ERXERMFtJ2CkqQlKNzwFGbc
kY29qxsQ7htQBCVmk9Vf0SwDeEweg55CfyY6CdE5EPy+E8da2lTnQHRoZc7NUnXOjJ7pU3ozLPs3
DQxfRkrT8O6n78V8y0JEwhH5ktEZdAiHwrHIovdQ1AID0YtooLcfn6zdkzTyITV5CkbfhwE8Js9U
HYVOEVFs052gh5m7DTqe/crnlRdHAMgDyVxTyJD8E7mQCCwUWf3lB+Pxjdks1PaCa0mM6koWN+4V
XR+AaNW1OBujO3TsRn9X3K28pup1IMF9PdZyMMpsAWfC9Sjpcud9wr0MjG0AsseVDeYgBHLYvnR+
qqSvul3W31OvlzIvvARQGYAC1YywfDhbQVw7LXXWrtH/AzSXIBGxx/ROhp50ZgYWALiLiPKH5kEH
g38m4McwDzaVBd7o1pox1QxoNTReucsdycEwUqG3yAAAAABJRU5ErkJggg==
{
const oauth2 = httpClient.createAuthSettingOAuth2(
'Microsoft Lists',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/token',
'https://graph.microsoft.com/Sites.ReadWrite.All offline_access',
'client_id',
'client_secret',
'access_token'
);
configs.putObject('conf_OAuth2', oauth2);
configs.put('conf_SiteUrl', siteUrl);
configs.put('conf_ListTitle', listTitle);
// リストアイテム ID を保存するデータ項目を作成し、設定
const listItemIdDef = engine.createDataDefinition('リストアイテム ID', 1, 'q_listItemId', 'STRING_TEXTFIELD');
engine.setData(listItemIdDef, '事前文字列');
configs.putObject('conf_ListItemId', listItemIdDef);
// 列の名前と値を設定
for (let i = 0; i < COLUMN_NUM; i++) {
configs.put(`conf_ColumnName${i + 1}`, columnNames[i]);
configs.put(`conf_ColumnValue${i + 1}`, columnValues[i]);
}
return listItemIdDef;
};
/**
* リストアイテム ID の準備(文字型データ項目の場合)
* @param listItemId
* @return listItemIdDef
*/
const preparelistItemIdStringDef = (listItemId) => {
// 文字型データ項目(単一行)を準備
const listItemIdDef = engine.createDataDefinition('リストアイテム ID', 1, 'q_listItemId', 'STRING_TEXTFIELD');
engine.setData(listItemIdDef, listItemId);
return listItemIdDef;
};
/**
* リストアイテム ID の準備(選択型データ項目の場合)
* @param listItemId
* @return listItemIdDef
*/
const preparelistItemIdSelectDef = (listItemId) => {
// 選択型データ項目を準備
const listItemIdDef = engine.createDataDefinition('リストアイテム ID', 1, 'q_listItemId', 'SELECT_SINGLE');
const select = new java.util.ArrayList();
const item = engine.createItem(listItemId, `${listItemId} を選択`);
select.add(item);
engine.setData(listItemIdDef, select);
return listItemIdDef;
};
/**
* 異常系のテスト
* @param errorMsg
*/
const assertError = (errorMsg) => {
let failed = false;
try {
main();
} catch (e) {
failed = true;
expect(e.message).toEqual(errorMsg);
}
if (!failed) {
fail('No error was thrown.');
}
};
const BLANKS = ['', '', '', '', '', '', ''];
const SAMPLE_COLUMN_NAMES = [
'SingleLineOfText',
'MultiLineOfText',
'Number',
'Currency',
'ChoiceSingle',
'Datetime',
'Date'
];
const SAMPLE_COLUMN_VALUES = [
'text',
'text\nwith\nline\nbreaks',
'123',
'1000',
'Choice 1',
'2022-02-22T12:34:56+09:00',
'2022-02-22'
];
const SAMPLE_FIELDS = {
SingleLineOfText: 'text',
MultiLineOfText: 'text\nwith\nline\nbreaks',
Number: '123',
Currency: '1000',
ChoiceSingle: 'Choice 1',
Datetime: '2022-02-22T12:34:56+09:00',
Date: '2022-02-22'
};
/**
* 列の値だけ指定されている組がある
*/
test('Column value is specified while its field name is not selected', () => {
const siteUrl = 'https://test-my.sharepoint.com/personal/user_test_onmicrosoft_com';
const listTitle = 'リスト 1';
const columnValues = JSON.parse(JSON.stringify(BLANKS)); // ディープコピー
columnValues[2] = '123';
prepareConfigs(siteUrl, listTitle, BLANKS, columnValues);
assertError('C-V3 is set while C-K3 is blank.');
});
/**
* 列名の指定が重複
*/
test('The same field name is set multiple times', () => {
const siteUrl = 'https://test-my.sharepoint.com/personal/user_test_onmicrosoft_com';
const listTitle = 'リスト 1';
const columnNames = JSON.parse(JSON.stringify(SAMPLE_COLUMN_NAMES)); // ディープコピー
columnNames[5] = SAMPLE_COLUMN_NAMES[0]; // 重複させる
prepareConfigs(siteUrl, listTitle, columnNames, SAMPLE_COLUMN_VALUES);
assertError(`The field name "${SAMPLE_COLUMN_NAMES[0]}" is set multiple times.`);
});
/**
* サイト情報取得の GET リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param siteUrl
*/
const assertGetSiteInfoRequest = ({ url, method, headers }, siteUrl) => {
const encodedUrl = encodeSharingUrl(siteUrl);
const expectedUrl = `${GRAPH_URI}shares/${encodedUrl}/site?select=id`;
expect(url).toEqual(expectedUrl);
expect(method).toEqual('GET');
expect(headers.Authorization).toEqual('Bearer access_token');
};
/**
* サイト情報取得の GET リクエストでエラー
*/
test('Fail in GET request', () => {
const siteUrl = 'https://test-my.sharepoint.com/personal/user_test_onmicrosoft_com';
const listTitle = 'リスト 1';
prepareConfigs(siteUrl, listTitle, BLANKS, BLANKS);
httpClient.setRequestHandler((request) => {
assertGetSiteInfoRequest(request, siteUrl);
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError('Failed to get site info. status: 400');
});
/**
* クエリパラメータのテスト用の文字列を生成する
* @param key
* @param value
* @returns {String}
*/
const generateQueryString = (key, value) => {
const encodedKey = encodeURIComponent(key);
const encodedValue = encodeURIComponent(value)
.replace(/%20/g, '+') // HttpRequestWrapper#formParam() はスペースを + に置き換える
.replace(/'/g, '%27') // encodeURIComponent() でエンコードされない文字をエンコード
.replace(/\(/g, '%28')
.replace(/\)/g, '%29');
return `${encodedKey}=${encodedValue}`;
};
/**
* リストアイテム追加の POST リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.contentType
* @param request.headers
* @param request.body
* @param siteId
* @param listTitle
* @param fields
*/
const assertPostRequest = ({ url, method, contentType, headers, body }, siteId, listTitle, fields) => {
let expectedUrl = `${GRAPH_URI}sites/${encodeURIComponent(siteId)}/lists/${encodeURIComponent(listTitle)}/items`
+ `?${generateQueryString('$select', 'id')}`;
expect(url).toEqual(expectedUrl);
expect(method).toEqual('POST');
expect(contentType).toEqual('application/json; charset=UTF-8');
expect(headers.Authorization).toEqual('Bearer access_token');
const bodyObj = JSON.parse(body);
expect(bodyObj.fields).toEqual(fields);
};
/**
* リストアイテム追加の POST リクエストでエラー
*/
test('Fail in POST request', () => {
const siteUrl = 'https://test-my.sharepoint.com/personal/user_test_onmicrosoft_com';
const listTitle = 'リスト 1';
prepareConfigs(siteUrl, listTitle, BLANKS, BLANKS);
let reqCount = 0;
const siteId = 'test-my.sharepoint.com,1234abcd-5e6f-7g8h-9i0j,1a2b3c4d-1a2b3c4d5e6f';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetSiteInfoRequest(request, siteUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', `{"id":"${siteId}"}`);
}
assertPostRequest(request, siteId, listTitle, {});
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError('Failed to add list item. status: 400');
});
/**
* 成功 - 列の指定なし
*/
test('Succeed - no columns', () => {
const siteUrl = 'https://test-my.sharepoint.com/personal/user_test_onmicrosoft_com';
const listTitle = 'リスト 1';
const listItemIdDef = prepareConfigs(siteUrl, listTitle, BLANKS, BLANKS);
let reqCount = 0;
const siteId = 'test-my.sharepoint.com,1234abcd-5e6f-7g8h-9i0j,1a2b3c4d-1a2b3c4d5e6f';
const listItemId = '1';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetSiteInfoRequest(request, siteUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', `{"id":"${siteId}"}`);
}
assertPostRequest(request, siteId, listTitle, {});
return httpClient.createHttpResponse(201, 'application/json', `{"id":"${listItemId}"}`);
});
expect(main()).toEqual(undefined);
expect(engine.findData(listItemIdDef)).toEqual(listItemId);
});
/**
* 成功 - すべての列名と値を指定
*/
test('Succeed - all columns', () => {
const siteUrl = 'https://test.sharepoint.com/sites/MarketingDepartment';
const listTitle = '共有リスト 1';
// サイト URL の末尾にスラッシュがある場合、無視して処理される
const listItemIdDef = prepareConfigs(`${siteUrl}/`, listTitle, SAMPLE_COLUMN_NAMES, SAMPLE_COLUMN_VALUES);
let reqCount = 0;
const siteId = 'test.sharepoint.com,9876abcd-5e6f-7g8h-9i0j,1a2b3c4d-9a8b7c6d5e4f';
const listItemId = '21';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetSiteInfoRequest(request, siteUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', `{"id":"${siteId}"}`);
}
assertPostRequest(request, siteId, listTitle, SAMPLE_FIELDS);
return httpClient.createHttpResponse(201, 'application/json', `{"id":"${listItemId}"}`);
});
expect(main()).toEqual(undefined);
expect(engine.findData(listItemIdDef)).toEqual(listItemId);
});
/**
* 成功 - 一部の列のみ指定し、列の値が空のものも含む。リストアイテム ID を保存しない
*/
test('Succeed - some columns, including empty values', () => {
const siteUrl = 'https://test.sharepoint.com/sites/MarketingDepartment';
const listTitle = '共有リスト 2';
const columnNames = [
'',
'Column1',
'',
'',
'Column2',
'COlumn3',
''
];
const columnValues = [
'',
'text',
'',
'',
'Choice 1',
'',
''
];
const fields = {
Column1: 'text',
Column2: 'Choice 1',
COlumn3: null
};
const listItemIdDef = prepareConfigs(`${siteUrl}/`, listTitle, columnNames, columnValues);
configs.put('conf_ListItemId', null);
let reqCount = 0;
const siteId = 'test.sharepoint.com,9876abcd-5e6f-7g8h-9i0j,1a2b3c4d-9a8b7c6d5e4f';
const listItemId = '21';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetSiteInfoRequest(request, siteUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', `{"id":"${siteId}"}`);
}
assertPostRequest(request, siteId, listTitle, fields);
return httpClient.createHttpResponse(201, 'application/json', `{"id":"${listItemId}"}`);
});
expect(main()).toEqual(undefined);
expect(engine.findData(listItemIdDef)).toEqual('事前文字列');
});
]]>