Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cla-backend-go/users/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ func Configure(api *operations.ClaAPI, service Service, eventsService events.Ser
}

userModel, err := service.GetUser(params.UserID)
if err != nil {
if err != nil || userModel == nil {
if err == nil {
err = fmt.Errorf("user not found for user_id: %s", params.UserID)
}
log.WithFields(f).Warnf("error retrieving user for user_id: %s, error: %+v", params.UserID, err)
return users.NewGetUserCompatBadRequest().WithPayload(errorResponse(err))
}
Expand Down
182 changes: 182 additions & 0 deletions tests/functional/cypress/e2e/v3/cla-manager.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import {
validate_200_Status,
validate_401_Status,
getTokenKey,
getAPIBaseURL,
getXACLHeaders,
validate_expected_status,
} from '../../support/commands';

describe('To Validate & test CLA Manager APIs via API call (V3)', function () {
const claEndpoint = getAPIBaseURL('v3');
let allowFail: boolean = !(Cypress.env('ALLOW_FAIL') === 1);
const timeout = 180000;
const local = Cypress.env('LOCAL');

// Sample test data - using realistic UUIDs/SFIDs
const testCompanyID = 'd9428888-122b-4b20-8c4a-0c9a1a6f9b8e';
const testProjectID = 'a0960000000CZRmAAO';
const testRequestID = 'd9428888-122b-4b20-8c4a-0c9a1a6f9b8e';
const testUserLFID = 'testuser';

let bearerToken: string = null;
before(() => {
getTokenKey(bearerToken);
cy.window().then((win) => {
bearerToken = win.localStorage.getItem('bearerToken');
});
});

it('Get CLA Manager Requests with authentication - Record should return 200 Response', function () {
cy.request({
method: 'GET',
url: `${claEndpoint}company/${testCompanyID}/project/${testProjectID}/cla-manager/requests`,
timeout: timeout,
failOnStatusCode: allowFail,
headers: getXACLHeaders(),
auth: {
bearer: bearerToken,
},
}).then((response) => {
if (response.status === 200) {
validate_200_Status(response);
expect(response.body).to.be.an('object');
if (response.body.requests) {
expect(response.body.requests).to.be.an('array');
}
} else if (response.status === 404) {
// Company or project not found is acceptable for this test
expect(response.status).to.eq(404);
} else {
// Allow other statuses during development
expect([200, 401, 403, 404]).to.include(response.status);
}
});
});

it('Get CLA Manager Request by ID with authentication', function () {
cy.request({
method: 'GET',
url: `${claEndpoint}company/${testCompanyID}/project/${testProjectID}/cla-manager/requests/${testRequestID}`,
timeout: timeout,
failOnStatusCode: allowFail,
headers: getXACLHeaders(),
auth: {
bearer: bearerToken,
},
}).then((response) => {
if (response.status === 200) {
validate_200_Status(response);
expect(response.body).to.be.an('object');
} else if (response.status === 404) {
// Request not found is acceptable
expect(response.status).to.eq(404);
} else {
// Allow other statuses during development
expect([200, 401, 403, 404]).to.include(response.status);
}
});
});

describe('Authentication Required Tests', () => {
it('Returns 401 for CLA Manager APIs when called without token', () => {
const requests = [
{ method: 'GET', url: `${claEndpoint}company/${testCompanyID}/project/${testProjectID}/cla-manager/requests` },
{
method: 'GET',
url: `${claEndpoint}company/${testCompanyID}/project/${testProjectID}/cla-manager/requests/${testRequestID}`,
},
];

cy.wrap(requests).each((req: any) => {
return cy
.request({
method: req.method,
url: req.url,
failOnStatusCode: false,
timeout,
})
.then((response) => {
cy.task('log', `Testing unauthorized ${req.method} ${req.url}`);
// Expect 401 for missing token
expect(response.status).to.eq(401);
if (response.body && typeof response.body === 'object') {
expect(response.body).to.have.property('message');
}
});
});
});
});

describe('Expected failures', () => {
it('Returns errors due to missing or malformed parameters for CLA Manager APIs', function () {
const defaultHeaders = getXACLHeaders();
const invalidUUID = 'invalid-uuid';
const invalidSFID = 'invalid-sfid';

const cases: Array<{
title: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
url: string;
body?: any;
needsAuth?: boolean;
expectedStatus?: number | number[];
expectedCode?: number;
expectedMessage?: string;
expectedMessageContains?: boolean;
}> = [
{
title: 'GET CLA Manager requests with invalid companyID',
method: 'GET',
url: `${claEndpoint}company/${invalidUUID}/project/${testProjectID}/cla-manager/requests`,
needsAuth: true,
expectedStatus: [200, 400, 404, 422], // Allow 200 if endpoint exists but data is empty
expectedMessageContains: true,
},
{
title: 'GET CLA Manager requests with invalid projectID',
method: 'GET',
url: `${claEndpoint}company/${testCompanyID}/project/${invalidSFID}/cla-manager/requests`,
needsAuth: true,
expectedStatus: [200, 400, 404, 422], // Allow 200 if endpoint exists but data is empty
expectedMessageContains: true,
},
{
title: 'GET CLA Manager request with invalid requestID',
method: 'GET',
url: `${claEndpoint}company/${testCompanyID}/project/${testProjectID}/cla-manager/requests/${invalidUUID}`,
needsAuth: true,
expectedStatus: [200, 400, 404, 422], // Allow 200 if endpoint exists but data is empty
expectedMessageContains: true,
},
];

cy.wrap(cases).each((c: any) => {
const authHeaders = c.needsAuth
? {
...defaultHeaders,
Authorization: `Bearer ${bearerToken}`,
}
: defaultHeaders;

return cy
.request({
method: c.method,
url: c.url,
body: c.body,
headers: authHeaders,
failOnStatusCode: false,
timeout,
})
.then((response) => {
cy.task('log', `Testing: ${c.title} - Got status: ${response.status}`);
if (Array.isArray(c.expectedStatus)) {
expect(c.expectedStatus).to.include(response.status);
} else if (c.expectedStatus) {
expect(response.status).to.eq(c.expectedStatus);
}
});
});
});
});
});
108 changes: 108 additions & 0 deletions tests/functional/cypress/e2e/v3/docs.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import {
validate_200_Status,
getTokenKey,
getAPIBaseURL,
getXACLHeaders,
validate_expected_status,
} from '../../support/commands';

describe('To Validate & test Documentation APIs via API call (V3)', function () {
const claEndpoint = getAPIBaseURL('v3');
let allowFail: boolean = !(Cypress.env('ALLOW_FAIL') === 1);
const timeout = 180000;
const local = Cypress.env('LOCAL');

let bearerToken: string = null;
before(() => {
if (bearerToken == null) {
getTokenKey(bearerToken);
cy.window().then((win) => {
bearerToken = win.localStorage.getItem('bearerToken');
});
}
});

it('Get API Documentation - Record should return 200 Response', function () {
cy.request({
method: 'GET',
url: `${claEndpoint}api-docs`,
timeout: timeout,
failOnStatusCode: allowFail,
}).then((response) => {
validate_200_Status(response);
expect(response.body).to.not.be.null;
});
});

it('Get Swagger JSON - Record should return 200 Response', function () {
cy.request({
method: 'GET',
url: `${claEndpoint}swagger.json`,
timeout: timeout,
failOnStatusCode: allowFail,
}).then((response) => {
validate_200_Status(response);
expect(response.body).to.be.an('object');
expect(response.body).to.have.property('swagger');
expect(response.body).to.have.property('info');
expect(response.body).to.have.property('paths');
});
});

describe('Expected failures', () => {
it('Returns errors due to malformed requests for Documentation APIs', function () {
const cases: Array<{
title: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
url: string;
body?: any;
expectedStatus?: number;
expectedCode?: number;
expectedMessage?: string;
expectedMessageContains?: boolean;
}> = [
{
title: 'POST /api-docs (method not allowed)',
method: 'POST',
url: `${claEndpoint}api-docs`,
body: {},
expectedStatus: 405,
expectedCode: 405,
expectedMessage: 'method POST is not allowed, but [GET] are',
expectedMessageContains: true,
},
{
title: 'POST /swagger.json (method not allowed)',
method: 'POST',
url: `${claEndpoint}swagger.json`,
body: {},
expectedStatus: 405,
expectedCode: 405,
expectedMessage: 'method POST is not allowed, but [GET] are',
expectedMessageContains: true,
},
];

cy.wrap(cases).each((c: any) => {
return cy
.request({
method: c.method,
url: c.url,
body: c.body,
failOnStatusCode: false,
timeout,
})
.then((response) => {
cy.task('log', `Testing: ${c.title}`);
validate_expected_status(
response,
c.expectedStatus,
c.expectedCode,
c.expectedMessage,
c.expectedMessageContains,
);
});
});
});
});
});
85 changes: 85 additions & 0 deletions tests/functional/cypress/e2e/v3/health.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
validate_200_Status,
getTokenKey,
getAPIBaseURL,
getXACLHeaders,
validate_expected_status,
} from '../../support/commands';

