2022-03-17
(C) Questetra, In. (MIT License)
2
Get data in a specified row from a Google Sheet.
Google スプレッドシートから指定した行のデータを取得します。
https://support.questetra.com/bpmn-icons/service-task-google-sheets-row-get/
https://support.questetra.com/ja/bpmn-icons/service-task-google-sheets-row-get/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADbElEQVRYR8WXS0hUURjH/2dGJFDz
lqNimmORhAU5hRVFojgTQSTarl3azN5x1aboQdAqGoVc2AyOFoGCpQuN7E6MRIVW4BBZUqJkbYTw
+H7M48Sdx3Ve986d0crFuDjfd8/v+5/vcQ7Bf/4jyezPWfX1IKQKDDoAHIj/P8AwBoCCYAwETnqF
71f63YQAXEc1B19aE8DMAOGUfZhRgFig8rTQRieV85EF4Gw1DQC5r3zj6K0YBUMjNTn6pCAkATir
3gJCmpRFnNDKQo18czyruACcVW8HIZcTfjYpA2anRkdjtEsMQHjkvefuoqawQvTxMV8w54S8Y2DM
/4uhmRGUZhfj9gcbBn+8lcZirIWaHOZwgwiAwJmrOkIGzro2lOeUJozzxcwITuYf8ts1v2lB39Sw
HMTF8JwQAQLZrp4KT7hkAbj0LMxvLOHquwfonuQlIBiFyrsvVB2bADbDTQA3wr1SARD8F9zLuD7a
jq6JQSklblEjL+yHTQCrQWgk2akC7FCnY2d6hug+uzqHSy+vSapAjY5dIkCwwz2LtlaqwNz6Ihbd
yxHuK551nHpqSpgLfgWkal4pQLxdlj1rKOqqTVgRAQCbwQmgKlUFUgIAhqmRrw4pMA1CtHIAK541
LGxEyhxtr1apkbsjMC4SK4AxauKPhhRg8aIIPwLX7294NPEch3fvR/d3HpUFOuzJ0IhuHuYF//M9
us/eUQYgjE8jT5ICGJoZhU5TivbxPpwvPo2izLxNAJ8X9omBFAGs+oRHICjw6tdHHNMcRNvnXtRq
z2BvZr4I4PZ58PBLfxIAzEWNDp3iJBQAeiYdOJJzAJ1fB2AoOoHCzFwRwOvzon/6dRIAkUkYd/RG
58Do7DgqcsvQ+qkHdSWV0GYVRChwz/VEOUBwMIWqQLhqyTaibU9CxvxDSXErFspwyb0q3VgAqAiB
RkkZMsxTE++v120ZRik0ojjDSBjH3rTp8IH0V1oxwzzUnpKYcRxoyZEXkqELrTieVyYru9Si0DW1
j+tjl4NnH1qQvZKltLO8kyi9JEBwOm7/pZSxTmpyNETz/atreUzksgqEFv0XFRB79E1J8dEICQfW
kNLDRIQIPM3MYDArBhE2JhCeZpYtPc2iIw0ogmoQogMYB5DygA1zAYSCMeGR6pSLWHEOKJZ5i4Z/
AEwJzTC2ALrNAAAAAElFTkSuQmCC
{
configs.put('conf_OAuth2', 'Google');
configs.put('conf_SheetId', sheetId);
configs.put('conf_SheetTitle', sheetTitle);
configs.put('conf_Range', range);
// 行番号を設定したデータ項目を作成し、C4 に設定
const rowNoDef = engine.createDataDefinition('行番号', 1, 'q_rowNo', 'STRING_TEXTFIELD');
engine.setData(rowNoDef, rowNo);
configs.putObject('conf_RowNo', rowNoDef);
const columnDefList = [];
types.forEach((type, i) => {
// 指定したタイプのデータ項目を作成し、C6 以降に順に設定
if (type !== null){
const columnDef = engine.createDataDefinition(`データ${i+1}`, i+2, `q_data${i+1}`, type);
engine.setData(columnDef, '事前文字列');
configs.putObject(`conf_Column${i+1}`, columnDef);
columnDefList.push(columnDef);
}
});
return columnDefList;
};
test('Row Number is invalid', () => {
//行番号が不適切な場合
prepareConfigs(configs, 'id', 'title', 'invalidrow', 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTFIELD');
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('Invalid Row number.');
}
});
test('Row Number is empty', () => {
//行番号が入力されていない場合
prepareConfigs(configs, 'id', 'title', null, 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTFIELD');
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('Row number is empty.');
}
});
test('Column Range is invalid', () => {
//列範囲が不適切である場合
prepareConfigs(configs, 'id', 'title', '1', 'invalidrange', 'STRING_TEXTFIELD', 'STRING_TEXTFIELD');
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('Invalid Range.');
}
});
test('Same Data Item is set twice', () => {
//同じデータ項目がC6に2回セットされている場合
const columnDefList = prepareConfigs(configs, 'id', 'title', '1', 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTFIELD');
configs.putObject("conf_Column2", columnDefList[0]);
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('The same data item is set multiple times.');
}
});
test('No Data Item is set', () => {
//保存先データ項目がひとつも設定されていない場合
const columnDefList = prepareConfigs(configs, 'id', 'title', '1', 'A:B');
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('No Data Item is set.');
}
});
/**
* リクエストのテスト
* @param url
* @param method
* @param contentType
* @param body
* @param sheetId
* @param sheetTitle
* @param range
*/
const assertRequest = ({url, method, contentType, body}, sheetId, sheetTitle, range) => {
const enSheetId = encodeURIComponent(sheetId);
const enSheetTitle = encodeURIComponent(sheetTitle);
expect(url).toEqual(`https://sheets.googleapis.com/v4/spreadsheets/${enSheetId}/values/${enSheetTitle}!${range}?valueRenderOption=UNFORMATTED_VALUE&dateTimeRenderOption=FORMATTED_STRING&majorDimension=ROWS`);
expect(method).toEqual('GET');
};
test('Succeed to get - TEXTFIELD and TEXTAREA', () => {
//行取得に成功する場合
const columnDefList = prepareConfigs(configs, 'id', 'シート 1', '1', 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTAREA');
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 1', 'A1:B1');
const ret = JSON.stringify({"values":[['A列','B列\n複数行']]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
expect(engine.findData(columnDefList[0])).toEqual('A列');
expect(engine.findData(columnDefList[1])).toEqual('B列\n複数行');
});
test('Succeed to get - 10 columns', () => {
//保存先データ項目がすべて設定されている場合
const types = new Array(10).fill('STRING_TEXTFIELD');
const columnDefList = prepareConfigs(configs, 'id', 'シート 2!', '70', 'XA:XJ', ...types);
const rowData = Array.from({length: 10}, (_, i) => `値${i+1}`);
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 2!', 'XA70:XJ70');
const ret = JSON.stringify({"values":[rowData]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
columnDefList.forEach((def, i) => {
expect(engine.findData(def)).toEqual(`値${i+1}`);
});
});
test('Succeed to get - Some data items are not set', () => {
//保存先データ項目が設定されていない列がある場合
const types = new Array(10).fill('STRING_TEXTFIELD');
const columnDefList = prepareConfigs(configs, 'id', 'シート 1', '1', 'A:J', ...types);
configs.put('conf_Column5', '');
configs.put('conf_Column8', '');
const rowData = Array.from({length: 10}, (_, i) => `値${i+1}`);
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 1', 'A1:J1');
const ret = JSON.stringify({"values":[rowData]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
columnDefList.forEach((def, i) => {
if (i === 4 || i === 7) { // 5, 8列目は保存先が未設定
expect(engine.findData(def)).toEqual('事前文字列');
return;
}
expect(engine.findData(def)).toEqual(`値${i+1}`);
});
});
test('Succeed to get - Number of Returned values is bigger than 10', () => {
//取得した行データの値の数が 10 を超える場合
const types = new Array(10).fill('STRING_TEXTFIELD');
const columnDefList = prepareConfigs(configs, 'id', 'シート 1', '1', 'A:Z', ...types);
const rowData = Array.from({length: 11}, (_, i) => `値${i+1}`);
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 1', 'A1:Z1');
const ret = JSON.stringify({"values":[rowData]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
columnDefList.forEach((def, i) => {
expect(engine.findData(def)).toEqual(`値${i+1}`);
});
});
test('Succeed to get - Number of Returned values is smaller than that of data items', () => {
//取得した行データの値の数が設定した保存先データ項目数より少ない場合
const types = new Array(10).fill('STRING_TEXTFIELD');
const columnDefList = prepareConfigs(configs, 'id', 'シート 1', '1', 'A:J', ...types);
const rowData = Array.from({length: 8}, (_, i) => `値${i+1}`);
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 1', 'A1:J1');
const ret = JSON.stringify({"values":[rowData]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
columnDefList.forEach((def, i) => {
if (i > 7) { // 9列目、10列目の保存される値は null
expect(engine.findData(def)).toEqual(null);
return;
}
expect(engine.findData(def)).toEqual(`値${i+1}`);
});
});
test('Succeed to get Numeric data', () => {
//数値データは文字列に変換され保存される
const columnDefList = prepareConfigs(configs, 'id', 'シート 1', '1', 'A:A', 'STRING_TEXTFIELD');
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'シート 1', 'A1:A1');
const ret = JSON.stringify({"values":[[100]]});
return httpClient.createHttpResponse(200, 'application/json', ret);
});
execute();
expect(engine.findData(columnDefList[0])).toEqual('100');
});
test('404 Error', () => {
//APIからエラーが返ってくる場合
const columnDefList = prepareConfigs(configs, 'id', 'title', '1', 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTAREA');
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'title', 'A1:B1', 1);
return httpClient.createHttpResponse(404, 'application/json', JSON.stringify({}));
});
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('Failed to get. status:404');
}
});
test('All cells are empty', () => {
//範囲内のセルがすべて空の場合
const columnDefList = prepareConfigs(configs, 'id', 'title', '1', 'A:B', 'STRING_TEXTFIELD', 'STRING_TEXTAREA');
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'title', 'A1:B1', 1);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify({}));
});
try {
execute();
fail('not come here');
} catch (e) {
expect(e.message).endsWith('No Data in range.');
}
});
test('Validation Error - Unable to save multi-line string to STRING_TEXTFIELD', () => {
//単一行データ項目に複数行の文字列を保存しようとしてエラーになる場合
const columnDefList = prepareConfigs(configs, 'id', 'title', '1', 'A:A', 'STRING_TEXTFIELD');
httpClient.setRequestHandler((request) => {
assertRequest(request, 'id', 'title', 'A1:A1', 1);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify({"values":[['複数行の\n文字列']]}));
});
try {
execute();
fail('not come here');
} catch (e) {
//エラーになるのが正しい
}
});
]]>