2024-05-02 (C) Questetra, Inc. (MIT License) 3 2 This item creates a card on Trello. この工程は、Trello のカードを作成します。 https://support.questetra.com/bpmn-icons/service-task-trello-card-create/ https://support.questetra.com/ja/bpmn-icons/service-task-trello-card-create/ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAzBJREFUWEfF l11IFFEUx/93xnH9iPzow0jBaIOsSNJWI+glX6KHJLcvkiKwF7WXolJ76iWiSLBeUortoSSLcDfp pZfwJXrQVV8MIsNEjFbwI5T1e/bGndnZnRlnZ8ZZau/b3HvuOb97zrnnniFI8SC27Z8KZoGPeMHz x0FpGSh2gSBP2k8xC4IxEDIEUeyFyPnxwbNgR7c1wLm+HRBJM0DqAWTYUQpgCaAd4OlDvKsMme0x B6gJ1oOgFUC2TcN6sTAobiHg6Ui0PzGAN/gUQINDw/pt7fB7Go10GQPU9L8GIRfZhgyBQ3qadaSM lM8tivFpSrsQqKjVy63XHD15aXEmAs1u7C5wOXbCyhqF79MUGp+NKzrWeUILIMe8nUl/uV+Co3ud hl7L7G4cxujksjxJ0aDOiTiAlO3cDyXhlt6UwyU4c73eZQ8CIdzp/KVMh8FH9ii3I27B298GkOuK 1PLbck3s5xdF/AnLMXUJHLbnpMXsrIoUodlV6ZvjCHbmCSAq9taeSdx+OaHioo/hr7jBJmQxVmQE TKvvuRogQgH+7IDmYCFfKQpyBWmutu0nuj7PxNZ914pRV7U19r0eAEtYxRZWrGSA032XwHGv1BbU ACyZXBcGNQBjHQdRvC1dmjt5bwQfh+biBq8U4WZ1gRkAEIlcxvvKThngzIAPlNb9VwBCXqD78FUZ wBtkxyv7rwDAEPyechmgJjgTe1iiFP88BOwBC3jyFQ9QTYABbASAZThLNGX0tLhRXZFrngNs1e+J XhZvMCkApovdFDbYidRXkM0Z3AJZOAaQZAj03tN/GwLoQpBUEjoC0CShxTVcEymE89o6MPG8FIX5 ciGyGoYe0FxDi0LEDIxPrWB6fk2ylZnOoaTQbnOUIAc0hciiFFud0GrduhRLxcj8MbIyYrb+qGcS TaaPEdute46/PjmA/UX23WwGcKTlG/pGwopIgueYLasakhOHNqO7yY1sF5fM4dE7PI+qu9/jOhI2 JIqIrhk9tm8TcrJ4RxCDowv4He0TogosWjLFjKopdWTZaJPtpjSBJ5IE2WBbHvNEKn9MFIiU/pqp /Z6yn9Mkg2+1/S+COKkwjkUALAAAAABJRU5ErkJggg== { const authKey = httpClient.createAuthSettingToken( 'Trello', 'TrelloApiKey', ); configs.putObject('conf_ApiKey', authKey); const authToken = httpClient.createAuthSettingToken( 'Trello', 'TrelloApiToken', ); configs.putObject('conf_ApiToken', authToken); setDataItem('ListId', 1, 'STRING_TEXTFIELD', listId); configs.put('conf_Name', name); configs.put('conf_Desc', desc); setDataItem('LabelIds', 2, 'STRING_TEXTAREA', labelIdsStr); setDataItem('MemberIds', 3, 'STRING_TEXTAREA', memberIdsStr); // ID を保存するデータ項目を作成し、設定 const idDef = setDataItem('CardId', 4, 'STRING_TEXTFIELD', '事前文字列'); // URL を保存するデータ項目を作成し、設定 const urlDef = setDataItem('CardUrl', 5, '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 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.'); } }; /** * 指定個数のデータを改行区切りにした文字列を生成する * @param num * @return string */ const createListString = (num) => { let string = ''; for (let i = 0; i < num; i++) { string += `item${i}\n`; } return string; }; /** * リスト ID が空(文字型データ項目) */ test('List ID is blank - set by STRING', () => { prepareConfigs(null, 'Card Title', 'Card Description', 'labelId1\nlabelId2', 'memberId1\nmemberId2'); assertError('List ID is blank.'); }); /** * リスト ID が未選択(選択型データ項目) */ test('List ID is not selected - set by SELECT', () => { prepareConfigs('dummy', 'Card Title', 'Card Description', 'labelId1\nlabelId2', 'memberId1\nmemberId2'); setDataItem('ListId', 11, 'SELECT_SINGLE', new java.util.ArrayList()); assertError('List ID is not selected.'); }); /** * カードタイトルが空 */ test('Card Title is blank', () => { prepareConfigs('listId1', '', 'Card Description', 'labelId1\nlabelId2', 'memberId1\nmemberId2'); assertError('Card Title is blank.'); }); /** * カードを作成する API リクエストのテスト * @param {Object} request * @param request.url * @param request.method * @param request.contentType * @param request.body * @param listId * @param name * @param desc * @param labelIds * @param memberIds * @param start * @param due * @param dueReminder */ const assertCreateRequest = ({url, method, contentType, body}, listId, name, desc, labelIds, memberIds, start, due, dueReminder) => { expect(url).toEqual('https://api.trello.com/1/cards?key=TrelloApiKey&token=TrelloApiToken'); // 認証設定のトークンのテスト時の値は token expect(method).toEqual('POST'); expect(contentType).toEqual('application/json'); const bodyObj = JSON.parse(body); expect(bodyObj.idList).toEqual(listId); expect(bodyObj.name).toEqual(name); expect(bodyObj.desc).toEqual(desc); expect(bodyObj.idLabels).toEqual(labelIds); expect(bodyObj.idMembers).toEqual(memberIds); expect(bodyObj.start).toEqual(start); expect(bodyObj.due).toEqual(due); expect(bodyObj.dueReminder).toEqual(dueReminder); }; /** * カードを作成する API リクエストでエラー */ test('Fail to create card', () => { prepareConfigs('listId1', 'Card Title', 'Card Description', 'labelId1\nlabelId2', 'memberId1\nmemberId2'); httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId1', 'Card Title', 'Card Description', ['labelId1', 'labelId2'], ['memberId1', 'memberId2'], null, null, null); return httpClient.createHttpResponse(400, 'application/json', '{}'); }); assertError('Failed to create card. status: 400'); }); /** * API のレスポンス文字列を作成 * @param cardId * @param cardUrl * @return requestBodyString */ const createCardResponse = (cardId, cardUrl) => { const responseObj = { id: cardId, url: cardUrl }; return JSON.stringify(responseObj); }; /** * 成功 * 文字型/選択型データ項目を指定できる設定項目は、文字型データ項目で指定 * 開始日、期限、リマインダ設定は指定なし */ test('Succeed - Configs set by STRING', () => { const {idDef, urlDef} = prepareConfigs('listId1', 'Card Title', 'Card Description', 'labelId1\nlabelId2', 'memberId1\nmemberId2'); const cardId = 'cardId1'; const cardUrl = 'https://trello.com/c/cardId1/1-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId1', 'Card Title', 'Card Description', ['labelId1', 'labelId2'], ['memberId1', 'memberId2'], null, null, null); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); /** * 成功 * 文字型/選択型データ項目を指定できる設定項目は、文字型データ項目で指定 * 説明、ラベル ID、メンバー ID は指定なし * 開始日、期限、リマインダ設定は指定なし */ test('Succeed - Configs set by STRING; Description, LabelIds and MemberIds are blank', () => { const {idDef, urlDef} = prepareConfigs('listId2', 'カードのタイトル', '', null, null); const cardId = 'cardId2'; const cardUrl = 'https://trello.com/c/cardId2/2-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId2', 'カードのタイトル', '', [], [], null, null, null); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); /** * 選択型データ設定用のオブジェクトを作成 * @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('Succeed - Configs set by SELECT', () => { const {idDef, urlDef} = prepareConfigs('dummy', 'Card Title', 'Card Description', 'dummy', 'dummy'); setDataItem('ListId', 11, 'SELECT_SINGLE', prepareSelects('listId', 1)); setDataItem('LabelIds', 12, 'SELECT_CHECKBOX', prepareSelects('labelId', 2)); setDataItem('MemberIds', 13, 'SELECT_CHECKBOX', prepareSelects('memberId', 3)); const cardId = 'cardId3'; const cardUrl = 'https://trello.com/c/cardId3/3-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId1', 'Card Title', 'Card Description', ['labelId1', 'labelId2'], ['memberId1', 'memberId2', 'memberId3'], null, null, null); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); /** * 成功 * 文字型/選択型データ項目を指定できる設定項目は、選択型データ項目で指定 * ラベル ID、メンバー ID は指定なし * 開始日、期限、リマインダ設定は指定なし */ test('Succeed - Configs set by SELECT; LabelIds and MemberIds are not selected', () => { const {idDef, urlDef} = prepareConfigs('dummy', 'Card Title', 'Card Description', 'dummy', 'dummy'); setDataItem('ListId', 11, 'SELECT_SINGLE', prepareSelects('listId', 1)); setDataItem('LabelIds', 12, 'SELECT_CHECKBOX', new java.util.ArrayList()); setDataItem('MemberIds', 13, 'SELECT_CHECKBOX', new java.util.ArrayList()); const cardId = 'cardId3'; const cardUrl = 'https://trello.com/c/cardId3/3-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId1', 'Card Title', 'Card Description', [], [], null, null, null); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); /** * 成功 * リスト ID を固定値で指定 * 開始日、期限、リマインダ設定を指定 */ test('Succeed - List ID set as fixed value, with Start, Due and DueReminder', () => { const {idDef, urlDef} = prepareConfigs('dummy', 'Card Title', 'Card Description', '', ''); configs.put('conf_ListId', 'listId4'); setDataItem('Start', 11, 'DATE_YMD', java.sql.Date.valueOf('2025-01-01')); const dueTimestamp = new com.questetra.bpms.util.AddableTimestamp().addDays(15); setDataItem('Due', 12, 'DATETIME', dueTimestamp); configs.put('conf_DueReminder', '10'); const due = dateFormatter.format('UTC', "yyyy-MM-dd'T'HH:mm:ss'Z'", dueTimestamp); const cardId = 'cardId4'; const cardUrl = 'https://trello.com/c/cardId4/4-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId4', 'Card Title', 'Card Description', [], [], '2025-01-01', due, 10); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); /** * 成功 * 開始日、期限にデータ項目を設定し、値が空 */ test('Succeed - Start and Due are blank', () => { const {idDef, urlDef} = prepareConfigs('listId5', 'Card Title', 'Card Description', '', ''); setDataItem('Start', 11, 'DATE_YMD', null); setDataItem('Due', 12, 'DATETIME', null); const cardId = 'cardId5'; const cardUrl = 'https://trello.com/c/cardId5/5-card-title'; httpClient.setRequestHandler((request) => { assertCreateRequest(request, 'listId5', 'Card Title', 'Card Description', [], [], null, null, null); return httpClient.createHttpResponse(200, 'application/json', createCardResponse(cardId, cardUrl)); }); main(); // データ項目の値をチェック expect(engine.findData(idDef)).toEqual(cardId); expect(engine.findData(urlDef)).toEqual(cardUrl); }); ]]>