START_EVENT
2025-11-13
(C) Questetra, Inc. (MIT License)
3
2
This item starts a process when a file has been uploaded on the specified OneDrive folder.
このアイテムは、OneDrive の指定フォルダにファイルがアップロードされると、プロセスを開始します。
https://support.questetra.com/bpmn-icons/start-event-onedrive-file-uploaded/
https://support.questetra.com/ja/bpmn-icons/start-event-onedrive-file-uploaded/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADXUlEQVRYR8WXW0hUURSG/33GbC5e
8pJJF6nM6YKUmsFAIAZSONOM4FtqL/mQVg9GhXR5iCIiEAqF9KEMsvKpi06OZoRPGaRmVoSGU4om
aqaMzeXYOLPjTJ7R41w8k8bZLwNn1r/Wt9dee+29CSQeRHR8vVEpd7vzGTAHKKXpADYDiJnTTwEY
IIR0u+FuYxnmCYx6uxjfSwKotE2JbuoqB0EJALkYpwBYUNQwRHbDZtKNBtMEBVBqG0ooSAUAlcjA
i81sBPSs3ZRXE0gfEECuM94mlJb+Y2CBjBJSzTbpT/jz5RdAoTU+BGjBSgSf90EeOUz6wsU+fQBW
cuaLg/nLhABgbs2rV3bmQm8EtHRhTXgBPNUOV/8yCk4st42BbBu/O7wAitzGmyAoE+tlWXYUtxzN
htOcj78AeqNS4aI/Q9jneH5Ng0x1DCLkMlhZFz59m0ZZ9UfPr4jBOmQkjmtWHgC5rqGIUFIXTHih
QI3UzVHoH7HhsCYROzZF+JgPjNqxq/iViPgAJfQo25T3wAOg1BnvUkqP+VNGKsLQXpmF5PXCXmR1
zKJvyAqL3Yn4qHCoN0ZCHs6gvm0YxRXdS0IQQmrtTfpiD4BC2/gOANfffUbjVQ1yMtYKvnNZGJlg
kZESDeVqGSy2WbzoHPdkpdtswcnKniUBAHQ7TIYMHmBywcEiEPfey0FSgsL7zWJzosc8jazdcQI7
l5tiwvIbUaowTE47UfXMjMqnX4OBTDlMhlgegC62TNmgwp0z6UhLjsaqMMbzN5f25o4x5O5bhwhF
WNBZ2mdcyDn3Gu/NloB2DpOBBAToqs7GzqRIr/j7BIu+4V9I2xqN2KhwMSlGbcsgTlV9EAXgswSW
Bp135pQCrV3jOJSZICowb2RjXWjtHEfh9U5/OsES+BThj8daqOQyb+q/DFuRkbImJADOmKuNg+Xt
ePOZm6NgzBehv21YfzETek0iGIZgxun2OMjeEx8yACfIv/wWLR1jAq1gGwZqROePqLE/NRZjUzOo
ezmE++V7ER8tbv35aFzm0o63+YALGlEorfhS0XZsSVSKysTgmANX6nr92QpbMWch7WHEncFSH8dc
FiS9kPALJemVjIeQ9FL6PzIR8rWch5D0YcJDSPo0E3QQqR6nolreMoz+ACVfiTBvFfnjAAAAAElF
TkSuQmCC
{
const oauth2 = httpClient.createAuthSettingOAuth2(
'OneDrive',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/token',
'https://graph.microsoft.com/Files.ReadWrite.All offline_access',
'client_id',
'client_secret',
'access_token'
);
configs.putObject('conf_OAuth2', oauth2);
configs.put('conf_FolderUrl', folderUrl);
};
/**
* URL からドライブアイテムの情報を取得する GET リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param category
* @param limit
* @param timestampLowerLimit
*/
const assertGetRequest = ({ url, method, headers }, sharingUrl) => {
const encodedUrl = encodeSharingUrl(sharingUrl);
const expectedUrl = `${GRAPH_URI}shares/${encodedUrl}/driveItem`
+ `?${generateQueryString('select', 'id,parentReference/driveId,folder')}`;
expect(url).toEqual(expectedUrl);
expect(method).toEqual('GET');
expect(headers['Authorization']).toEqual('Bearer access_token');
};
/**
* ドライブアイテム取得の GET リクエストのレスポンスを準備
* @param driveId
* @param id
* @param childCount
* @return {Object} responseObj
*/
const prepareDriveItemResponse = (driveId, id, childCount = undefined) => {
const driveItem = {
id,
parentReference: { driveId }
};
if (childCount !== undefined) { // フォルダの場合のみ存在するプロパティ
Object.assign(driveItem, { folder: { childCount } });
}
return JSON.stringify(driveItem);
};
/**
* ドライブアイテム一覧を取得する GET リクエストのテスト
* @param {Object} request
* @param request.url
* @param request.method
* @param request.headers
* @param category
* @param limit
* @param timestampLowerLimit
*/
const assertListRequest = ({ url, method, headers }, drivePath, folderId) => {
const expectedUrl = `https://graph.microsoft.com/v1.0/${drivePath}/items/${folderId}/children`
+ `?${generateQueryString('$top', LIMIT)}`
+ `&${generateQueryString('$select', 'id,createdDateTime,file,webUrl')}`;
expect(url).toEqual(expectedUrl);
expect(method).toEqual('GET');
expect(headers['Authorization']).toEqual('Bearer access_token');
};
/**
* クエリパラメータのテスト用の文字列を生成する
* @param key
* @param value
* @returns {String}
*/
const generateQueryString = (key, value) => {
const encodedKey = encodeURIComponent(key);
const encodedValue = encodeURIComponent(value);
return `${encodedKey}=${encodedValue}`;
};
/**
* 返り値の file のテスト
* @param file
* @param id
* @param timestamp
* @param url
*/
const assertFile = (file, id, timestamp, url) => {
expect(file.id).toEqual(id);
expect(file.timestamp).toEqual(timestamp);
expect(file.url).toEqual(url);
};
/**
* 正常系のテストケース
*/
test('Success', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345",
"createdDateTime": "2012-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2012-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt",
"file" : {
"mimeType": "text/plain"
}
},
{
"id": "34567",
"createdDateTime": "2012-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
let reqCount = 0;
const driveId = 'driveId-1';
const folderId = 'folderId-1';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetRequest(request, folderUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse(driveId, folderId, 3));
}
assertListRequest(request, `drives/${driveId}`, folderId);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(3);
// 作成日の降順で返される
assertFile(result[0], '34567', dateFormatter.parse(DATETIME_FORMAT, '2012-12-25T10:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf');
assertFile(result[1], '12345', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T12:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file1.pdf');
assertFile(result[2], '23456', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T10:30:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt');
});
/**
* 正常系のテストケース
* フォルダ URL の指定が空で、ルートフォルダが対象になる場合
*/
test('Success - Root Folder', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345",
"createdDateTime": "2012-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2012-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/file2.txt",
"file" : {
"mimeType": "text/plain"
}
},
{
"id": "34567",
"createdDateTime": "2012-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
prepareConfigs('');
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
httpClient.setRequestHandler((request) => {
assertListRequest(request, 'me/drive', 'root');
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(3);
// 作成日の降順で返される
assertFile(result[0], '34567', dateFormatter.parse(DATETIME_FORMAT, '2012-12-25T10:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/file3.pdf');
assertFile(result[1], '12345', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T12:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/file1.pdf');
assertFile(result[2], '23456', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T10:30:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/file2.txt');
});
/**
* 正常系のテストケース
* レスポンスにファイルでないアイテムが含まれる場合、結果から除かれる
*/
test('Success - response includes an item which is not a file', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345",
"createdDateTime": "2022-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2022-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2/Folder",
"folder" : {
"childCount": 0
}
},
{
"id": "34567",
"createdDateTime": "2022-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
const folderUrl = 'https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2022-01-01T00:00:00+09:00');
let reqCount = 0;
const driveId = 'driveId-2';
const folderId = 'folderId-2';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetRequest(request, folderUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse(driveId, folderId, 3));
}
assertListRequest(request, `drives/${driveId}`, folderId);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(2); // ファイル以外のアイテムは除かれる
// 作成日の降順で返される
assertFile(result[0], '34567', dateFormatter.parse(DATETIME_FORMAT, '2022-12-25T10:00:00Z'),
'https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2/file3.pdf');
assertFile(result[1], '12345', dateFormatter.parse(DATETIME_FORMAT, '2022-12-12T12:00:00Z'),
'https://test-my.sharepoint.com/personal/bbb/Documents/TestFolder2/file1.pdf');
});
/**
* 正常系のテストケース
* レスポンスに timestampLowerLimit より前に作成されたファイルが含まれる場合、結果から除かれる
*/
test('Success - response includes an item created before timestampLowerLimit', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345",
"createdDateTime": "2012-12-11T00:00:00Z", // timestampLowerLimit より前
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2012-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt",
"file" : {
"mimeType": "text/plain"
}
},
{
"id": "34567",
"createdDateTime": "2012-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
let reqCount = 0;
const driveId = 'driveId-3';
const folderId = 'folderId-3';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetRequest(request, folderUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse(driveId, folderId, 3));
}
assertListRequest(request, `drives/${driveId}`, folderId);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(2); // timestampLowerLimit より前のファイルは除かれる
// 作成日の降順で返される
assertFile(result[0], '34567', dateFormatter.parse(DATETIME_FORMAT, '2012-12-25T10:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf');
assertFile(result[1], '23456', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T10:30:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt');
});
/**
* 正常系のテストケース
* レスポンスに含まれるファイル件数が limit を超える
*/
test('Success - response includes more files than limit', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345",
"createdDateTime": "2012-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2012-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt",
"file" : {
"mimeType": "text/plain"
}
},
{
"id": "34567",
"createdDateTime": "2012-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "45678",
"createdDateTime": "2012-12-30T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file4.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder';
prepareConfigs(folderUrl);
const limit = 2;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
let reqCount = 0;
const driveId = 'driveId-1';
const folderId = 'folderId-1';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetRequest(request, folderUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse(driveId, folderId, 3));
}
assertListRequest(request, `drives/${driveId}`, folderId);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(2); // limit 件数までしか返されない
// 作成日の降順で返される
assertFile(result[0], '45678', dateFormatter.parse(DATETIME_FORMAT, '2012-12-30T10:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file4.pdf');
assertFile(result[1], '34567', dateFormatter.parse(DATETIME_FORMAT, '2012-12-25T10:00:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf');
});
/**
* 異常系のテストケース
* ドライブアイテム取得の GET リクエストで 403 エラー
*/
test('Fail in get drive item request', () => {
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
httpClient.setRequestHandler((request) => {
assertGetRequest(request, folderUrl);
return httpClient.createHttpResponse(403, 'application/json', '{}');
});
try {
list(limit, timestampLowerLimit);
fail();
} catch (e) {
expect(e.toString()).toEqual('Failed to get drive item. status: 403');
}
});
/**
* 異常系のテストケース
* フォルダ URL として、ファイル URL を指定した場合
*/
test('Fail - specified URL is not a folder', () => {
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/file.txt';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
httpClient.setRequestHandler((request) => {
assertGetRequest(request, folderUrl);
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse('driveId-1', 'fileId-1'));
});
try {
list(limit, timestampLowerLimit);
fail();
} catch (e) {
expect(e.toString()).toEqual('The specified URL is not a folder.');
}
});
/**
* 正常系のテストケース
* フォルダ内のドライブアイテム一覧取得の GET リクエストで 403 エラー
*/
test('Fail in get children request', () => {
prepareConfigs('');
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
httpClient.setRequestHandler((request) => {
assertListRequest(request, 'me/drive', 'root');
return httpClient.createHttpResponse(403, 'application/json', '{}');
});
try {
list(limit, timestampLowerLimit);
fail();
} catch (e) {
expect(e.toString()).toEqual('Failed to get children of the folder. status: 403');
}
});
/**
* 異常系のテストケース
* レスポンスに次のページがあることを示すプロパティがある場合
*/
test('Fail - response indicates there are more items', () => {
const response = {
"value": [ // 実際には 1000 件のアイテムを含むが、省略
{
"id": "12345",
"createdDateTime": "2012-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
],
"@odata.nextLink": "https://graph.microsoft.com/v1.0/me/root/children?$top=1000&$select=id,createdDateTime,file,webUrl&$skip=1000"
};
prepareConfigs('');
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
httpClient.setRequestHandler((request) => {
assertListRequest(request, 'me/drive', 'root');
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
try {
list(limit, timestampLowerLimit);
fail();
} catch (e) {
expect(e.toString()).toEqual(`More than ${LIMIT} items are in the specified folder.`);
}
});
/**
* 正常系のテストケース
* プロセス開始済みのファイルを含むレスポンス
*/
test('Success - response includes files that are already processed', () => {
const response = {
"value": [ // 作成日順とは限らない
{
"id": "12345", // プロセス開始済み
"createdDateTime": "2012-12-12T12:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file1.pdf",
"file" : {
"mimeType": "application/pdf"
}
},
{
"id": "23456",
"createdDateTime": "2012-12-12T10:30:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt",
"file" : {
"mimeType": "text/plain"
}
},
{
"id": "34567", // プロセス開始済み
"createdDateTime": "2012-12-25T10:00:00Z",
"webUrl": "https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file3.pdf",
"file" : {
"mimeType": "application/pdf"
}
}
]
};
const folderUrl = 'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder';
prepareConfigs(folderUrl);
const limit = 3;
const timestampLowerLimit = dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T00:00:00+09:00');
// engine.isProcessStarted のモック設定
engine.addProcessStartedSet('12345'); // 1 つ目のファイル ID をプロセス開始済みにセット
engine.addProcessStartedSet('34567'); // 3 つ目のファイル ID をプロセス開始済みにセット
let reqCount = 0;
const driveId = 'driveId-1';
const folderId = 'folderId-1';
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetRequest(request, folderUrl);
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', prepareDriveItemResponse(driveId, folderId, 3));
}
assertListRequest(request, `drives/${driveId}`, folderId);
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(response));
});
const result = list(limit, timestampLowerLimit);
expect(result.length).toEqual(1); // プロセス開始済みのファイルは除外される
// プロセス未開始のファイルのみが返される
assertFile(result[0], '23456', dateFormatter.parse(DATETIME_FORMAT, '2012-12-12T10:30:00Z'),
'https://test-my.sharepoint.com/personal/aaa/Documents/TestFolder/file2.txt');
});
]]>