refactor: Use internal namespace for the existing API
This commit is contained in:
@@ -1,13 +0,0 @@
|
||||
import User from '../../../../models/user.js';
|
||||
import { renderObject, renderError } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const { email, password } = request.body;
|
||||
const token = await User.authenticate(email, password);
|
||||
|
||||
if (token) {
|
||||
return renderObject(response, { token });
|
||||
}
|
||||
|
||||
renderError(response, [{ general: ['Incorrect email or password.'] }]);
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
|
||||
describe('POST /api/v1/access-tokens', () => {
|
||||
beforeEach(async () => {
|
||||
await createUser({
|
||||
email: 'user@automatisch.io',
|
||||
password: 'password',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the token data with correct credentials', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/access-tokens')
|
||||
.send({
|
||||
email: 'user@automatisch.io',
|
||||
password: 'password',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data.token.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should return error with incorrect credentials', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/access-tokens')
|
||||
.send({
|
||||
email: 'incorrect@email.com',
|
||||
password: 'incorrectpassword',
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.errors.general).toStrictEqual([
|
||||
'Incorrect email or password.',
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
export default async (request, response) => {
|
||||
const token = request.params.token;
|
||||
|
||||
const accessToken = await request.currentUser
|
||||
.$relatedQuery('accessTokens')
|
||||
.findOne({
|
||||
token,
|
||||
revoked_at: null,
|
||||
})
|
||||
.throwIfNotFound();
|
||||
|
||||
await accessToken.revoke();
|
||||
|
||||
response.status(204).end();
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
import { expect, describe, it, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import AccessToken from '../../../../models/access-token.js';
|
||||
|
||||
describe('DELETE /api/v1/access-tokens/:token', () => {
|
||||
let token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const currentUser = await createUser({
|
||||
email: 'user@automatisch.io',
|
||||
password: 'password',
|
||||
});
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should respond with HTTP 204 with correct token', async () => {
|
||||
await request(app)
|
||||
.delete(`/api/v1/access-tokens/${token}`)
|
||||
.set('Authorization', token)
|
||||
.expect(204);
|
||||
|
||||
const revokedToken = await AccessToken.query().findOne({ token });
|
||||
|
||||
expect(revokedToken).toBeDefined();
|
||||
expect(revokedToken.revokedAt).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should respond with HTTP 401 with incorrect credentials', async () => {
|
||||
await request(app)
|
||||
.delete(`/api/v1/access-tokens/${token}`)
|
||||
.set('Authorization', 'wrong-token')
|
||||
.expect(401);
|
||||
|
||||
const unrevokedToken = await AccessToken.query().findOne({ token });
|
||||
|
||||
expect(unrevokedToken).toBeDefined();
|
||||
expect(unrevokedToken.revokedAt).toBeNull();
|
||||
});
|
||||
|
||||
it('should respond with HTTP 404 with correct credentials, but non-valid token', async () => {
|
||||
await request(app)
|
||||
.delete('/api/v1/access-tokens/wrong-token')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
|
||||
const unrevokedToken = await AccessToken.query().findOne({ token });
|
||||
|
||||
expect(unrevokedToken).toBeDefined();
|
||||
expect(unrevokedToken.revokedAt).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import ApiToken from '../../../../../models/api-token.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const apiToken = await ApiToken.query().insertAndFetch({});
|
||||
|
||||
renderObject(response, apiToken, {
|
||||
serializer: 'AdminApiTokenFull',
|
||||
status: 201,
|
||||
});
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import ApiToken from '../../../../../models/api-token.ee.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import createApiTokenMock from '../../../../../../test/mocks/rest/api/v1/admin/api-tokens/create-api-token.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/api-tokens', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the created api token', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/api-tokens')
|
||||
.set('Authorization', token)
|
||||
.expect(201);
|
||||
|
||||
const refetchedToken = await ApiToken.query().findById(
|
||||
response.body.data.id
|
||||
);
|
||||
|
||||
const expectedPayload = await createApiTokenMock(refetchedToken);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import ApiToken from '../../../../../models/api-token.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const apiToken = await ApiToken.query()
|
||||
.findById(request.params.id)
|
||||
.throwIfNotFound();
|
||||
|
||||
await apiToken.$query().delete();
|
||||
|
||||
response.status(204).end();
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import Crypto from 'node:crypto';
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createApiToken } from '../../../../../../test/factories/api-token.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('DELETE /api/v1/admin/api-tokens/:id', () => {
|
||||
let adminRole, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should delete the api token and return HTTP 204', async () => {
|
||||
const apiToken = await createApiToken();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/api-tokens/${apiToken.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(204);
|
||||
|
||||
const refetchedApiToken = await apiToken.$query();
|
||||
|
||||
expect(refetchedApiToken).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return HTTP 404 for not existing api token id', async () => {
|
||||
const notExistingApiTokenId = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/api-tokens/${notExistingApiTokenId}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import ApiToken from '../../../../../models/api-token.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const apiTokens = await ApiToken.query().orderBy('created_at', 'desc');
|
||||
|
||||
renderObject(response, apiTokens, { serializer: 'AdminApiToken' });
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import getAdminApiTokensMock from '../../../../../../test/mocks/rest/api/v1/admin/api-tokens/get-api-tokens.js';
|
||||
import { createApiToken } from '../../../../../../test/factories/api-token.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/api-tokens', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return all api tokens', async () => {
|
||||
const apiTokenOne = await createApiToken();
|
||||
const apiTokenTwo = await createApiToken();
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/api-tokens')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getAdminApiTokensMock([
|
||||
apiTokenTwo,
|
||||
apiTokenOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import AppConfig from '../../../../../models/app-config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const createdAppConfig = await AppConfig.query().insertAndFetch(
|
||||
appConfigParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, createdAppConfig, { status: 201 });
|
||||
};
|
||||
|
||||
const appConfigParams = (request) => {
|
||||
const { useOnlyPredefinedAuthClients, disabled } = request.body;
|
||||
|
||||
return {
|
||||
key: request.params.appKey,
|
||||
useOnlyPredefinedAuthClients,
|
||||
disabled,
|
||||
};
|
||||
};
|
||||
@@ -1,66 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import createAppConfigMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-config.js';
|
||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/apps/:appKey/config', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return created app config', async () => {
|
||||
const appConfig = {
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/apps/gitlab/config')
|
||||
.set('Authorization', token)
|
||||
.send(appConfig)
|
||||
.expect(201);
|
||||
|
||||
const expectedPayload = createAppConfigMock({
|
||||
...appConfig,
|
||||
key: 'gitlab',
|
||||
});
|
||||
|
||||
expect(response.body).toMatchObject(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return HTTP 422 for already existing app config', async () => {
|
||||
const appConfig = {
|
||||
key: 'gitlab',
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
await createAppConfig(appConfig);
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/apps/gitlab/config')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
disabled: false,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toStrictEqual('UniqueViolationError');
|
||||
expect(response.body.errors).toMatchObject({
|
||||
key: ["'key' must be unique."],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import AppConfig from '../../../../../models/app-config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const appConfig = await AppConfig.query()
|
||||
.findOne({ key: request.params.appKey })
|
||||
.throwIfNotFound();
|
||||
|
||||
const oauthClient = await appConfig.createOAuthClient(
|
||||
oauthClientParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, oauthClient, { status: 201 });
|
||||
};
|
||||
|
||||
const oauthClientParams = (request) => {
|
||||
const { active, appKey, name, formattedAuthDefaults } = request.body;
|
||||
|
||||
return {
|
||||
active,
|
||||
appKey,
|
||||
name,
|
||||
formattedAuthDefaults,
|
||||
};
|
||||
};
|
||||
@@ -1,122 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import createOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-oauth-client.js';
|
||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return created response for valid app config', async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
});
|
||||
|
||||
const oauthClient = {
|
||||
active: true,
|
||||
appKey: 'gitlab',
|
||||
name: 'First auth client',
|
||||
formattedAuthDefaults: {
|
||||
clientid: 'sample client ID',
|
||||
clientSecret: 'sample client secret',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(201);
|
||||
|
||||
const expectedPayload = createOAuthClientMock(oauthClient);
|
||||
expect(response.body).toMatchObject(expectedPayload);
|
||||
});
|
||||
|
||||
it('should throw validation error for app that does not support oauth connections', async () => {
|
||||
await createAppConfig({
|
||||
key: 'deepl',
|
||||
});
|
||||
|
||||
const oauthClient = {
|
||||
active: true,
|
||||
appKey: 'deepl',
|
||||
name: 'First auth client',
|
||||
formattedAuthDefaults: {
|
||||
clientid: 'sample client ID',
|
||||
clientSecret: 'sample client secret',
|
||||
instanceUrl: 'https://deepl.com',
|
||||
oAuthRedirectUrl: 'http://localhost:3001/app/deepl/connection/add',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/apps/deepl/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.errors).toMatchObject({
|
||||
app: ['This app does not support OAuth clients!'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not found response for not existing app config', async () => {
|
||||
const oauthClient = {
|
||||
active: true,
|
||||
appKey: 'gitlab',
|
||||
name: 'First auth client',
|
||||
formattedAuthDefaults: {
|
||||
clientid: 'sample client ID',
|
||||
clientSecret: 'sample client secret',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
|
||||
},
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for missing required fields', async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
});
|
||||
|
||||
const oauthClient = {
|
||||
appKey: 'gitlab',
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/apps/gitlab/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
||||
expect(response.body.errors).toMatchObject({
|
||||
name: ["must have required property 'name'"],
|
||||
formattedAuthDefaults: [
|
||||
"must have required property 'formattedAuthDefaults'",
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const oauthClient = await OAuthClient.query()
|
||||
.findById(request.params.oauthClientId)
|
||||
.where({ app_key: request.params.appKey })
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, oauthClient);
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import getOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-oauth-client.js';
|
||||
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/apps/:appKey/oauth-clients/:oauthClientId', () => {
|
||||
let currentUser, adminRole, currentOAuthClient, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
currentOAuthClient = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified oauth client', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/apps/deepl/oauth-clients/${currentOAuthClient.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getOAuthClientMock(currentOAuthClient);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing oauth client ID', async () => {
|
||||
const notExistingOAuthClientUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(
|
||||
`/api/v1/admin/apps/deepl/oauth-clients/${notExistingOAuthClientUUID}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/admin/apps/deepl/oauth-clients/invalidOAuthClientUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const oauthClients = await OAuthClient.query()
|
||||
.where({ app_key: request.params.appKey })
|
||||
.orderBy('created_at', 'desc');
|
||||
|
||||
renderObject(response, oauthClients);
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import getAdminOAuthClientsMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/get-oauth-clients.js';
|
||||
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified oauth client info', async () => {
|
||||
const oauthClientOne = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
const oauthClientTwo = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/apps/deepl/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAdminOAuthClientsMock([
|
||||
oauthClientTwo,
|
||||
oauthClientOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import AppConfig from '../../../../../models/app-config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const appConfig = await AppConfig.query()
|
||||
.findOne({
|
||||
key: request.params.appKey,
|
||||
})
|
||||
.throwIfNotFound();
|
||||
|
||||
await appConfig.$query().patchAndFetch({
|
||||
...appConfigParams(request),
|
||||
key: request.params.appKey,
|
||||
});
|
||||
|
||||
renderObject(response, appConfig);
|
||||
};
|
||||
|
||||
const appConfigParams = (request) => {
|
||||
const { useOnlyPredefinedAuthClients, disabled } = request.body;
|
||||
|
||||
return {
|
||||
useOnlyPredefinedAuthClients,
|
||||
disabled,
|
||||
};
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import createAppConfigMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/create-config.js';
|
||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/apps/:appKey/config', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return updated app config', async () => {
|
||||
const appConfig = {
|
||||
key: 'gitlab',
|
||||
useOnlyPredefinedAuthClients: true,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
await createAppConfig(appConfig);
|
||||
|
||||
const newAppConfigValues = {
|
||||
disabled: true,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch('/api/v1/admin/apps/gitlab/config')
|
||||
.set('Authorization', token)
|
||||
.send(newAppConfigValues)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = createAppConfigMock({
|
||||
...newAppConfigValues,
|
||||
key: 'gitlab',
|
||||
});
|
||||
|
||||
expect(response.body).toMatchObject(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for unexisting app config', async () => {
|
||||
const appConfig = {
|
||||
disabled: true,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.patch('/api/v1/admin/apps/gitlab/config')
|
||||
.set('Authorization', token)
|
||||
.send(appConfig)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return HTTP 422 for invalid app config data', async () => {
|
||||
const appConfig = {
|
||||
key: 'gitlab',
|
||||
useOnlyPredefinedAuthClients: true,
|
||||
disabled: false,
|
||||
};
|
||||
|
||||
await createAppConfig(appConfig);
|
||||
|
||||
const response = await request(app)
|
||||
.patch('/api/v1/admin/apps/gitlab/config')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
disabled: 'invalid value type',
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
||||
expect(response.body.errors).toMatchObject({
|
||||
disabled: ['must be boolean'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import OAuthClient from '../../../../../models/oauth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const oauthClient = await OAuthClient.query()
|
||||
.findById(request.params.oauthClientId)
|
||||
.throwIfNotFound();
|
||||
|
||||
await oauthClient.$query().patchAndFetch(oauthClientParams(request));
|
||||
|
||||
renderObject(response, oauthClient);
|
||||
};
|
||||
|
||||
const oauthClientParams = (request) => {
|
||||
const { active, name, formattedAuthDefaults } = request.body;
|
||||
|
||||
return {
|
||||
active,
|
||||
name,
|
||||
formattedAuthDefaults,
|
||||
};
|
||||
};
|
||||
@@ -1,104 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import updateOAuthClientMock from '../../../../../../test/mocks/rest/api/v1/admin/apps/update-oauth-client.js';
|
||||
import { createAppConfig } from '../../../../../../test/factories/app-config.js';
|
||||
import { createOAuthClient } from '../../../../../../test/factories/oauth-client.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/apps/:appKey/oauth-clients', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return updated entity for valid oauth client', async () => {
|
||||
const oauthClient = {
|
||||
active: true,
|
||||
appKey: 'gitlab',
|
||||
formattedAuthDefaults: {
|
||||
clientid: 'sample client ID',
|
||||
clientSecret: 'sample client secret',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
oAuthRedirectUrl: 'http://localhost:3001/app/gitlab/connection/add',
|
||||
},
|
||||
};
|
||||
|
||||
const existingOAuthClient = await createOAuthClient({
|
||||
appKey: 'gitlab',
|
||||
name: 'First auth client',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/apps/gitlab/oauth-clients/${existingOAuthClient.id}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = updateOAuthClientMock({
|
||||
...existingOAuthClient,
|
||||
...oauthClient,
|
||||
});
|
||||
|
||||
expect(response.body).toMatchObject(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing oauth client', async () => {
|
||||
const notExistingOAuthClientId = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/apps/gitlab/oauth-clients/${notExistingOAuthClientId}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.patch('/api/v1/admin/apps/gitlab/oauth-clients/invalidAuthClientUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
|
||||
it('should return HTTP 422 for invalid payload', async () => {
|
||||
const oauthClient = {
|
||||
formattedAuthDefaults: 'invalid input',
|
||||
};
|
||||
|
||||
const existingOAuthClient = await createOAuthClient({
|
||||
appKey: 'gitlab',
|
||||
name: 'First auth client',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/apps/gitlab/oauth-clients/${existingOAuthClient.id}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(oauthClient)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toBe('ModelValidation');
|
||||
expect(response.body.errors).toMatchObject({
|
||||
formattedAuthDefaults: ['must be object'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,48 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Config from '../../../../../models/config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const config = await Config.query().updateFirstOrInsert(
|
||||
configParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, config);
|
||||
};
|
||||
|
||||
const configParams = (request) => {
|
||||
const {
|
||||
enableTemplates,
|
||||
enableFooter,
|
||||
footerBackgroundColor,
|
||||
footerCopyrightText,
|
||||
footerDocsUrl,
|
||||
footerImprintUrl,
|
||||
footerLogoSvgData,
|
||||
footerPrivacyPolicyUrl,
|
||||
footerTextColor,
|
||||
footerTosUrl,
|
||||
logoSvgData,
|
||||
palettePrimaryDark,
|
||||
palettePrimaryLight,
|
||||
palettePrimaryMain,
|
||||
title,
|
||||
} = request.body;
|
||||
|
||||
return {
|
||||
enableTemplates,
|
||||
enableFooter,
|
||||
footerBackgroundColor,
|
||||
footerCopyrightText,
|
||||
footerDocsUrl,
|
||||
footerImprintUrl,
|
||||
footerLogoSvgData,
|
||||
footerPrivacyPolicyUrl,
|
||||
footerTextColor,
|
||||
footerTosUrl,
|
||||
logoSvgData,
|
||||
palettePrimaryDark,
|
||||
palettePrimaryLight,
|
||||
palettePrimaryMain,
|
||||
title,
|
||||
};
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { updateConfig } from '../../../../../../test/factories/config.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/config', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return updated config', async () => {
|
||||
const title = 'Test environment - Automatisch';
|
||||
const palettePrimaryMain = '#00adef';
|
||||
const palettePrimaryDark = '#222222';
|
||||
const palettePrimaryLight = '#f90707';
|
||||
const enableFooter = true;
|
||||
const footerCopyrightText = '© AB Software GmbH';
|
||||
const footerBackgroundColor = '#FFFFFF';
|
||||
const footerTextColor = '#000000';
|
||||
const footerDocsUrl = 'https://automatisch.io/docs';
|
||||
const footerTosUrl = 'https://automatisch.io/terms';
|
||||
const footerPrivacyPolicyUrl = 'https://automatisch.io/privacy';
|
||||
const footerImprintUrl = 'https://automatisch.io/imprint';
|
||||
|
||||
const footerLogoSvgData =
|
||||
'<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100"><rect width="100%" height="100%" fill="white" /><text x="10" y="40" font-family="Arial" font-size="40" fill="black">Sample Footer Logo</text></svg>';
|
||||
|
||||
const logoSvgData =
|
||||
'<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100"><rect width="100%" height="100%" fill="white" /><text x="10" y="40" font-family="Arial" font-size="40" fill="black">A</text></svg>';
|
||||
|
||||
const appConfig = {
|
||||
title,
|
||||
palettePrimaryMain: palettePrimaryMain,
|
||||
palettePrimaryDark: palettePrimaryDark,
|
||||
palettePrimaryLight: palettePrimaryLight,
|
||||
logoSvgData: logoSvgData,
|
||||
enableFooter,
|
||||
footerCopyrightText,
|
||||
footerBackgroundColor,
|
||||
footerTextColor,
|
||||
footerDocsUrl,
|
||||
footerTosUrl,
|
||||
footerPrivacyPolicyUrl,
|
||||
footerImprintUrl,
|
||||
footerLogoSvgData,
|
||||
};
|
||||
|
||||
await updateConfig(appConfig);
|
||||
|
||||
const newTitle = 'Updated title';
|
||||
|
||||
const newConfigValues = {
|
||||
title: newTitle,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch('/api/v1/admin/config')
|
||||
.set('Authorization', token)
|
||||
.send(newConfigValues)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data.title).toStrictEqual(newTitle);
|
||||
expect(response.body.meta.type).toStrictEqual('Config');
|
||||
});
|
||||
|
||||
it('should return created config for unexisting config', async () => {
|
||||
const newTitle = 'Updated title';
|
||||
|
||||
const newConfigValues = {
|
||||
title: newTitle,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch('/api/v1/admin/config')
|
||||
.set('Authorization', token)
|
||||
.send(newConfigValues)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data.title).toStrictEqual(newTitle);
|
||||
expect(response.body.meta.type).toStrictEqual('Config');
|
||||
});
|
||||
|
||||
it('should return null for deleted config entry', async () => {
|
||||
const newConfigValues = {
|
||||
title: null,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch('/api/v1/admin/config')
|
||||
.set('Authorization', token)
|
||||
.send(newConfigValues)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data.title).toBeNull();
|
||||
expect(response.body.meta.type).toStrictEqual('Config');
|
||||
});
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import permissionCatalog from '../../../../../helpers/permission-catalog.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
renderObject(response, permissionCatalog);
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import getPermissionsCatalogMock from '../../../../../../test/mocks/rest/api/v1/admin/permissions/get-permissions-catalog.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/permissions/catalog', () => {
|
||||
let role, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return roles', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/permissions/catalog')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getPermissionsCatalogMock();
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const roleData = roleParams(request);
|
||||
|
||||
const roleWithPermissions = await Role.query().insertGraphAndFetch(roleData, {
|
||||
relate: ['permissions'],
|
||||
});
|
||||
|
||||
renderObject(response, roleWithPermissions, { status: 201 });
|
||||
};
|
||||
|
||||
const roleParams = (request) => {
|
||||
const { name, description, permissions } = request.body;
|
||||
|
||||
return {
|
||||
name,
|
||||
description,
|
||||
permissions,
|
||||
};
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import createRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/create-role.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/roles', () => {
|
||||
let role, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the created role along with permissions', async () => {
|
||||
const roleData = {
|
||||
name: 'Viewer',
|
||||
description: '',
|
||||
permissions: [
|
||||
{
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
conditions: ['isCreator'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/roles')
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(201);
|
||||
|
||||
const createdRole = await Role.query()
|
||||
.withGraphFetched({ permissions: true })
|
||||
.findOne({ name: 'Viewer' })
|
||||
.throwIfNotFound();
|
||||
|
||||
const expectedPayload = await createRoleMock(
|
||||
{
|
||||
...createdRole,
|
||||
...roleData,
|
||||
isAdmin: createdRole.isAdmin,
|
||||
},
|
||||
[
|
||||
{
|
||||
...createdRole.permissions[0],
|
||||
...roleData.permissions[0],
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid role data', async () => {
|
||||
const roleData = {
|
||||
description: '',
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/roles')
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ["must have required property 'name'"],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for duplicate role', async () => {
|
||||
await createRole({ name: 'Viewer' });
|
||||
|
||||
const roleData = {
|
||||
name: 'Viewer',
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/roles')
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ["'name' must be unique."],
|
||||
},
|
||||
meta: {
|
||||
type: 'UniqueViolationError',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const role = await Role.query()
|
||||
.findById(request.params.roleId)
|
||||
.throwIfNotFound();
|
||||
|
||||
await role.deleteWithPermissions();
|
||||
|
||||
response.status(204).end();
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
import Crypto from 'node:crypto';
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createPermission } from '../../../../../../test/factories/permission.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('DELETE /api/v1/admin/roles/:roleId', () => {
|
||||
let adminRole, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return HTTP 204 for unused role', async () => {
|
||||
const role = await createRole();
|
||||
const permission = await createPermission({ roleId: role.id });
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/roles/${role.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(204);
|
||||
|
||||
const refetchedRole = await role.$query();
|
||||
const refetchedPermission = await permission.$query();
|
||||
|
||||
expect(refetchedRole).toBeUndefined();
|
||||
expect(refetchedPermission).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return HTTP 404 for not existing role UUID', async () => {
|
||||
const notExistingRoleUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/roles/${notExistingRoleUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return not authorized response for deleting admin role', async () => {
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/roles/${adminRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for role used by users', async () => {
|
||||
const role = await createRole();
|
||||
await createUser({ roleId: role.id });
|
||||
|
||||
const response = await request(app)
|
||||
.delete(`/api/v1/admin/roles/${role.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
role: [`All users must be migrated away from the "${role.name}" role.`],
|
||||
},
|
||||
meta: {
|
||||
type: 'ValidationError',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for role used by saml auth providers', async () => {
|
||||
const samlAuthProvider = await createSamlAuthProvider();
|
||||
|
||||
const response = await request(app)
|
||||
.delete(`/api/v1/admin/roles/${samlAuthProvider.defaultRoleId}`)
|
||||
.set('Authorization', token)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
samlAuthProvider: [
|
||||
'You need to change the default role in the SAML configuration before deleting this role.',
|
||||
],
|
||||
},
|
||||
meta: {
|
||||
type: 'ValidationError',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const role = await Role.query()
|
||||
.leftJoinRelated({
|
||||
permissions: true,
|
||||
})
|
||||
.withGraphFetched({
|
||||
permissions: true,
|
||||
})
|
||||
.findById(request.params.roleId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, role);
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createPermission } from '../../../../../../test/factories/permission.js';
|
||||
import getRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/get-role.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/roles/:roleId', () => {
|
||||
let role, currentUser, token, permissionOne, permissionTwo;
|
||||
|
||||
beforeEach(async () => {
|
||||
role = await createRole({ name: 'Admin' });
|
||||
permissionOne = await createPermission({ roleId: role.id });
|
||||
permissionTwo = await createPermission({ roleId: role.id });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return role', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/roles/${role.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getRoleMock(role, [
|
||||
permissionOne,
|
||||
permissionTwo,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing role UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingRoleUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/admin/roles/${notExistingRoleUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/roles/invalidRoleUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const roles = await Role.query().orderBy('name');
|
||||
|
||||
renderObject(response, roles);
|
||||
};
|
||||
@@ -1,33 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import getRolesMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/get-roles.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/roles', () => {
|
||||
let roleOne, roleTwo, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
roleOne = await createRole({ name: 'Admin' });
|
||||
roleTwo = await createRole({ name: 'User' });
|
||||
currentUser = await createUser({ roleId: roleOne.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return roles', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/roles')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getRolesMock([roleOne, roleTwo]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const role = await Role.query()
|
||||
.findById(request.params.roleId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const updatedRoleWithPermissions = await role.updateWithPermissions(
|
||||
roleParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, updatedRoleWithPermissions);
|
||||
};
|
||||
|
||||
const roleParams = (request) => {
|
||||
const { name, description, permissions } = request.body;
|
||||
|
||||
return {
|
||||
name,
|
||||
description,
|
||||
permissions,
|
||||
};
|
||||
};
|
||||
@@ -1,177 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createPermission } from '../../../../../../test/factories/permission.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import updateRoleMock from '../../../../../../test/mocks/rest/api/v1/admin/roles/update-role.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/roles/:roleId', () => {
|
||||
let adminRole, viewerRole, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
viewerRole = await createRole({ name: 'Viewer' });
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Connection',
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
});
|
||||
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the updated role along with permissions', async () => {
|
||||
const roleData = {
|
||||
name: 'Updated role name',
|
||||
description: 'A new description',
|
||||
permissions: [
|
||||
{
|
||||
action: 'read',
|
||||
subject: 'Execution',
|
||||
conditions: ['isCreator'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(200);
|
||||
|
||||
const refetchedViewerRole = await viewerRole
|
||||
.$query()
|
||||
.withGraphFetched({ permissions: true });
|
||||
|
||||
const expectedPayload = await updateRoleMock(
|
||||
{
|
||||
...refetchedViewerRole,
|
||||
...roleData,
|
||||
isAdmin: false,
|
||||
},
|
||||
[
|
||||
{
|
||||
...refetchedViewerRole.permissions[0],
|
||||
...roleData.permissions[0],
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return the updated role with sanitized permissions', async () => {
|
||||
const validPermission = {
|
||||
action: 'manage',
|
||||
subject: 'Connection',
|
||||
conditions: ['isCreator'],
|
||||
};
|
||||
|
||||
const invalidPermission = {
|
||||
action: 'publish',
|
||||
subject: 'Connection',
|
||||
conditions: ['isCreator'],
|
||||
};
|
||||
|
||||
const roleData = {
|
||||
permissions: [validPermission, invalidPermission],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(200);
|
||||
|
||||
const refetchedViewerRole = await viewerRole.$query().withGraphFetched({
|
||||
permissions: true,
|
||||
});
|
||||
|
||||
const expectedPayload = updateRoleMock(refetchedViewerRole, [
|
||||
{
|
||||
...refetchedViewerRole.permissions[0],
|
||||
...validPermission,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not authorized response for updating admin role', async () => {
|
||||
const roleData = {
|
||||
name: 'Updated role name',
|
||||
description: 'A new description',
|
||||
permissions: [
|
||||
{
|
||||
action: 'read',
|
||||
subject: 'Execution',
|
||||
conditions: ['isCreator'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.patch(`/api/v1/admin/roles/${adminRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid role data', async () => {
|
||||
const roleData = {
|
||||
description: 123,
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
description: ['must be string,null'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return unique violation response for duplicate role data', async () => {
|
||||
await createRole({ name: 'Editor' });
|
||||
|
||||
const roleData = {
|
||||
name: 'Editor',
|
||||
permissions: [],
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/roles/${viewerRole.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(roleData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ["'name' must be unique."],
|
||||
},
|
||||
meta: {
|
||||
type: 'UniqueViolationError',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,43 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProvider = await SamlAuthProvider.query().insert(
|
||||
samlAuthProviderParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, samlAuthProvider, {
|
||||
serializer: 'AdminSamlAuthProvider',
|
||||
status: 201,
|
||||
});
|
||||
};
|
||||
|
||||
const samlAuthProviderParams = (request) => {
|
||||
const {
|
||||
name,
|
||||
certificate,
|
||||
signatureAlgorithm,
|
||||
issuer,
|
||||
entryPoint,
|
||||
firstnameAttributeName,
|
||||
surnameAttributeName,
|
||||
emailAttributeName,
|
||||
roleAttributeName,
|
||||
defaultRoleId,
|
||||
active,
|
||||
} = request.body;
|
||||
|
||||
return {
|
||||
name,
|
||||
certificate,
|
||||
signatureAlgorithm,
|
||||
issuer,
|
||||
entryPoint,
|
||||
firstnameAttributeName,
|
||||
surnameAttributeName,
|
||||
emailAttributeName,
|
||||
roleAttributeName,
|
||||
defaultRoleId,
|
||||
active,
|
||||
};
|
||||
};
|
||||
@@ -1,78 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import createSamlAuthProviderMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/create-saml-auth-provider.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/saml-auth-provider', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the created saml auth provider', async () => {
|
||||
const samlAuthProviderPayload = {
|
||||
active: true,
|
||||
name: 'Name',
|
||||
issuer: 'theclientid',
|
||||
certificate: 'dummycert',
|
||||
entryPoint: 'http://localhost:8080/realms/automatisch/protocol/saml',
|
||||
signatureAlgorithm: 'sha256',
|
||||
defaultRoleId: role.id,
|
||||
firstnameAttributeName: 'urn:oid:2.5.4.42',
|
||||
surnameAttributeName: 'urn:oid:2.5.4.4',
|
||||
emailAttributeName: 'urn:oid:1.2.840.113549.1.9.1',
|
||||
roleAttributeName: 'Role',
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/saml-auth-providers')
|
||||
.set('Authorization', token)
|
||||
.send(samlAuthProviderPayload)
|
||||
.expect(201);
|
||||
|
||||
const expectedPayload = await createSamlAuthProviderMock({
|
||||
id: response.body.data.id,
|
||||
...samlAuthProviderPayload,
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/saml-auth-providers')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
active: true,
|
||||
name: 'Name',
|
||||
issuer: 'theclientid',
|
||||
signatureAlgorithm: 'invalid',
|
||||
firstnameAttributeName: 'urn:oid:2.5.4.42',
|
||||
surnameAttributeName: 'urn:oid:2.5.4.4',
|
||||
emailAttributeName: 'urn:oid:1.2.840.113549.1.9.1',
|
||||
roleAttributeName: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
certificate: ["must have required property 'certificate'"],
|
||||
entryPoint: ["must have required property 'entryPoint'"],
|
||||
defaultRoleId: ["must have required property 'defaultRoleId'"],
|
||||
signatureAlgorithm: ['must be equal to one of the allowed values'],
|
||||
roleAttributeName: ['must be string'],
|
||||
},
|
||||
meta: { type: 'ModelValidation' },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,14 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProvider = await SamlAuthProvider.query()
|
||||
.findById(request.params.samlAuthProviderId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const roleMappings = await samlAuthProvider
|
||||
.$relatedQuery('roleMappings')
|
||||
.orderBy('remote_role_name', 'asc');
|
||||
|
||||
renderObject(response, roleMappings);
|
||||
};
|
||||
@@ -1,51 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import { createRoleMapping } from '../../../../../../test/factories/role-mapping.js';
|
||||
import getRoleMappingsMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/get-role-mappings.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/saml-auth-providers/:samlAuthProviderId/role-mappings', () => {
|
||||
let roleMappingOne, roleMappingTwo, samlAuthProvider, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
samlAuthProvider = await createSamlAuthProvider();
|
||||
|
||||
roleMappingOne = await createRoleMapping({
|
||||
samlAuthProviderId: samlAuthProvider.id,
|
||||
remoteRoleName: 'Admin',
|
||||
});
|
||||
|
||||
roleMappingTwo = await createRoleMapping({
|
||||
samlAuthProviderId: samlAuthProvider.id,
|
||||
remoteRoleName: 'User',
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return role mappings', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(
|
||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getRoleMappingsMock([
|
||||
roleMappingOne,
|
||||
roleMappingTwo,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,12 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProvider = await SamlAuthProvider.query()
|
||||
.findById(request.params.samlAuthProviderId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, samlAuthProvider, {
|
||||
serializer: 'AdminSamlAuthProvider',
|
||||
});
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import getSamlAuthProviderMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/get-saml-auth-provider.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/saml-auth-provider/:samlAuthProviderId', () => {
|
||||
let samlAuthProvider, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
samlAuthProvider = await createSamlAuthProvider();
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return saml auth provider with specified id', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getSamlAuthProviderMock(samlAuthProvider);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing saml auth provider UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingSamlAuthProviderUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(
|
||||
`/api/v1/admin/saml-auth-providers/${notExistingSamlAuthProviderUUID}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/saml-auth-providers/invalidSamlAuthProviderUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProviders = await SamlAuthProvider.query().orderBy(
|
||||
'created_at',
|
||||
'desc'
|
||||
);
|
||||
|
||||
renderObject(response, samlAuthProviders, {
|
||||
serializer: 'AdminSamlAuthProvider',
|
||||
});
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import getSamlAuthProvidersMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/get-saml-auth-providers.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/saml-auth-providers', () => {
|
||||
let samlAuthProviderOne, samlAuthProviderTwo, currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
samlAuthProviderOne = await createSamlAuthProvider();
|
||||
samlAuthProviderTwo = await createSamlAuthProvider();
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return saml auth providers', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/saml-auth-providers')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getSamlAuthProvidersMock([
|
||||
samlAuthProviderTwo,
|
||||
samlAuthProviderOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,25 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProviderId = request.params.samlAuthProviderId;
|
||||
|
||||
const samlAuthProvider = await SamlAuthProvider.query()
|
||||
.findById(samlAuthProviderId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const roleMappings = await samlAuthProvider.updateRoleMappings(
|
||||
roleMappingsParams(request)
|
||||
);
|
||||
|
||||
renderObject(response, roleMappings);
|
||||
};
|
||||
|
||||
const roleMappingsParams = (request) => {
|
||||
const roleMappings = request.body;
|
||||
|
||||
return roleMappings.map(({ roleId, remoteRoleName }) => ({
|
||||
roleId,
|
||||
remoteRoleName,
|
||||
}));
|
||||
};
|
||||
@@ -1,152 +0,0 @@
|
||||
import Crypto from 'node:crypto';
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import { createRoleMapping } from '../../../../../../test/factories/role-mapping.js';
|
||||
import createRoleMappingsMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/update-role-mappings.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/saml-auth-providers/:samlAuthProviderId/role-mappings', () => {
|
||||
let samlAuthProvider, currentUser, userRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
userRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: userRole.id });
|
||||
|
||||
samlAuthProvider = await createSamlAuthProvider();
|
||||
|
||||
await createRoleMapping({
|
||||
samlAuthProviderId: samlAuthProvider.id,
|
||||
remoteRoleName: 'Viewer',
|
||||
});
|
||||
|
||||
await createRoleMapping({
|
||||
samlAuthProviderId: samlAuthProvider.id,
|
||||
remoteRoleName: 'Editor',
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should update role mappings', async () => {
|
||||
const roleMappings = [
|
||||
{
|
||||
roleId: userRole.id,
|
||||
remoteRoleName: 'Admin',
|
||||
},
|
||||
];
|
||||
|
||||
const response = await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(roleMappings)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await createRoleMappingsMock([
|
||||
{
|
||||
roleId: userRole.id,
|
||||
remoteRoleName: 'Admin',
|
||||
id: response.body.data[0].id,
|
||||
samlAuthProviderId: samlAuthProvider.id,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should delete role mappings when given empty role mappings', async () => {
|
||||
const existingRoleMappings = await samlAuthProvider.$relatedQuery(
|
||||
'roleMappings'
|
||||
);
|
||||
|
||||
expect(existingRoleMappings.length).toBe(2);
|
||||
|
||||
const response = await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send([])
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await createRoleMappingsMock([]);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
...expectedPayload,
|
||||
meta: {
|
||||
...expectedPayload.meta,
|
||||
type: 'Object',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return internal server error response for not existing role UUID', async () => {
|
||||
const notExistingRoleUUID = Crypto.randomUUID();
|
||||
const roleMappings = [
|
||||
{
|
||||
roleId: notExistingRoleUUID,
|
||||
remoteRoleName: 'Admin',
|
||||
},
|
||||
];
|
||||
|
||||
await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(roleMappings)
|
||||
.expect(500);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid data', async () => {
|
||||
const roleMappings = [
|
||||
{
|
||||
roleId: userRole.id,
|
||||
remoteRoleName: {},
|
||||
},
|
||||
];
|
||||
|
||||
const response = await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(roleMappings)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
remoteRoleName: ['must be string'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not found response for not existing SAML auth provider UUID', async () => {
|
||||
const notExistingSamlAuthProviderUUID = Crypto.randomUUID();
|
||||
const roleMappings = [
|
||||
{
|
||||
roleId: userRole.id,
|
||||
remoteRoleName: 'Admin',
|
||||
},
|
||||
];
|
||||
|
||||
await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${notExistingSamlAuthProviderUUID}/role-mappings`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.send(roleMappings)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import SamlAuthProvider from '../../../../../models/saml-auth-provider.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const samlAuthProvider = await SamlAuthProvider.query()
|
||||
.patchAndFetchById(
|
||||
request.params.samlAuthProviderId,
|
||||
samlAuthProviderParams(request)
|
||||
)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, samlAuthProvider, {
|
||||
serializer: 'AdminSamlAuthProvider',
|
||||
});
|
||||
};
|
||||
|
||||
const samlAuthProviderParams = (request) => {
|
||||
const {
|
||||
name,
|
||||
certificate,
|
||||
signatureAlgorithm,
|
||||
issuer,
|
||||
entryPoint,
|
||||
firstnameAttributeName,
|
||||
surnameAttributeName,
|
||||
emailAttributeName,
|
||||
roleAttributeName,
|
||||
defaultRoleId,
|
||||
active,
|
||||
} = request.body;
|
||||
|
||||
return {
|
||||
name,
|
||||
certificate,
|
||||
signatureAlgorithm,
|
||||
issuer,
|
||||
entryPoint,
|
||||
firstnameAttributeName,
|
||||
surnameAttributeName,
|
||||
emailAttributeName,
|
||||
roleAttributeName,
|
||||
defaultRoleId,
|
||||
active,
|
||||
};
|
||||
};
|
||||
@@ -1,119 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createSamlAuthProvider } from '../../../../../../test/factories/saml-auth-provider.ee.js';
|
||||
import createSamlAuthProviderMock from '../../../../../../test/mocks/rest/api/v1/admin/saml-auth-providers/create-saml-auth-provider.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/saml-auth-provider/:samlAuthProviderId', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the updated saml auth provider', async () => {
|
||||
const samlAuthProviderPayload = {
|
||||
active: true,
|
||||
name: 'Name',
|
||||
issuer: 'theclientid',
|
||||
certificate: 'dummycert',
|
||||
entryPoint: 'http://localhost:8080/realms/automatisch/protocol/saml',
|
||||
signatureAlgorithm: 'sha256',
|
||||
defaultRoleId: role.id,
|
||||
firstnameAttributeName: 'urn:oid:2.5.4.42',
|
||||
surnameAttributeName: 'urn:oid:2.5.4.4',
|
||||
emailAttributeName: 'urn:oid:1.2.840.113549.1.9.1',
|
||||
roleAttributeName: 'Role',
|
||||
};
|
||||
|
||||
const samlAuthProvider = await createSamlAuthProvider(
|
||||
samlAuthProviderPayload
|
||||
);
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}`)
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
active: false,
|
||||
name: 'Archived',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const refetchedSamlAuthProvider = await samlAuthProvider.$query();
|
||||
|
||||
const expectedPayload = await createSamlAuthProviderMock({
|
||||
...refetchedSamlAuthProvider,
|
||||
name: 'Archived',
|
||||
active: false,
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid data', async () => {
|
||||
const samlAuthProviderPayload = {
|
||||
active: true,
|
||||
name: 'Name',
|
||||
issuer: 'theclientid',
|
||||
certificate: 'dummycert',
|
||||
entryPoint: 'http://localhost:8080/realms/automatisch/protocol/saml',
|
||||
signatureAlgorithm: 'sha256',
|
||||
defaultRoleId: role.id,
|
||||
firstnameAttributeName: 'urn:oid:2.5.4.42',
|
||||
surnameAttributeName: 'urn:oid:2.5.4.4',
|
||||
emailAttributeName: 'urn:oid:1.2.840.113549.1.9.1',
|
||||
roleAttributeName: 'Role',
|
||||
};
|
||||
|
||||
const samlAuthProvider = await createSamlAuthProvider(
|
||||
samlAuthProviderPayload
|
||||
);
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}`)
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
active: 'true',
|
||||
name: 123,
|
||||
roleAttributeName: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ['must be string'],
|
||||
active: ['must be boolean'],
|
||||
roleAttributeName: ['must be string'],
|
||||
},
|
||||
meta: { type: 'ModelValidation' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not found response for not existing SAML auth provider UUID', async () => {
|
||||
const notExistingSamlAuthProviderUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.patch(
|
||||
`/api/v1/admin/saml-auth-providers/${notExistingSamlAuthProviderUUID}`
|
||||
)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.patch('/api/v1/admin/saml-auth-providers/invalidSamlAuthProviderUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const template = await Template.create(templateParams(request));
|
||||
|
||||
renderObject(response, template, {
|
||||
serializer: 'AdminTemplate',
|
||||
status: 201,
|
||||
});
|
||||
};
|
||||
|
||||
const templateParams = (request) => {
|
||||
const { name, flowId } = request.body;
|
||||
|
||||
return {
|
||||
name,
|
||||
flowId,
|
||||
};
|
||||
};
|
||||
@@ -1,135 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createFlow } from '../../../../../../test/factories/flow.js';
|
||||
import { createStep } from '../../../../../../test/factories/step.js';
|
||||
import createTemplateMock from '../../../../../../test/mocks/rest/api/v1/admin/templates/create-template.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('POST /api/v1/admin/templates', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the created template', async () => {
|
||||
const currentUserFlow = await createFlow({ userId: currentUser.id });
|
||||
|
||||
const triggerStep = await createStep({
|
||||
flowId: currentUserFlow.id,
|
||||
type: 'trigger',
|
||||
appKey: 'webhook',
|
||||
key: 'catchRawWebhook',
|
||||
name: 'Catch raw webhook',
|
||||
parameters: {
|
||||
workSynchronously: true,
|
||||
},
|
||||
position: 1,
|
||||
webhookPath: `/webhooks/flows/${currentUserFlow.id}/sync`,
|
||||
});
|
||||
|
||||
await createStep({
|
||||
flowId: currentUserFlow.id,
|
||||
type: 'action',
|
||||
appKey: 'formatter',
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
parameters: {
|
||||
input: `hello {{step.${triggerStep.id}.query.sample}} world`,
|
||||
transform: 'capitalize',
|
||||
},
|
||||
position: 2,
|
||||
});
|
||||
|
||||
const templatePayload = {
|
||||
name: 'Sample Template Name',
|
||||
flowId: currentUserFlow.id,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/templates')
|
||||
.set('Authorization', token)
|
||||
.send(templatePayload)
|
||||
.expect(201);
|
||||
|
||||
const refetchedTemplate = await Template.query().findById(
|
||||
response.body.data.id
|
||||
);
|
||||
|
||||
const expectedPayload = await createTemplateMock(refetchedTemplate);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid flow ID', async () => {
|
||||
const invalidFlowId = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.post('/api/v1/admin/templates')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
name: 'Sample Template Name',
|
||||
flowId: invalidFlowId,
|
||||
})
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid name', async () => {
|
||||
const currentUserFlow = await createFlow({ userId: currentUser.id });
|
||||
|
||||
const triggerStep = await createStep({
|
||||
flowId: currentUserFlow.id,
|
||||
type: 'trigger',
|
||||
appKey: 'webhook',
|
||||
key: 'catchRawWebhook',
|
||||
name: 'Catch raw webhook',
|
||||
parameters: {
|
||||
workSynchronously: true,
|
||||
},
|
||||
position: 1,
|
||||
webhookPath: `/webhooks/flows/${currentUserFlow.id}/sync`,
|
||||
});
|
||||
|
||||
await createStep({
|
||||
flowId: currentUserFlow.id,
|
||||
type: 'action',
|
||||
appKey: 'formatter',
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
parameters: {
|
||||
input: `hello {{step.${triggerStep.id}.query.sample}} world`,
|
||||
transform: 'capitalize',
|
||||
},
|
||||
position: 2,
|
||||
});
|
||||
|
||||
const templatePayload = {
|
||||
name: '',
|
||||
flowId: currentUserFlow.id,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/templates')
|
||||
.set('Authorization', token)
|
||||
.send(templatePayload)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ['must NOT have fewer than 1 characters'],
|
||||
},
|
||||
meta: { type: 'ModelValidation' },
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const template = await Template.query()
|
||||
.findById(request.params.templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
await template.$query().delete();
|
||||
|
||||
response.status(204).end();
|
||||
};
|
||||
@@ -1,51 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createTemplate } from '../../../../../../test/factories/template.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('DELETE /api/v1/admin/templates/:templateId', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should delete the template', async () => {
|
||||
const template = await createTemplate();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/templates/${template.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(204);
|
||||
|
||||
const deletedTemplate = await Template.query().findById(template.id);
|
||||
expect(deletedTemplate).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should return not found response for not existing template UUID', async () => {
|
||||
const notExistingTemplateUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/templates/${notExistingTemplateUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.delete('/api/v1/admin/templates/invalidTemplateUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const template = await Template.query()
|
||||
.findById(request.params.templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, template, { serializer: 'AdminTemplate' });
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createTemplate } from '../../../../../../test/factories/template.js';
|
||||
import getTemplateMock from '../../../../../../test/mocks/rest/api/v1/admin/templates/get-template.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/templates/:templateId', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return templates', async () => {
|
||||
const template = await createTemplate();
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/templates/${template.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getTemplateMock(template);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const templates = await Template.query().orderBy('created_at', 'asc');
|
||||
|
||||
renderObject(response, templates, {
|
||||
serializer: 'AdminTemplate',
|
||||
});
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createTemplate } from '../../../../../../test/factories/template.js';
|
||||
import getTemplatesMock from '../../../../../../test/mocks/rest/api/v1/admin/templates/get-templates.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/templates', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return templates', async () => {
|
||||
const templateOne = await createTemplate();
|
||||
const templateTwo = await createTemplate();
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/templates')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getTemplatesMock([templateOne, templateTwo]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import Template from '../../../../../models/template.ee.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const template = await Template.query()
|
||||
.patchAndFetchById(request.params.templateId, templateParams(request))
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, template, {
|
||||
serializer: 'AdminTemplate',
|
||||
});
|
||||
};
|
||||
|
||||
const templateParams = (request) => {
|
||||
const { name } = request.body;
|
||||
return { name };
|
||||
};
|
||||
@@ -1,77 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createTemplate } from '../../../../../../test/factories/template.js';
|
||||
import updateTemplateMock from '../../../../../../test/mocks/rest/api/v1/admin/templates/update-template.ee.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/templates/:templateId', () => {
|
||||
let currentUser, token, role;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
role = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the updated template', async () => {
|
||||
const template = await createTemplate();
|
||||
const updatedName = 'Updated Template Name';
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/templates/${template.id}`)
|
||||
.set('Authorization', token)
|
||||
.send({ name: updatedName })
|
||||
.expect(200);
|
||||
|
||||
const refetchedTemplate = await template.$query();
|
||||
|
||||
const expectedPayload = await updateTemplateMock({
|
||||
...refetchedTemplate,
|
||||
flowData: refetchedTemplate.getFlowDataWithIconUrls(),
|
||||
name: updatedName,
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response for invalid name', async () => {
|
||||
const template = await createTemplate();
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/templates/${template.id}`)
|
||||
.set('Authorization', token)
|
||||
.send({ name: '' })
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
name: ['must NOT have fewer than 1 characters'],
|
||||
},
|
||||
meta: { type: 'ModelValidation' },
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not found response for not existing template UUID', async () => {
|
||||
const notExistingTemplateUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.patch(`/api/v1/admin/templates/${notExistingTemplateUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.patch('/api/v1/admin/templates/invalidTemplateUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const user = await User.query().insertAndFetch(await userParams(request));
|
||||
await user.sendInvitationEmail();
|
||||
|
||||
renderObject(response, user, { status: 201, serializer: 'AdminUser' });
|
||||
};
|
||||
|
||||
const userParams = async (request) => {
|
||||
const { fullName, email } = request.body;
|
||||
const roleId = request.body.roleId || (await Role.findAdmin()).id;
|
||||
|
||||
return {
|
||||
fullName,
|
||||
status: 'invited',
|
||||
email: email?.toLowerCase(),
|
||||
roleId,
|
||||
};
|
||||
};
|
||||
@@ -1,122 +0,0 @@
|
||||
import { describe, beforeEach, it, expect } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
import Role from '../../../../../models/role.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import createUserMock from '../../../../../../test/mocks/rest/api/v1/admin/users/create-user.js';
|
||||
|
||||
describe('POST /api/v1/admin/users', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return created user with valid data', async () => {
|
||||
const userRole = await createRole({ name: 'User' });
|
||||
|
||||
const userData = {
|
||||
email: 'created@sample.com',
|
||||
fullName: 'Full Name',
|
||||
password: 'samplePassword123',
|
||||
roleId: userRole.id,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.send(userData)
|
||||
.expect(201);
|
||||
|
||||
const refetchedRegisteredUser = await User.query()
|
||||
.findById(response.body.data.id)
|
||||
.throwIfNotFound();
|
||||
|
||||
const expectedPayload = createUserMock(refetchedRegisteredUser);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
expect(refetchedRegisteredUser.roleId).toStrictEqual(userRole.id);
|
||||
});
|
||||
|
||||
it('should create user with admin role if there is no role id given', async () => {
|
||||
const userData = {
|
||||
email: 'created@sample.com',
|
||||
fullName: 'Full Name',
|
||||
password: 'samplePassword123',
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.send(userData)
|
||||
.expect(201);
|
||||
|
||||
const refetchedRegisteredUser = await User.query()
|
||||
.findById(response.body.data.id)
|
||||
.throwIfNotFound();
|
||||
|
||||
const refetchedUserRole = await Role.query().findById(
|
||||
refetchedRegisteredUser.roleId
|
||||
);
|
||||
|
||||
const expectedPayload = createUserMock(refetchedRegisteredUser);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
expect(refetchedUserRole.name).toStrictEqual('Admin');
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response with already used email', async () => {
|
||||
await createRole({ name: 'User' });
|
||||
|
||||
await createUser({
|
||||
email: 'created@sample.com',
|
||||
});
|
||||
|
||||
const userData = {
|
||||
email: 'created@sample.com',
|
||||
fullName: 'Full Name',
|
||||
password: 'samplePassword123',
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.send(userData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.errors).toStrictEqual({
|
||||
email: ["'email' must be unique."],
|
||||
});
|
||||
|
||||
expect(response.body.meta).toStrictEqual({
|
||||
type: 'UniqueViolationError',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return unprocessable entity response with invalid user data', async () => {
|
||||
await createRole({ name: 'User' });
|
||||
|
||||
const userData = {
|
||||
email: null,
|
||||
fullName: null,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.send(userData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
||||
expect(response.body.errors).toStrictEqual({
|
||||
email: ["must have required property 'email'"],
|
||||
fullName: ['must be string'],
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import User from '../../../../../models/user.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const id = request.params.userId;
|
||||
|
||||
const user = await User.query().findById(id).throwIfNotFound();
|
||||
await user.softRemove();
|
||||
|
||||
response.status(204).end();
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
import { describe, it, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../../test/factories/user';
|
||||
import { createRole } from '../../../../../../test/factories/role';
|
||||
|
||||
describe('DELETE /api/v1/admin/users/:userId', () => {
|
||||
let currentUser, currentUserRole, anotherUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: currentUserRole.id });
|
||||
|
||||
anotherUser = await createUser();
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should soft delete user and respond with no content', async () => {
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/users/${anotherUser.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(204);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing user UUID', async () => {
|
||||
const notExistingUserUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.delete(`/api/v1/admin/users/${notExistingUserUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.delete('/api/v1/admin/users/invalidUserUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const user = await User.query()
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
})
|
||||
.findById(request.params.userId)
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, user);
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../../test/factories/user';
|
||||
import { createRole } from '../../../../../../test/factories/role';
|
||||
import getUserMock from '../../../../../../test/mocks/rest/api/v1/admin/users/get-user.js';
|
||||
import * as license from '../../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/admin/users/:userId', () => {
|
||||
let currentUser, currentUserRole, anotherUser, anotherUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: currentUserRole.id });
|
||||
|
||||
anotherUser = await createUser();
|
||||
anotherUserRole = await anotherUser.$relatedQuery('role');
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified user info', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/admin/users/${anotherUser.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getUserMock(anotherUser, anotherUserRole);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing user UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
const notExistingUserUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/admin/users/${notExistingUserUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/admin/users/invalidUserUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
import paginateRest from '../../../../../helpers/pagination.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const usersQuery = User.query()
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
})
|
||||
.orderBy('full_name', 'asc');
|
||||
|
||||
const users = await paginateRest(usersQuery, request.query.page);
|
||||
|
||||
renderObject(response, users);
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../../app';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createRole } from '../../../../../../test/factories/role';
|
||||
import { createUser } from '../../../../../../test/factories/user';
|
||||
import getUsersMock from '../../../../../../test/mocks/rest/api/v1/admin/users/get-users.js';
|
||||
|
||||
describe('GET /api/v1/admin/users', () => {
|
||||
let currentUser, currentUserRole, anotherUser, anotherUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUserRole = await createRole({ name: 'Admin' });
|
||||
|
||||
currentUser = await createUser({
|
||||
roleId: currentUserRole.id,
|
||||
fullName: 'Current User',
|
||||
});
|
||||
|
||||
anotherUserRole = await createRole({
|
||||
name: 'Another user role',
|
||||
});
|
||||
|
||||
anotherUser = await createUser({
|
||||
roleId: anotherUserRole.id,
|
||||
fullName: 'Another User',
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return users data', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/admin/users')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedResponsePayload = await getUsersMock(
|
||||
[anotherUser, currentUser],
|
||||
[anotherUserRole, currentUserRole]
|
||||
);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedResponsePayload);
|
||||
});
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import { renderObject } from '../../../../../helpers/renderer.js';
|
||||
import User from '../../../../../models/user.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const user = await User.query()
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
})
|
||||
.patchAndFetchById(request.params.userId, userParams(request))
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, user);
|
||||
};
|
||||
|
||||
const userParams = (request) => {
|
||||
const { email, fullName, roleId } = request.body;
|
||||
return { email, fullName, roleId };
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../../test/factories/user.js';
|
||||
import { createRole } from '../../../../../../test/factories/role.js';
|
||||
import updateUserMock from '../../../../../../test/mocks/rest/api/v1/admin/users/update-user.js';
|
||||
|
||||
describe('PATCH /api/v1/admin/users/:userId', () => {
|
||||
let currentUser, adminRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
adminRole = await createRole({ name: 'Admin' });
|
||||
currentUser = await createUser({ roleId: adminRole.id });
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return updated user with valid data for another user', async () => {
|
||||
const anotherUser = await createUser();
|
||||
const anotherRole = await createRole();
|
||||
|
||||
const anotherUserUpdatedData = {
|
||||
email: 'updated@sample.com',
|
||||
fullName: 'Updated Full Name',
|
||||
roleId: anotherRole.id,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/users/${anotherUser.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(anotherUserUpdatedData)
|
||||
.expect(200);
|
||||
|
||||
const refetchedAnotherUser = await anotherUser.$query();
|
||||
|
||||
const expectedPayload = updateUserMock(
|
||||
{
|
||||
...refetchedAnotherUser,
|
||||
...anotherUserUpdatedData,
|
||||
},
|
||||
anotherRole
|
||||
);
|
||||
|
||||
expect(response.body).toMatchObject(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return HTTP 422 with invalid user data', async () => {
|
||||
const anotherUser = await createUser();
|
||||
|
||||
const anotherUserUpdatedData = {
|
||||
email: null,
|
||||
fullName: null,
|
||||
roleId: null,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.patch(`/api/v1/admin/users/${anotherUser.id}`)
|
||||
.set('Authorization', token)
|
||||
.send(anotherUserUpdatedData)
|
||||
.expect(422);
|
||||
|
||||
expect(response.body.meta.type).toStrictEqual('ModelValidation');
|
||||
|
||||
expect(response.body.errors).toMatchObject({
|
||||
email: ['must be string'],
|
||||
fullName: ['must be string'],
|
||||
roleId: ['must be string'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return not found response for not existing user UUID', async () => {
|
||||
const notExistingUserUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.patch(`/api/v1/admin/users/${notExistingUserUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.patch('/api/v1/admin/users/invalidUserUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const connection = await request.currentUser
|
||||
.$relatedQuery('connections')
|
||||
.insertAndFetch(connectionParams(request));
|
||||
|
||||
const connectionWithAppConfigAndAuthClient = await connection
|
||||
.$query()
|
||||
.withGraphFetched({
|
||||
appConfig: true,
|
||||
oauthClient: true,
|
||||
});
|
||||
|
||||
renderObject(response, connectionWithAppConfigAndAuthClient, { status: 201 });
|
||||
};
|
||||
|
||||
const connectionParams = (request) => {
|
||||
const { oauthClientId, formattedData } = request.body;
|
||||
|
||||
return {
|
||||
key: request.params.appKey,
|
||||
oauthClientId,
|
||||
formattedData,
|
||||
verified: false,
|
||||
};
|
||||
};
|
||||
@@ -1,394 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createAppConfig } from '../../../../../test/factories/app-config.js';
|
||||
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import { createPermission } from '../../../../../test/factories/permission.js';
|
||||
import { createRole } from '../../../../../test/factories/role.js';
|
||||
import createConnection from '../../../../../test/mocks/rest/api/v1/apps/create-connection.js';
|
||||
|
||||
describe('POST /api/v1/apps/:appKey/connections', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
const role = await createRole();
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Connection',
|
||||
roleId: role.id,
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'manage',
|
||||
subject: 'Connection',
|
||||
roleId: role.id,
|
||||
});
|
||||
|
||||
currentUser = await createUser({ roleId: role.id });
|
||||
|
||||
currentUser = await currentUser
|
||||
.$query()
|
||||
.leftJoinRelated({
|
||||
role: true,
|
||||
permissions: true,
|
||||
})
|
||||
.withGraphFetched({
|
||||
role: true,
|
||||
permissions: true,
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
describe('with no app config', async () => {
|
||||
it('should return created connection', async () => {
|
||||
const connectionData = {
|
||||
formattedData: {
|
||||
oAuthRedirectUrl: 'http://localhost:3000/app/gitlab/connections/add',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
clientId: 'sample_client_id',
|
||||
clientSecret: 'sample_client_secret',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(201);
|
||||
|
||||
const fetchedConnection =
|
||||
await currentUser.authorizedConnections.findById(response.body.data.id);
|
||||
|
||||
const expectedPayload = createConnection({
|
||||
...fetchedConnection,
|
||||
formattedData: {},
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with app disabled', async () => {
|
||||
beforeEach(async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
disabled: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return with not authorized response', async () => {
|
||||
const connectionData = {
|
||||
formattedData: {
|
||||
oAuthRedirectUrl: 'http://localhost:3000/app/gitlab/connections/add',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
clientId: 'sample_client_id',
|
||||
clientSecret: 'sample_client_secret',
|
||||
},
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom connections enabled', async () => {
|
||||
beforeEach(async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
disabled: false,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return created conncetion', async () => {
|
||||
const connectionData = {
|
||||
formattedData: {
|
||||
oAuthRedirectUrl: 'http://localhost:3000/app/gitlab/connections/add',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
clientId: 'sample_client_id',
|
||||
clientSecret: 'sample_client_secret',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(201);
|
||||
|
||||
const fetchedConnection =
|
||||
await currentUser.authorizedConnections.findById(response.body.data.id);
|
||||
|
||||
const expectedPayload = createConnection({
|
||||
...fetchedConnection,
|
||||
formattedData: {},
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with custom connections disabled', async () => {
|
||||
beforeEach(async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
disabled: false,
|
||||
useOnlyPredefinedAuthClients: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return with not authorized response', async () => {
|
||||
const connectionData = {
|
||||
formattedData: {
|
||||
oAuthRedirectUrl: 'http://localhost:3000/app/gitlab/connections/add',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
clientId: 'sample_client_id',
|
||||
clientSecret: 'sample_client_secret',
|
||||
},
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with auth client enabled', async () => {
|
||||
let oauthClient;
|
||||
|
||||
beforeEach(async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
disabled: false,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
});
|
||||
|
||||
oauthClient = await createOAuthClient({
|
||||
appKey: 'gitlab',
|
||||
active: true,
|
||||
formattedAuthDefaults: {
|
||||
oAuthRedirectUrl: 'http://localhost:3000/app/gitlab/connections/add',
|
||||
instanceUrl: 'https://gitlab.com',
|
||||
clientId: 'sample_client_id',
|
||||
clientSecret: 'sample_client_secret',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return created connection', async () => {
|
||||
const connectionData = {
|
||||
oauthClientId: oauthClient.id,
|
||||
};
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(201);
|
||||
|
||||
const fetchedConnection =
|
||||
await currentUser.authorizedConnections.findById(response.body.data.id);
|
||||
|
||||
const expectedPayload = createConnection({
|
||||
...fetchedConnection,
|
||||
formattedData: {},
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with auth client disabled', async () => {
|
||||
let oauthClient;
|
||||
|
||||
beforeEach(async () => {
|
||||
await createAppConfig({
|
||||
key: 'gitlab',
|
||||
disabled: false,
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
});
|
||||
|
||||
oauthClient = await createOAuthClient({
|
||||
appKey: 'gitlab',
|
||||
active: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return with not authorized response', async () => {
|
||||
const connectionData = {
|
||||
oauthClientId: oauthClient.id,
|
||||
};
|
||||
|
||||
await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send(connectionData)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.post('/api/v1/apps/invalid-app-key/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return unprocesible entity response for invalid connection data', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/v1/apps/gitlab/connections')
|
||||
.set('Authorization', token)
|
||||
.send({
|
||||
formattedData: 123,
|
||||
})
|
||||
.expect(422);
|
||||
|
||||
expect(response.body).toStrictEqual({
|
||||
errors: {
|
||||
formattedData: ['must be object'],
|
||||
},
|
||||
meta: {
|
||||
type: 'ModelValidation',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const substeps = await App.findActionSubsteps(
|
||||
request.params.appKey,
|
||||
request.params.actionKey
|
||||
);
|
||||
|
||||
renderObject(response, substeps);
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getActionSubstepsMock from '../../../../../test/mocks/rest/api/v1/apps/get-action-substeps.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/actions/:actionKey/substeps', () => {
|
||||
let currentUser, exampleApp, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
exampleApp = await App.findOneByKey('github');
|
||||
});
|
||||
|
||||
it('should return the action substeps info', async () => {
|
||||
const actions = await App.findActionsByKey('github');
|
||||
const exampleAction = actions.find(
|
||||
(action) => action.key === 'createIssue'
|
||||
);
|
||||
|
||||
const endpointUrl = `/api/v1/apps/${exampleApp.key}/actions/${exampleAction.key}/substeps`;
|
||||
|
||||
const response = await request(app)
|
||||
.get(endpointUrl)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getActionSubstepsMock(exampleAction.substeps);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/actions/invalid-actions-key/substeps')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return empty array for invalid action key', async () => {
|
||||
const endpointUrl = `/api/v1/apps/${exampleApp.key}/actions/invalid-action-key/substeps`;
|
||||
|
||||
const response = await request(app)
|
||||
.get(endpointUrl)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const actions = await App.findActionsByKey(request.params.appKey);
|
||||
|
||||
renderObject(response, actions, { serializer: 'Action' });
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getActionsMock from '../../../../../test/mocks/rest/api/v1/apps/get-actions.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/actions', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the app actions', async () => {
|
||||
const exampleApp = await App.findOneByKey('github');
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${exampleApp.key}/actions`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getActionsMock(exampleApp.actions);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/actions')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const app = await App.findOneByKey(request.params.appKey);
|
||||
|
||||
renderObject(response, app, { serializer: 'App' });
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getAppMock from '../../../../../test/mocks/rest/api/v1/apps/get-app.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the app info', async () => {
|
||||
const exampleApp = await App.findOneByKey('github');
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${exampleApp.key}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppMock(exampleApp);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
let apps = await App.findAll(request.query.name);
|
||||
|
||||
if (request.query.onlyWithTriggers) {
|
||||
apps = apps.filter((app) => app.triggers?.length);
|
||||
}
|
||||
|
||||
if (request.query.onlyWithActions) {
|
||||
apps = apps.filter((app) => app.actions?.length);
|
||||
}
|
||||
|
||||
renderObject(response, apps, { serializer: 'App' });
|
||||
};
|
||||
@@ -1,63 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getAppsMock from '../../../../../test/mocks/rest/api/v1/apps/get-apps.js';
|
||||
|
||||
describe('GET /api/v1/apps', () => {
|
||||
let currentUser, apps, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
apps = await App.findAll();
|
||||
});
|
||||
|
||||
it('should return all apps', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppsMock(apps);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return all apps filtered by name', async () => {
|
||||
const appsWithNameGit = apps.filter((app) => app.name.includes('Git'));
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps?name=Git')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppsMock(appsWithNameGit);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return only the apps with triggers', async () => {
|
||||
const appsWithTriggers = apps.filter((app) => app.triggers?.length > 0);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps?onlyWithTriggers=true')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppsMock(appsWithTriggers);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return only the apps with actions', async () => {
|
||||
const appsWithActions = apps.filter((app) => app.actions?.length > 0);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps?onlyWithActions=true')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppsMock(appsWithActions);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const auth = await App.findAuthByKey(request.params.appKey);
|
||||
|
||||
renderObject(response, auth, { serializer: 'Auth' });
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getAuthMock from '../../../../../test/mocks/rest/api/v1/apps/get-auth.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/auth', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the app auth info', async () => {
|
||||
const exampleApp = await App.findOneByKey('github');
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${exampleApp.key}/auth`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAuthMock(exampleApp.auth);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/auth')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import AppConfig from '../../../../models/app-config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const appConfig = await AppConfig.query()
|
||||
.withGraphFetched({
|
||||
oauthClients: true,
|
||||
})
|
||||
.findOne({
|
||||
key: request.params.appKey,
|
||||
})
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, appConfig);
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getAppConfigMock from '../../../../../test/mocks/rest/api/v1/apps/get-config.js';
|
||||
import { createAppConfig } from '../../../../../test/factories/app-config.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/config', () => {
|
||||
let currentUser, appConfig, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
currentUser = await createUser();
|
||||
|
||||
appConfig = await createAppConfig({
|
||||
key: 'deepl',
|
||||
useOnlyPredefinedAuthClients: false,
|
||||
disabled: false,
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified app config info', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${appConfig.key}/config`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getAppConfigMock(appConfig);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/not-existing-app-key/config')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import App from '../../../../models/app.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const app = await App.findOneByKey(request.params.appKey);
|
||||
|
||||
const connections = await request.currentUser.authorizedConnections
|
||||
.clone()
|
||||
.select('connections.*')
|
||||
.withGraphFetched({
|
||||
appConfig: true,
|
||||
oauthClient: true,
|
||||
})
|
||||
.fullOuterJoinRelated('steps')
|
||||
.where({
|
||||
'connections.key': app.key,
|
||||
'connections.draft': false,
|
||||
})
|
||||
.countDistinct('steps.flow_id as flowCount')
|
||||
.groupBy('connections.id')
|
||||
.orderBy('created_at', 'desc');
|
||||
|
||||
renderObject(response, connections);
|
||||
};
|
||||
@@ -1,101 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import { createConnection } from '../../../../../test/factories/connection.js';
|
||||
import { createPermission } from '../../../../../test/factories/permission.js';
|
||||
import getConnectionsMock from '../../../../../test/mocks/rest/api/v1/apps/get-connections.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/connections', () => {
|
||||
let currentUser, currentUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
currentUserRole = await currentUser.$relatedQuery('role');
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the connections data of specified app for current user', async () => {
|
||||
const currentUserConnectionOne = await createConnection({
|
||||
userId: currentUser.id,
|
||||
key: 'deepl',
|
||||
draft: false,
|
||||
});
|
||||
|
||||
const currentUserConnectionTwo = await createConnection({
|
||||
userId: currentUser.id,
|
||||
key: 'deepl',
|
||||
draft: false,
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Connection',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: ['isCreator'],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps/deepl/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getConnectionsMock([
|
||||
currentUserConnectionTwo,
|
||||
currentUserConnectionOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return the connections data of specified app for another user', async () => {
|
||||
const anotherUser = await createUser();
|
||||
|
||||
const anotherUserConnectionOne = await createConnection({
|
||||
userId: anotherUser.id,
|
||||
key: 'deepl',
|
||||
draft: false,
|
||||
});
|
||||
|
||||
const anotherUserConnectionTwo = await createConnection({
|
||||
userId: anotherUser.id,
|
||||
key: 'deepl',
|
||||
draft: false,
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Connection',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: [],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps/deepl/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getConnectionsMock([
|
||||
anotherUserConnectionTwo,
|
||||
anotherUserConnectionOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid connection UUID', async () => {
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Connection',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: ['isCreator'],
|
||||
});
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-connection-id/connections')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import App from '../../../../models/app.js';
|
||||
import Flow from '../../../../models/flow.js';
|
||||
import paginateRest from '../../../../helpers/pagination.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const app = await App.findOneByKey(request.params.appKey);
|
||||
|
||||
const flowsQuery = request.currentUser.authorizedFlows
|
||||
.clone()
|
||||
.distinct('flows.*')
|
||||
.joinRelated({
|
||||
steps: true,
|
||||
})
|
||||
.withGraphFetched({
|
||||
steps: true,
|
||||
})
|
||||
.select('flows.*')
|
||||
.select(
|
||||
Flow.raw('flows.user_id = ? as "isOwner"', [request.currentUser.id])
|
||||
)
|
||||
.where('steps.app_key', app.key)
|
||||
.orderBy('active', 'desc')
|
||||
.orderBy('updated_at', 'desc');
|
||||
|
||||
const flows = await paginateRest(flowsQuery, request.query.page);
|
||||
|
||||
renderObject(response, flows);
|
||||
};
|
||||
@@ -1,131 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import { createFlow } from '../../../../../test/factories/flow.js';
|
||||
import { createStep } from '../../../../../test/factories/step.js';
|
||||
import { createPermission } from '../../../../../test/factories/permission.js';
|
||||
import getFlowsMock from '../../../../../test/mocks/rest/api/v1/apps/get-flows.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/flows', () => {
|
||||
let currentUser, currentUserRole, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
currentUserRole = await currentUser.$relatedQuery('role');
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the flows data of specified app for current user', async () => {
|
||||
const currentUserFlowOne = await createFlow({ userId: currentUser.id });
|
||||
|
||||
const triggerStepFlowOne = await createStep({
|
||||
flowId: currentUserFlowOne.id,
|
||||
type: 'trigger',
|
||||
appKey: 'webhook',
|
||||
});
|
||||
|
||||
const actionStepFlowOne = await createStep({
|
||||
flowId: currentUserFlowOne.id,
|
||||
type: 'action',
|
||||
});
|
||||
|
||||
const currentUserFlowTwo = await createFlow({ userId: currentUser.id });
|
||||
|
||||
await createStep({
|
||||
flowId: currentUserFlowTwo.id,
|
||||
type: 'trigger',
|
||||
appKey: 'github',
|
||||
});
|
||||
|
||||
await createStep({
|
||||
flowId: currentUserFlowTwo.id,
|
||||
type: 'action',
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: ['isCreator'],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps/webhook/flows')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getFlowsMock(
|
||||
[currentUserFlowOne],
|
||||
[triggerStepFlowOne, actionStepFlowOne],
|
||||
currentUser.id
|
||||
);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return the flows data of specified app for another user', async () => {
|
||||
const anotherUser = await createUser();
|
||||
const anotherUserFlowOne = await createFlow({ userId: anotherUser.id });
|
||||
|
||||
const triggerStepFlowOne = await createStep({
|
||||
flowId: anotherUserFlowOne.id,
|
||||
type: 'trigger',
|
||||
appKey: 'webhook',
|
||||
});
|
||||
|
||||
const actionStepFlowOne = await createStep({
|
||||
flowId: anotherUserFlowOne.id,
|
||||
type: 'action',
|
||||
});
|
||||
|
||||
const anotherUserFlowTwo = await createFlow({ userId: anotherUser.id });
|
||||
|
||||
await createStep({
|
||||
flowId: anotherUserFlowTwo.id,
|
||||
type: 'trigger',
|
||||
appKey: 'github',
|
||||
});
|
||||
|
||||
await createStep({
|
||||
flowId: anotherUserFlowTwo.id,
|
||||
type: 'action',
|
||||
});
|
||||
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: [],
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps/webhook/flows')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = await getFlowsMock(
|
||||
[anotherUserFlowOne],
|
||||
[triggerStepFlowOne, actionStepFlowOne],
|
||||
currentUser.id
|
||||
);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await createPermission({
|
||||
action: 'read',
|
||||
subject: 'Flow',
|
||||
roleId: currentUserRole.id,
|
||||
conditions: ['isCreator'],
|
||||
});
|
||||
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/flows')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import OAuthClient from '../../../../models/oauth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const oauthClient = await OAuthClient.query()
|
||||
.findById(request.params.oauthClientId)
|
||||
.where({ app_key: request.params.appKey, active: true })
|
||||
.throwIfNotFound();
|
||||
|
||||
renderObject(response, oauthClient);
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import Crypto from 'crypto';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getOAuthClientMock from '../../../../../test/mocks/rest/api/v1/apps/get-oauth-client.js';
|
||||
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/oauth-clients/:oauthClientId', () => {
|
||||
let currentUser, currentOAuthClient, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
currentUser = await createUser();
|
||||
currentOAuthClient = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified oauth client', async () => {
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/deepl/oauth-clients/${currentOAuthClient.id}`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getOAuthClientMock(currentOAuthClient);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for not existing oauth client ID', async () => {
|
||||
const notExistingOAuthClientUUID = Crypto.randomUUID();
|
||||
|
||||
await request(app)
|
||||
.get(`/api/v1/apps/deepl/oauth-clients/${notExistingOAuthClientUUID}`)
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return bad request response for invalid UUID', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/deepl/oauth-clients/invalidOAuthClientUUID')
|
||||
.set('Authorization', token)
|
||||
.expect(400);
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import OAuthClient from '../../../../models/oauth-client.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const oauthClients = await OAuthClient.query()
|
||||
.where({ app_key: request.params.appKey, active: true })
|
||||
.orderBy('created_at', 'desc');
|
||||
|
||||
renderObject(response, oauthClients);
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js';
|
||||
import { createUser } from '../../../../../test/factories/user.js';
|
||||
import getOAuthClientsMock from '../../../../../test/mocks/rest/api/v1/apps/get-oauth-clients.js';
|
||||
import { createOAuthClient } from '../../../../../test/factories/oauth-client.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/oauth-clients', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
|
||||
currentUser = await createUser();
|
||||
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return specified oauth client info', async () => {
|
||||
const oauthClientOne = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
const oauthClientTwo = await createOAuthClient({
|
||||
appKey: 'deepl',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/apps/deepl/oauth-clients')
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getOAuthClientsMock([
|
||||
oauthClientTwo,
|
||||
oauthClientOne,
|
||||
]);
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const substeps = await App.findTriggerSubsteps(
|
||||
request.params.appKey,
|
||||
request.params.triggerKey
|
||||
);
|
||||
|
||||
renderObject(response, substeps);
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getTriggerSubstepsMock from '../../../../../test/mocks/rest/api/v1/apps/get-trigger-substeps.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/triggers/:triggerKey/substeps', () => {
|
||||
let currentUser, exampleApp, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
exampleApp = await App.findOneByKey('github');
|
||||
});
|
||||
|
||||
it('should return the trigger substeps info', async () => {
|
||||
const triggers = await App.findTriggersByKey('github');
|
||||
const exampleTrigger = triggers.find(
|
||||
(trigger) => trigger.key === 'newIssues'
|
||||
);
|
||||
|
||||
const endpointUrl = `/api/v1/apps/${exampleApp.key}/triggers/${exampleTrigger.key}/substeps`;
|
||||
|
||||
const response = await request(app)
|
||||
.get(endpointUrl)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getTriggerSubstepsMock(exampleTrigger.substeps);
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/triggers/invalid-trigger-key/substeps')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it('should return empty array for invalid trigger key', async () => {
|
||||
const endpointUrl = `/api/v1/apps/${exampleApp.key}/triggers/invalid-trigger-key/substeps`;
|
||||
|
||||
const response = await request(app)
|
||||
.get(endpointUrl)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.data).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import App from '../../../../models/app.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const triggers = await App.findTriggersByKey(request.params.appKey);
|
||||
|
||||
renderObject(response, triggers, { serializer: 'Trigger' });
|
||||
};
|
||||
@@ -1,35 +0,0 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import App from '../../../../models/app';
|
||||
import app from '../../../../app.js';
|
||||
import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id';
|
||||
import { createUser } from '../../../../../test/factories/user';
|
||||
import getTriggersMock from '../../../../../test/mocks/rest/api/v1/apps/get-triggers.js';
|
||||
|
||||
describe('GET /api/v1/apps/:appKey/triggers', () => {
|
||||
let currentUser, token;
|
||||
|
||||
beforeEach(async () => {
|
||||
currentUser = await createUser();
|
||||
token = await createAuthTokenByUserId(currentUser.id);
|
||||
});
|
||||
|
||||
it('should return the app triggers', async () => {
|
||||
const exampleApp = await App.findOneByKey('github');
|
||||
|
||||
const response = await request(app)
|
||||
.get(`/api/v1/apps/${exampleApp.key}/triggers`)
|
||||
.set('Authorization', token)
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = getTriggersMock(exampleApp.triggers);
|
||||
expect(expectedPayload).toMatchObject(response.body);
|
||||
});
|
||||
|
||||
it('should return not found response for invalid app key', async () => {
|
||||
await request(app)
|
||||
.get('/api/v1/apps/invalid-app-key/triggers')
|
||||
.set('Authorization', token)
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
@@ -1,8 +0,0 @@
|
||||
import Config from '../../../../models/config.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const config = await Config.get();
|
||||
|
||||
renderObject(response, config);
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
import { vi, expect, describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import { updateConfig } from '../../../../../test/factories/config.js';
|
||||
import app from '../../../../app.js';
|
||||
import configMock from '../../../../../test/mocks/rest/api/v1/automatisch/config.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/config', () => {
|
||||
it('should return Automatisch config along with static config', async () => {
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
vi.spyOn(appConfig, 'disableNotificationsPage', 'get').mockReturnValue(
|
||||
true
|
||||
);
|
||||
vi.spyOn(appConfig, 'disableFavicon', 'get').mockReturnValue(true);
|
||||
vi.spyOn(appConfig, 'additionalDrawerLink', 'get').mockReturnValue('link');
|
||||
vi.spyOn(appConfig, 'additionalDrawerLinkIcon', 'get').mockReturnValue(
|
||||
'icon'
|
||||
);
|
||||
vi.spyOn(appConfig, 'additionalDrawerLinkText', 'get').mockReturnValue(
|
||||
'text'
|
||||
);
|
||||
|
||||
const config = await updateConfig({
|
||||
logoSvgData: '<svg>Sample</svg>',
|
||||
palettePrimaryDark: '#001f52',
|
||||
palettePrimaryLight: '#4286FF',
|
||||
palettePrimaryMain: '#0059F7',
|
||||
title: 'Sample Title',
|
||||
enableTemplates: true,
|
||||
enableFooter: true,
|
||||
footerLogoSvgData: '<svg>Sample Footer Logo</svg>',
|
||||
footerCopyrightText: '© AB Software GmbH',
|
||||
footerBackgroundColor: '#FFFFFF',
|
||||
footerTextColor: '#000000',
|
||||
footerDocsUrl: 'https://automatisch.io/docs',
|
||||
footerTosUrl: 'https://automatisch.io/terms',
|
||||
footerPrivacyPolicyUrl: 'https://automatisch.io/privacy',
|
||||
footerImprintUrl: 'https://automatisch.io/imprint',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/config')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = configMock({
|
||||
...config,
|
||||
disableNotificationsPage: true,
|
||||
disableFavicon: true,
|
||||
additionalDrawerLink: 'link',
|
||||
additionalDrawerLinkIcon: 'icon',
|
||||
additionalDrawerLinkText: 'text',
|
||||
enableTemplates: true,
|
||||
enableFooter: true,
|
||||
footerLogoSvgData: '<svg>Sample Footer Logo</svg>',
|
||||
footerCopyrightText: '© AB Software GmbH',
|
||||
footerBackgroundColor: '#FFFFFF',
|
||||
footerTextColor: '#000000',
|
||||
footerDocsUrl: 'https://automatisch.io/docs',
|
||||
footerTosUrl: 'https://automatisch.io/terms',
|
||||
footerPrivacyPolicyUrl: 'https://automatisch.io/privacy',
|
||||
footerImprintUrl: 'https://automatisch.io/imprint',
|
||||
});
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import { hasValidLicense } from '../../../../helpers/license.ee.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
import Config from '../../../../models/config.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const installationCompleted = await Config.isInstallationCompleted();
|
||||
|
||||
const info = {
|
||||
docsUrl: appConfig.docsUrl,
|
||||
installationCompleted,
|
||||
isCloud: appConfig.isCloud,
|
||||
isEnterprise: await hasValidLicense(),
|
||||
isMation: appConfig.isMation,
|
||||
};
|
||||
|
||||
renderObject(response, info);
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import { vi, expect, describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import appConfig from '../../../../config/app.js';
|
||||
import Config from '../../../../models/config.js';
|
||||
import app from '../../../../app.js';
|
||||
import infoMock from '../../../../../test/mocks/rest/api/v1/automatisch/info.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/info', () => {
|
||||
it('should return Automatisch info', async () => {
|
||||
vi.spyOn(Config, 'isInstallationCompleted').mockResolvedValue(true);
|
||||
vi.spyOn(appConfig, 'isCloud', 'get').mockReturnValue(false);
|
||||
vi.spyOn(appConfig, 'isMation', 'get').mockReturnValue(false);
|
||||
vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true);
|
||||
vi.spyOn(appConfig, 'docsUrl', 'get').mockReturnValue('https://automatisch.io/docs');
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/info')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = infoMock();
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
import { getLicense } from '../../../../helpers/license.ee.js';
|
||||
import { renderObject } from '../../../../helpers/renderer.js';
|
||||
|
||||
export default async (request, response) => {
|
||||
const license = await getLicense();
|
||||
|
||||
const computedLicense = {
|
||||
id: license ? license.id : null,
|
||||
name: license ? license.name : null,
|
||||
expireAt: license ? license.expireAt : null,
|
||||
verified: license ? true : false,
|
||||
};
|
||||
|
||||
renderObject(response, computedLicense);
|
||||
};
|
||||
@@ -1,23 +0,0 @@
|
||||
import { vi, expect, describe, it } from 'vitest';
|
||||
import request from 'supertest';
|
||||
import app from '../../../../app.js';
|
||||
import licenseMock from '../../../../../test/mocks/rest/api/v1/automatisch/license.js';
|
||||
import * as license from '../../../../helpers/license.ee.js';
|
||||
|
||||
describe('GET /api/v1/automatisch/license', () => {
|
||||
it('should return Automatisch license info', async () => {
|
||||
vi.spyOn(license, 'getLicense').mockResolvedValue({
|
||||
id: '123',
|
||||
name: 'license-name',
|
||||
expireAt: '2025-12-31T23:59:59Z',
|
||||
});
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/v1/automatisch/license')
|
||||
.expect(200);
|
||||
|
||||
const expectedPayload = licenseMock();
|
||||
|
||||
expect(response.body).toStrictEqual(expectedPayload);
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user