Skip to content

Commit 8101b26

Browse files
Merge pull request #4838 from linuxfoundation/unicron-update-e2e-test-coverage
Unicron update e2e test coverage
2 parents 2d417d6 + 4cc265c commit 8101b26

File tree

10 files changed

+1720
-6
lines changed

10 files changed

+1720
-6
lines changed

tests/functional/cypress/e2e/v4/github-organizations.cy.ts

Lines changed: 172 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
validateApiResponse,
33
validate_200_Status,
4+
validate_401_Status,
5+
validate_expected_status,
46
getTokenKey,
57
getAPIBaseURL,
68
getXACLHeader,
@@ -26,6 +28,8 @@ describe('To Validate github-organizations API call', function () {
2628
const claEndpoint = getAPIBaseURL('v4') + `project/${projectSfidOrg}/github/organizations`;
2729
const claGroupId: string = appConfig.claGroupId;
2830
let allowFail: boolean = !(Cypress.env('ALLOW_FAIL') === 1);
31+
const local = Cypress.env('LOCAL') ? true : false;
32+
const timeout = 180000;
2933

3034
let bearerToken: string = null;
3135
before(() => {
@@ -41,7 +45,7 @@ describe('To Validate github-organizations API call', function () {
4145
cy.request({
4246
method: 'GET',
4347
url: `${claEndpoint}`,
44-
timeout: 180000,
48+
timeout: timeout,
4549
failOnStatusCode: allowFail,
4650
headers: getXACLHeader(),
4751
auth: {
@@ -64,7 +68,7 @@ describe('To Validate github-organizations API call', function () {
6468
cy.request({
6569
method: 'PUT',
6670
url: `${claEndpoint}/${gitHubOrgName}/config`,
67-
timeout: 180000,
71+
timeout: timeout,
6872
failOnStatusCode: allowFail,
6973
headers: getXACLHeader(),
7074
auth: {
@@ -84,7 +88,7 @@ describe('To Validate github-organizations API call', function () {
8488
cy.request({
8589
method: 'POST',
8690
url: `${claEndpoint}`,
87-
timeout: 180000,
91+
timeout: timeout,
8892
failOnStatusCode: allowFail,
8993
headers: getXACLHeader(),
9094
auth: {
@@ -112,7 +116,7 @@ describe('To Validate github-organizations API call', function () {
112116
cy.request({
113117
method: 'DELETE',
114118
url: `${claEndpoint}/${gitHubOrg}`,
115-
timeout: 180000,
119+
timeout: timeout,
116120
failOnStatusCode: allowFail,
117121
headers: getXACLHeader(),
118122
auth: {
@@ -122,4 +126,168 @@ describe('To Validate github-organizations API call', function () {
122126
expect(response.status).to.eq(204);
123127
});
124128
});
129+
130+
// ========================= Expected failures (github-organizations) =========================
131+
describe('Expected failures', () => {
132+
it('Returns 401 for all GitHub Organizations APIs when called without token', () => {
133+
// Use the same base as the rest of this spec:
134+
const claBaseEndpoint = getAPIBaseURL('v4');
135+
136+
// Dummy-but-plausible ids/names so server can fail on auth first
137+
const exampleProjectSFID = '001000000000000AAA'; // plausible SFID shape
138+
const exampleOrgName = 'test-org-123'; // valid org name pattern
139+
140+
// NOTE: Endpoints below are ONLY those that require auth in Swagger.
141+
// Endpoints with security: [] are intentionally excluded.
142+
143+
const requests = [
144+
// GET /project/{projectSFID}/github/organizations
145+
{ method: 'GET', url: `${claBaseEndpoint}project/${exampleProjectSFID}/github/organizations` },
146+
147+
// POST /project/{projectSFID}/github/organizations
148+
{
149+
method: 'POST',
150+
url: `${claBaseEndpoint}project/${exampleProjectSFID}/github/organizations`,
151+
body: {
152+
organizationName: exampleOrgName,
153+
autoEnabled: false,
154+
branchProtectionEnabled: false,
155+
},
156+
},
157+
158+
// PUT /project/{projectSFID}/github/organizations/{orgName}/config
159+
{
160+
method: 'PUT',
161+
url: `${claBaseEndpoint}project/${exampleProjectSFID}/github/organizations/${exampleOrgName}/config`,
162+
body: {
163+
autoEnabled: true,
164+
branchProtectionEnabled: true,
165+
},
166+
},
167+
168+
// DELETE /project/{projectSFID}/github/organizations/{orgName}
169+
{
170+
method: 'DELETE',
171+
url: `${claBaseEndpoint}project/${exampleProjectSFID}/github/organizations/${exampleOrgName}`,
172+
},
173+
];
174+
175+
cy.wrap(requests).each((req: any) => {
176+
return cy
177+
.request({
178+
method: req.method as any,
179+
url: req.url,
180+
body: req.body,
181+
failOnStatusCode: false, // expect 401
182+
timeout,
183+
})
184+
.then((response) => {
185+
return cy.logJson('401 response (github-organizations)', response).then(() => {
186+
validate_401_Status(response, local);
187+
});
188+
});
189+
});
190+
});
191+
192+
it('Returns errors due to missing or malformed parameters for GitHub Organizations APIs', function () {
193+
// Use the same project SFID as the working tests
194+
const projectSfidOrg = appConfig.childProjectSFID;
195+
const exampleOrgName = 'test-org-123';
196+
197+
const defaultHeaders = getXACLHeader();
198+
const defaultAuth = { bearer: bearerToken };
199+
const claBaseEndpoint = getAPIBaseURL('v4');
200+
201+
const cases: Array<{
202+
title: string;
203+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
204+
url: string;
205+
body?: any;
206+
mode?: 'auth' | 'noauth' | 'either';
207+
// when running locally
208+
expectedStatusLocal?: number;
209+
expectedCodeLocal?: number;
210+
expectedMessageLocal?: string;
211+
expectedMessageContainsLocal?: boolean;
212+
// when running against dev via ACS & API-gw
213+
expectedStatusRemote?: number;
214+
expectedCodeRemote?: number;
215+
expectedMessageRemote?: string;
216+
expectedMessageContainsRemote?: boolean;
217+
// if the same
218+
expectedStatus?: number;
219+
expectedCode?: number;
220+
expectedMessage?: string;
221+
expectedMessageContains?: boolean;
222+
}> = [
223+
// --- POST /project/{projectSFID}/github/organizations (missing required fields) ---
224+
{
225+
title: 'POST /project/.../github/organizations with missing organizationName',
226+
method: 'POST',
227+
url: `${claBaseEndpoint}project/${projectSfidOrg}/github/organizations`,
228+
body: {
229+
autoEnabled: false,
230+
branchProtectionEnabled: false,
231+
},
232+
expectedStatus: 422,
233+
expectedCode: 602,
234+
expectedMessage: 'organizationName in body is required',
235+
expectedMessageContains: false,
236+
},
237+
238+
// --- PUT /project/{projectSFID}/github/organizations/{orgName}/config (missing required fields) ---
239+
{
240+
title: 'PUT /project/.../github/organizations/.../config with missing autoEnabled',
241+
method: 'PUT',
242+
url: `${claBaseEndpoint}project/${projectSfidOrg}/github/organizations/${exampleOrgName}/config`,
243+
body: {
244+
branchProtectionEnabled: true,
245+
},
246+
expectedStatus: 422,
247+
expectedCode: 602,
248+
expectedMessage: 'autoEnabled in body is required',
249+
expectedMessageContains: false,
250+
},
251+
252+
// (Sanity) valid-looking parameters should succeed (or at least get past validation)
253+
{
254+
title: 'GET /project/.../github/organizations with valid projectSFID',
255+
method: 'GET',
256+
url: `${claBaseEndpoint}project/${projectSfidOrg}/github/organizations`,
257+
expectedStatus: 200,
258+
},
259+
];
260+
261+
cy.wrap(cases).each((c: any) => {
262+
cy.task('log', `--> ${c.title} | ${c.method} ${c.url}`);
263+
const opts: any = {
264+
method: c.method,
265+
url: c.url,
266+
headers: defaultHeaders,
267+
auth: defaultAuth,
268+
failOnStatusCode: false,
269+
timeout,
270+
};
271+
if (c.body) opts.body = c.body;
272+
273+
cy.request(opts).then((response) => {
274+
return cy.logJson('response', response).then(() => {
275+
const es = local
276+
? (c.expectedStatusLocal ?? c.expectedStatus)
277+
: (c.expectedStatusRemote ?? c.expectedStatus);
278+
const ec = local ? (c.expectedCodeLocal ?? c.expectedCode) : (c.expectedCodeRemote ?? c.expectedCode);
279+
const em = local
280+
? (c.expectedMessageLocal ?? c.expectedMessage)
281+
: (c.expectedMessageRemote ?? c.expectedMessage);
282+
const emc = local
283+
? (c.expectedMessageContainsLocal ?? c.expectedMessageContains)
284+
: (c.expectedMessageContainsRemote ?? c.expectedMessageContains);
285+
286+
cy.task('log', ` --> expected ${es}, ${ec}, '${em}' (contains? ${emc})`);
287+
validate_expected_status(response, es, ec, em, emc);
288+
});
289+
});
290+
});
291+
});
292+
});
125293
});

0 commit comments

Comments
 (0)