describe('To Validate & test Health APIs via API call (V3)', function () {
const claEndpoint = getAPIBaseURL('v3');
let allowFail: boolean = !(Cypress.env('ALLOW_FAIL') === 1);
const timeout = 180000;
const local = Cypress.env('LOCAL');

let bearerToken: string = null;
before(() => {
if (bearerToken == null) {
getTokenKey(bearerToken);
cy.window().then((win) => {
bearerToken = win.localStorage.getItem('bearerToken');
});
}
});

it('Returns the Health of the application - Record should return 200 Response', function () {
cy.request({
method: 'GET',
url: `${claEndpoint}ops/health`,
timeout: timeout,
failOnStatusCode: allowFail,
}).then((response) => {
validate_200_Status(response);
expect(response.body).to.be.an('object');
expect(response.body).to.have.property('Status');
expect(response.body.Status).to.equal('healthy');
});
});

describe('Expected failures', () => {
it('Returns errors due to malformed requests for Health APIs', function () {
const cases: Array<{
title: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
url: string;
body?: any;
expectedStatus?: number;
expectedCode?: number;
expectedMessage?: string;
expectedMessageContains?: boolean;
}> = [
{
title: 'POST /ops/health (method not allowed)',
method: 'POST',
url: `${claEndpoint}ops/health`,
body: {},
expectedStatus: 405,
expectedCode: 405,
expectedMessage: 'method POST is not allowed, but [GET] are',
expectedMessageContains: true,
},
];

cy.wrap(cases).each((c: any) => {
return cy
.request({
method: c.method,
url: c.url,
body: c.body,
failOnStatusCode: false,
timeout,
})
.then((response) => {
cy.task('log', `Testing: ${c.title}`);
validate_expected_status(
response,
c.expectedStatus,
c.expectedCode,
c.expectedMessage,
c.expectedMessageContains,
);
});
});
});
});
});
Loading
Loading