3 2 2024-02-27 (C) Questetra, Inc. (MIT License) This item creates a post in draft status on WordPress.com. この工程は、WordPress.com 上に下書き状態の記事(投稿)を作成します。 https://support.questetra.com/bpmn-icons/service-task-wordpress-post-create/ https://support.questetra.com/ja/bpmn-icons/service-task-wordpress-post-create/ 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 { const oauth2 = httpClient.createAuthSettingOAuth2( 'WordPress.com', 'https://public-api.wordpress.com/oauth2/authorize', 'https://public-api.wordpress.com/oauth2/token', 'posts', 'client_id', 'client_secret', 'access_token' ); configs.putObject('conf_Auth', oauth2); configs.put('conf_Domain', domain); configs.put('conf_Title', title); configs.put('conf_Content', content); configs.put('conf_Excerpt', excerpt); configs.put('conf_Slug', slug); setDataItem('FeaturedImage', 5, 'STRING_TEXTFIELD', featuredImage); setDataItem('Categories', 1, 'STRING_TEXTAREA', categories); setDataItem('Tags', 2, 'STRING_TEXTAREA', tags); const postIdDef = engine.createDataDefinition('投稿 ID', 3, 'q_PostId', 'STRING_TEXTFIELD'); engine.setData(postIdDef, '事前文字列'); configs.putObject('conf_PostId', postIdDef); const postUrlDef = engine.createDataDefinition('投稿 URL', 4, 'q_PostUrl', 'STRING_TEXTFIELD'); engine.setData(postUrlDef, '事前文字列'); configs.putObject('conf_PostUrl', postUrlDef); return { postIdDef, postUrlDef }; }; /** * データ項目を作成し、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.'); } }; /** * 本文が空でエラー */ test('Content is blank', () => { prepareConfigs('test1.example.com', 'タイトル', '', '抜粋', 'slug-12345', '55', '0\n9\n10', '100\n102'); assertError('Content is blank.'); }); /** * アイキャッチ画像のメディア ID が非負整数でない(文字型) */ test('Media ID for Featured Image must be a non-negative integer - STRING', () => { prepareConfigs('test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', 'invalid', '0\n9\10', '100\n102'); assertError('Media ID for Featured Image must be a non-negative integer.'); }); /** * カテゴリ ID に非負整数以外が含まれている(文字型) */ test('Category ID must be a non-negative integer - STRING', () => { prepareConfigs('test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', '0\nカテゴリ1', '100\n102'); assertError('Category ID must be a non-negative integer.'); }); /** * タグ ID に非負整数以外が含まれている(文字型) */ test('Tag ID must be a non-negative integer - STRING', () => { prepareConfigs('test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', '0\n9\n10', '100-tag\n102'); assertError('Tag ID must be a non-negative integer.'); }); /** * 記事作成の POST リクエストのテスト * @param {Object} request * @param request.url * @param request.method * @param request.headers * @param request.contentType * @param request.body * @param domain * @param title * @param content * @param excerpt * @param slug * @param featuredImage * @param categoryList * @param tagList */ const assertRequest = ({ url, method, headers, contentType, body }, domain, title, content, excerpt, slug, featuredImage, categoryList, tagList) => { const expectedUrl = `https://public-api.wordpress.com/rest/${API_VERSION}/sites/${encodeURIComponent(domain)}/posts/new` + `?fields=${encodeURIComponent('ID,URL')}`; expect(url).toEqual(expectedUrl); expect(method).toEqual('POST'); expect(headers['Authorization']).toEqual('Bearer access_token'); expect(contentType).toEqual('application/json'); const bodyObj = JSON.parse(body); expect(bodyObj.title).toEqual(title); expect(bodyObj.content).toEqual(content); expect(bodyObj.excerpt).toEqual(excerpt); expect(bodyObj.slug).toEqual(slug); expect(bodyObj.featured_image).toEqual(featuredImage); expect(bodyObj.categories).toEqual(categoryList); expect(bodyObj.tags).toEqual(tagList); expect(bodyObj.status).toEqual('draft'); }; /** * 記事作成の POST リクエストでエラー */ test('Fail in POST request', () => { prepareConfigs('test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', '0\n1\n9\n10', '100\n199\n99999'); httpClient.setRequestHandler((request) => { assertRequest(request, 'test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', ['0', '1', '9', '10'], ['100', '199', '99999']); return httpClient.createHttpResponse(400, 'application/json', '{}'); }); assertError('Failed to create post. status: 400'); }); /** * 記事作成の API レスポンスを作成 * @param postId * @param postUrl */ const createResponse = (postId, postUrl) => { return httpClient.createHttpResponse(200, 'application/json', JSON.stringify({ ID: postId, URL: postUrl })); }; /** * 成功 - すべての項目を指定 */ test('Succeed - with all configurations', () => { const categories = '0\n\n\n9'; // 空行は無視される const tags = '\n100\n99\n123456789\n'; // 空行は無視される const { postIdDef, postUrlDef } = prepareConfigs('test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', categories, tags); const postId = '12345'; const postUrl = 'https://test1.example.com/?p=12345'; httpClient.setRequestHandler((request) => { assertRequest(request, 'test1.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', '55', ['0', '9'], ['100', '99', '123456789']); return createResponse(postId, postUrl); }); expect(main()).toEqual(undefined); expect(engine.findData(postIdDef)).toEqual(postId); expect(engine.findData(postUrlDef)).toEqual(postUrl); }); /** * 成功 - 必須項目のみ指定 */ test('Succeed - with only required configurations', () => { const { postIdDef, postUrlDef } = prepareConfigs('test1.example.com', '', '本文\nここは本文です', '', '', null, '', ''); configs.put('conf_PostId', ''); configs.put('conf_PostUrl', ''); const postId = '12345'; const postUrl = 'https://test1.example.com/?p=12345'; httpClient.setRequestHandler((request) => { assertRequest(request, 'test1.example.com', '', '本文\nここは本文です', '', '', null, [], []); return createResponse(postId, postUrl); }); expect(main()).toEqual(undefined); expect(engine.findData(postIdDef)).toEqual('事前文字列'); expect(engine.findData(postUrlDef)).toEqual('事前文字列'); }); /** * 選択型データ設定用のオブジェクトを作成 * @param num * @return selects */ const prepareSelects = (offset, num) => { const selects = new java.util.ArrayList(); for (let i = 0; i < num; i++) { const id = `${offset + i + 1}`; const item = engine.createItem(id, `${id} を選択`); selects.add(item); } return selects; }; /** * 成功 - アイキャッチ画像、カテゴリ、タグを選択型データ項目で指定 */ test('Succeed - featured image, categories and tags set by SELECT', () => { const { postIdDef, postUrlDef } = prepareConfigs('test2.example.com', 'タイトル', '本文', '抜粋\nこれは抜粋です', 'slug-99999', 'dummy', 'dummy', 'dummy'); setDataItem('FeaturedImage', 10, 'SELECT_SINGLE', prepareSelects(10, 1)); setDataItem('Categories', 11, 'SELECT_CHECKBOX', prepareSelects(0, 3)); setDataItem('Tags', 12, 'SELECT_CHECKBOX', prepareSelects(900, 2)); const postId = '67890'; const postUrl = 'https://test2.example.com/?p=67890'; httpClient.setRequestHandler((request) => { assertRequest(request, 'test2.example.com', 'タイトル', '本文', '抜粋\nこれは抜粋です', 'slug-99999', '11', ['1', '2', '3'], ['901', '902']); return createResponse(postId, postUrl); }); expect(main()).toEqual(undefined); expect(engine.findData(postIdDef)).toEqual(postId); expect(engine.findData(postUrlDef)).toEqual(postUrl); }); /** * 成功 - アイキャッチ画像、カテゴリ、タグを選択型データ項目で指定し、1 つも選択されていない */ test('Succeed - categories and tags set by SELECT, no item selected', () => { const { postIdDef, postUrlDef } = prepareConfigs('test2.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', 'dummy', 'dummy', 'dummy'); setDataItem('FeaturedImage', 10, 'SELECT_SINGLE', null); setDataItem('Categories', 11, 'SELECT_CHECKBOX', null); setDataItem('Tags', 12, 'SELECT_CHECKBOX', null); const postId = '67890'; const postUrl = 'https://test2.example.com/?p=67890'; httpClient.setRequestHandler((request) => { assertRequest(request, 'test2.example.com', 'タイトル', '本文', '抜粋', 'slug-12345', null, [], []); return createResponse(postId, postUrl); }); expect(main()).toEqual(undefined); expect(engine.findData(postIdDef)).toEqual(postId); expect(engine.findData(postUrlDef)).toEqual(postUrl); }); /** * アイキャッチ画像のメディア ID が非負整数でない(選択型) */ test('Media ID for Featured Image must be a non-negative integer - SELECT', () => { prepareConfigs('test2.example.com', 'タイトル', '本文', '抜粋\nこれは抜粋です', 'slug-99999', '1', '2', '3'); const selects = [engine.createItem('invalid', '非負整数でない値を選択')]; setDataItem('FeaturedImage', 10, 'SELECT_SINGLE', selects); assertError('Media ID for Featured Image must be a non-negative integer.'); }); /** * カテゴリ ID が非負整数でない(選択型) */ test('Category ID must be a non-negative integer - SELECT', () => { prepareConfigs('test2.example.com', 'タイトル', '本文', '抜粋\nこれは抜粋です', 'slug-99999', '1', '2', '3'); const selects = prepareSelects(0, 3); selects.add(engine.createItem('-1', '非負整数でない値を選択')); setDataItem('Categories', 10, 'SELECT_CHECKBOX', selects); assertError('Category ID must be a non-negative integer.'); }); /** * タグ ID が非負整数でない(選択型) */ test('Tag ID must be a non-negative integer - SELECT', () => { prepareConfigs('test2.example.com', 'タイトル', '本文', '抜粋\nこれは抜粋です', 'slug-99999', '1', '2', '3'); const selects = prepareSelects(0, 2); selects.add(engine.createItem('1!', '非負整数でない値を選択')); setDataItem('Tags', 10, 'SELECT_CHECKBOX', selects); assertError('Tag ID must be a non-negative integer.'); }); ]]>