3
2
2024-10-08
(C) Questetra, Inc. (MIT License)
This item removes a collaborator from a specified repository on GitHub.
この工程は、GitHub の指定したリポジトリのコラボレーターを削除します。
https://support.questetra.com/bpmn-icons/service-task-github-repository-collaborator-remove/
https://support.questetra.com/ja/bpmn-icons/service-task-github-repository-collaborator-remove/
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABM9JREFUWEfF
V2tQlFUYfs4ugiKgePkTiE3gCIssGWRhg1EwaE2OUZNjVDIFEwyJM12MSZKgokkNUdZNMhwCCg0p
Bi8UxGVRblkgLHFJ12ZipImBLiAOg7h7mvfT/dz99lt2sR+8v3bPe3vOez0fw/+gqKgoF1LX6XQ3
79YMc1bxvuBgP2ZSRjHGH4SJqcCwGsCi2/pj4PgVCt7HOfuJK4y633p7B52x7RBAgCo0GCYeD4bn
AKxyxiiAy+A4CQUrM/R1986kYxdAWFjYvH8nb6YoOE/igNpJx1ZiDNCbGCtcvMCloKOjY1rOhiyA
ALXal93gb3PG0u7GsVSHca7hrmyfQa+/asOTHpBzTCMLQKIj5wqFAiaTyZGYmX8M85AlBWEVAQr7
+PUbufZu7uvrg+SkV3B/aAj8VqyAu7u7AGB09C8MXLqEH+oacKK8wi4gioTXQtc3LdNhBcBfFZrG
OM+Xs7AjNRlpqSmgW89Evw8OIiExGUNDf8iKccZ2Xunr1piZIgCqdsZ5mbTgvL0Xo7ysFPeu9HM2
1EJU9uXm4VhRiY0OFSZnLN7cHXcABKpzwLBbqlH1zddQBQU67dxScGv8dlzs6rbV5fjIMKDPIIYA
gIaMwqSsk/b5i/Hb8N677wgGJicnsSfrA6S9loKVfn7CLaempqBUKuHq6gqj0Sjkf8H8+Xgmboug
MzY2hnWPRMkV6mWTwhhDw0oA4B+k3s6AYkuoi7y80N7cCBcXYdqCchuzabPwe/nyZRgZGRXFyanS
RYmJieuIeGgdSoo+F3nfVlYhPSPTJgocSLjSry8RAASoQjTgbIelVPy2rcjOFKIk0MjoKNZviHaY
Crr93pz3Rbmx8XGEPxxpq8f4YUNfT9otAIHqejA8bil1+GAuNsbGiEd0C7qNI6IuudDaBIqgmQJD
1sJolMwLjgbDgD76FoAgNU0oH0vjjbXVoL4nonyvXrPWkW+Rn5+3H09sjBX/U1u2trVL9YcM/Xpf
Riv16vDf/wDwsJT45eIFuLm5CUdUYIEhDzgN4OOcbDwb97Qor9EWIF97RKo/YejXe9oF0Ha+AcuW
LhWV1j8abVV4M6GpPHkca4JVoshb6btRdfqsPAB7Kag48SVC1SGiErUYtaEjWrLEGy26OrF7SD7y
sVj8OTwsnwJ7RUgdQJ1gSY4KkSJGwH187hHV7KbPqghl2pBGcPv5RmH2U89T7xNRO3Z2diEjMxvU
YkQ0sOK2bBbCLt0V39XUYufru2wDZ9mGcoOINPI+2YunntyE6elpYcq99MLzgiGacOERG0SjSS8n
IH3XGzZOqHvCIyJx7dqEDc9qENkbxR4eC9FUXwMvT090detxvLwCqwL8cfpMNfr6B0SjFJ3Wpnob
J3n5WnxacFSubKxH8e06kF1GVFS11aeEwUKjVt/TA925ZhQVl4qG6V3Q/XOblSPtkaM4qNHK16x0
GQkA7Kxj4lE9fFH4mbgVzzW3IPHVVNG4p6cHOn9sEf7Tgtp/4BCKS7+SdW53HZP0TA8S4lNbfpi9
B1WnzqKw6M7uooX1/ZlK1NTW4cAhje3YtYBi90FCMo6eZPLxdP7U4ZNMSMUsHqXOuxYkHT9KzQbn
9FluBjGnHyaWoZ2zTzNpfufs43SWhTZr8f8AaTovPzYDLOEAAAAASUVORK5CYII=
{
const auth = httpClient.createAuthSettingToken('Personal Access Token', 'github-token-12345');
configs.putObject('conf_Auth', auth);
// 文字型データ項目を準備して、config に指定
const repositoryUrlDef = engine.createDataDefinition('リポジトリURL', 2, 'q_RepositoryUrl', 'STRING_TEXTFIELD');
configs.putObject('conf_RepositoryUrl', repositoryUrlDef);
// 文字型データ項目の値(リポジトリURL)を指定
engine.setData(repositoryUrlDef, repositoryUrl);
// 文字型データ項目を準備して、config に指定
const nameDef = engine.createDataDefinition('ハンドル名', 3, 'q_Handle', 'STRING_TEXTFIELD');
configs.putObject('conf_UserName', nameDef);
// 文字型データ項目の値(ハンドル名)を指定
engine.setData(nameDef, name);
};
/**
* 異常系のテスト
* @param func
* @param errorMsg
*/
const assertError = (func, errorMsg) => {
let failed = false;
try {
func();
} catch (e) {
failed = true;
expect(e.message).toEqual(errorMsg);
}
if (!failed) {
fail('No error was thrown.');
}
};
/**
* conf_RepositoryUrl にデータ項目を設定しているが、そのデータ項目の値が空でエラーになる場合
*/
test("Repository's URL is blank - Repository's URL specified by String Data", () => {
prepareConfigs(null, 'user1');
assertError(main, "Repository's URL is blank.");
});
/**
* conf_UserName にデータ項目を設定しているが、そのデータ項目の値が空でエラーになる場合
*/
test("handle is blank - handle specified by String Data", () => {
prepareConfigs("https://github.com/user1Org/user1Org123", null);
assertError(main, "handle is blank.");
});
/**
* リポジトリURLが不正
*/
test("Invalid repository URL - handle specified by String Data", () => {
prepareConfigs("https://invalid.com/user1Org/user1Org123", 'user1');
assertError(main, "Invalid repository URL.");
});
/**
* リクエストのテスト(ユーザーがリポジトリ招待中であるかどうかを確認する)
* @param {Object} request
* @param request.url
* @param request.method
* @param ownerAndRepo
*/
const assertGetInviteeRequest = ({ url, method }, ownerAndRepo) => {
expect(url).toEqual(`https://api.github.com/repos/${ownerAndRepo}/invitations?per_page=100`);
expect(method).toEqual('GET');
};
/**
* ユーザーがリポジトリ招待中であるかどうかを確認する API リクエストでエラー
*/
test('GETinvitee Failed', () => {
prepareConfigs("https://github.com/user1Org/user1Org123", 'user2');
httpClient.setRequestHandler((request) => {
assertGetInviteeRequest(request, 'user1Org/user1Org123');
return httpClient.createHttpResponse(404, 'application/json', '{}');
});
assertError(main, 'Failed to get invitee information. status: 404');
});
/**
* GETinvitee リクエスト のレスポンス
*/
const INVITEE_RESPONSE = [
{
"id": 1,
"repository": {
"full_name": "octocat/Hello-World",
"owner": {
"login": "userA",
"url": `https://api.github.com/users/userA`,
"type": "User"
}
},
"invitee": {
"login": "userB",
"id": 1,
"url": `https://api.github.com/users/userB`,
"html_url": "https://github.com/userB",
"type": "User"
},
"inviter": {
"login": "userC",
"id": 1,
"url": `https://api.github.com/users/userC`,
"type": "User"
},
"permissions": "read"
},
{
"id": 2,
"repository": {
"full_name": "octocat/Hello-World",
"owner": {
"login": "user2",
"url": `https://api.github.com/users/user2`,
"type": "User"
}
},
"invitee": {
"login": "user3",
"id": 1,
"url": `https://api.github.com/users/user3`,
"html_url": "https://github.com/user3",
"type": "User"
},
"inviter": {
"login": "user4",
"id": 1,
"url": `https://api.github.com/users/user4`,
"type": "User"
},
"permissions": "write"
}
];
/**
* レスポンスに含まれる招待数が最大値 100 のためエラー
*/
test('Too many invitations found', () => {
prepareConfigs("https://github.com/user1Org/user1Org100", 'user100', 'pull');
httpClient.setRequestHandler((request) => {
assertGetInviteeRequest(request, 'user1Org/user1Org100', 'user100');
const invitee_ResponseObj = [];
for (let i = 0; i < 100; i++) {
invitee_ResponseObj.push({
"id": `${i}`,
"repository": {
"full_name": "octocat/Hello-World",
"owner": {
"login": `UserA${i}`,
"url": `https://api.github.com/users/userA${i}`,
"type": "User"
}
},
"invitee": {
"login": `UserB${i}`,
"id": `${i}`,
"url": `https://api.github.com/users/userB${i}`,
"html_url": `https://github.com/userB${i}`,
"type": "User"
},
"inviter": {
"login": `UserC${i}`,
"id": `${i}`,
"url": `https://api.github.com/users/userC${i}`,
"type": "User"
},
"permissions": "read"
});
}
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(invitee_ResponseObj));
});
assertError(main, 'Too many invitations found.');
});
/**
* リクエストのテスト(リポジトリ招待を削除する)
* @param {Object} request
* @param request.url
* @param request.method
* @param ownerAndRepo
* @param invitationId
*/
const assertRemoveInvitationRequest = ({ url, method }, ownerAndRepo, invitationId) => {
expect(url).toEqual(`https://api.github.com/repos/${ownerAndRepo}/invitations/${invitationId}`);
expect(method).toEqual('DELETE');
};
/**
* 招待削除成功
* URL 、ユーザ名をデータ項目で指定
*/
test('Succeed - invitation', () => {
prepareConfigs("https://github.com/user1Org/user1Org456", 'user3');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user1Org/user1Org456');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
assertRemoveInvitationRequest(request, 'user1Org/user1Org456', '2');
return httpClient.createHttpResponse(204, 'application/json', '{}');
});
main();
});
/**
* 招待削除失敗
* 招待が承認済み、キャンセル済み以外のエラー
* URL 、ユーザ名をを固定値で指定
*/
test('Failed - invitation - 403', () => {
prepareConfigs('null', 'null');
configs.put('conf_RepositoryUrl', 'https://github.com/user1Org/user1Org456');
configs.put('conf_UserName', 'user3');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user1Org/user1Org456');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
assertRemoveInvitationRequest(request, 'user1Org/user1Org456', '2');
return httpClient.createHttpResponse(403, 'application/json', '{}');
});
assertError(main, 'Failed to remove the invitation. status: 403');
});
/**
* リクエストのテスト(ユーザーがリポジトリコラボレータであるかどうかを確認する)
* @param {Object} request
* @param request.url
* @param request.method
* @param ownerAndRepo
* @param name
*/
const assertGetCollaborationRequest = ({ url, method }, ownerAndRepo, name) => {
expect(url).toEqual(`https://api.github.com/repos/${ownerAndRepo}/collaborators/${encodeURIComponent(name)}`);
expect(method).toEqual('GET');
};
/**
* ユーザーがリポジトリコラボレータであるかどうかを確認する API リクエストでエラー
*/
test('GETCollaboration Failed', () => {
prepareConfigs("https://github.com/userA/userArepo", 'userA');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'userA/userArepo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
assertGetCollaborationRequest(request, 'userA/userArepo', 'userA');
return httpClient.createHttpResponse(403, 'application/json', '{}');
});
assertError(main, 'Failed to get a userA information. status: 403');
});
/**
* ユーザーがリポジトリコラボレータでないのでエラー
*/
test('user1 is not a collaborator', () => {
prepareConfigs("https://github.com/user1/user1repo", 'user1');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user1/user1repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
assertGetCollaborationRequest(request, 'user1/user1repo', 'user1');
return httpClient.createHttpResponse(404, 'application/json', '{}');
});
assertError(main, 'user1 is not a collaborator. status: 404');
});
/**
* ユーザーがリポジトリコラボレータでないのでエラー
* 招待確認直後に招待削除される
* URL 、ユーザ名をを固定値で指定
*/
test('userB is not a collaborator - fixed value', () => {
prepareConfigs('null', 'null');
configs.put('conf_RepositoryUrl', 'https://github.com/user5/user5repo');
configs.put('conf_UserName', 'userB');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user5/user5repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
if (reqCount === 1) {
assertRemoveInvitationRequest(request, 'user5/user5repo', '1');
reqCount++;
return httpClient.createHttpResponse(404, 'application/json', '{}');
}
assertGetCollaborationRequest(request, 'user5/user5repo', 'userB');
return httpClient.createHttpResponse(404, 'application/json', '{}');
});
assertError(main, 'userB is not a collaborator. status: 404');
});
/**
* リクエストのテスト(リポジトリコラボレータを削除する)
* @param {Object} request
* @param request.url
* @param request.method
* @param ownerAndRepo
* @param name
*/
const assertRemoveCollaborationRequest = ({ url, method,}, ownerAndRepo, name) => {
expect(url).toEqual(`https://api.github.com/repos/${ownerAndRepo}/collaborators/${encodeURIComponent(name)}`);
expect(method).toEqual('DELETE');
};
/**
* リポジトリにコラボレーションを削除する API でエラー
*/
test('DELETECollaboration Failed', () => {
prepareConfigs("https://github.com/user7/user7repo", 'user7');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user7/user7repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
if (reqCount === 1) {
assertGetCollaborationRequest(request, 'user7/user7repo', 'user7');
reqCount++;
return httpClient.createHttpResponse(204, 'application/json', '{}');
}
assertRemoveCollaborationRequest(request, 'user7/user7repo', 'user7');
return httpClient.createHttpResponse(404, 'application/json', '{}');
});
assertError(main, 'Failed to remove a collaborator. status: 404');
});
/**
* コラボレーション削除成功
* URL 、ユーザ名をデータ項目で指定
*/
test('Succeed', () => {
prepareConfigs("https://github.com/user4/user4repo", 'user4');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user4/user4repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
if (reqCount === 1) {
assertGetCollaborationRequest(request, 'user4/user4repo', 'user4');
reqCount++;
return httpClient.createHttpResponse(204, 'application/json', '{}');
}
assertRemoveCollaborationRequest(request, 'user4/user4repo', 'user4');
return httpClient.createHttpResponse(204, 'application/json', '{}');
});
main();
});
/**
* コラボレーション削除成功
* URL 、ユーザ名をを固定値で指定
*/
test('Succeed - fixed value', () => {
prepareConfigs(null, null);
configs.put('conf_RepositoryUrl', 'https://github.com/user5/user5repo');
configs.put('conf_UserName', 'user5');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user5/user5repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
if (reqCount === 1) {
assertGetCollaborationRequest(request, 'user5/user5repo', 'user5');
reqCount++;
return httpClient.createHttpResponse(204, 'application/json', '{}');
}
assertRemoveCollaborationRequest(request, 'user5/user5repo', 'user5');
return httpClient.createHttpResponse(204, 'application/json', '{}');
});
main();
});
/**
* コラボレータ削除成功
* 招待確認直後にコラボレーションされ招待削除失敗 404
* URL 、ユーザ名をを固定値で指定
*/
test('Succeed - invitationFailed - fixed value', () => {
prepareConfigs('null', 'null');
configs.put('conf_RepositoryUrl', 'https://github.com/user5/user5repo');
configs.put('conf_UserName', 'userB');
let reqCount = 0;
httpClient.setRequestHandler((request) => {
if (reqCount === 0) {
assertGetInviteeRequest(request, 'user5/user5repo');
reqCount++;
return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(INVITEE_RESPONSE));
}
if (reqCount === 1) {
assertRemoveInvitationRequest(request, 'user5/user5repo', '1');
reqCount++;
return httpClient.createHttpResponse(404, 'application/json', '{}');
}
if (reqCount === 2) {
assertGetCollaborationRequest(request, 'user5/user5repo', 'userB');
reqCount++;
return httpClient.createHttpResponse(204, 'application/json', '{}');
}
assertRemoveCollaborationRequest(request, 'user5/user5repo', 'userB');
return httpClient.createHttpResponse(204, 'application/json', '{}');
});
main();
});
]]>