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('事前文字列'); }); ]]>