1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-10 17:53:36 +02:00

Make services terrible again (send knex)

This commit is contained in:
Christopher Kolstad 2022-10-20 14:06:26 +02:00
parent 914955e9d7
commit c5ec8fb240
No known key found for this signature in database
GPG Key ID: 559ACB0E3DB5538A
82 changed files with 190 additions and 181 deletions

View File

@ -1,10 +1,11 @@
import { Knex } from 'knex';
import { IEvent, IBaseEvent } from '../types/events';
import { LogProvider, Logger } from '../logger';
import { IBaseEvent, IEvent } from '../types/events';
import { Logger, LogProvider } from '../logger';
import { IEventStore } from '../types/stores/event-store';
import { ITag } from '../types/model';
import { SearchEventsSchema } from '../openapi/spec/search-events-schema';
import { AnyEventEmitter } from '../util/anyEventEmitter';
import { Transactional } from '../types/stores/transactional';
const EVENT_COLUMNS = [
'id',
@ -34,14 +35,20 @@ export interface IEventTable {
const TABLE = 'events';
class EventStore extends AnyEventEmitter implements IEventStore {
class EventStore
extends AnyEventEmitter
implements IEventStore, Transactional<IEventStore>
{
private db: Knex;
private logger: Logger;
private logProvider: LogProvider;
constructor(db: Knex, getLogger: LogProvider) {
super();
this.db = db;
this.logProvider = getLogger;
this.logger = getLogger('lib/db/event-store.ts');
}
@ -217,6 +224,18 @@ class EventStore extends AnyEventEmitter implements IEventStore {
environment: e.environment,
};
}
transactional(transaction: Knex.Transaction): IEventStore {
let clone = new (this.constructor as {
new (db: Knex, getLogger: LogProvider): any;
})(this.db, this.logProvider);
for (const attribute in this) {
clone[attribute] = this[attribute];
}
clone.db = transaction;
return clone as IEventStore;
}
}
export default EventStore;

View File

@ -21,7 +21,7 @@ async function getSetup(preRouterHook) {
},
});
const stores = createStores();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const unleashSession = sessionDb(config, undefined);
const app = await getApp(config, stores, services, unleashSession);

View File

@ -21,7 +21,7 @@ async function getSetup() {
ui: uiConfig,
});
const stores = createStores();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);

View File

@ -14,7 +14,7 @@ async function getSetup() {
});
const stores = createStores();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -14,7 +14,7 @@ async function getSetup() {
server: { baseUriPath: base },
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -14,7 +14,7 @@ async function getSetup(anonymise: boolean = false) {
server: { baseUriPath: base },
experimental: { flags: { anonymiseEventLog: anonymise } },
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return { base, eventStore: stores.eventStore, request: supertest(app) };

View File

@ -11,7 +11,7 @@ async function getSetup() {
const config = createTestConfig({
preRouterHook: perms.hook,
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -21,7 +21,7 @@ async function getSetup() {
const config = createTestConfig({
server: { baseUriPath: base },
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return { base, request: supertest(app) };
}

View File

@ -25,7 +25,7 @@ describe('Public Signup API', () => {
removeRolesOfTypeForUser: jest.fn(),
};
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
await stores.roleStore.create({

View File

@ -15,7 +15,7 @@ async function getSetup() {
server: { baseUriPath: randomBase },
preRouterHook: perms.hook,
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
destroy = () => {

View File

@ -13,7 +13,7 @@ async function getSetup() {
server: { baseUriPath: base },
preRouterHook: perms.hook,
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -22,7 +22,7 @@ async function getSetup() {
},
server: { baseUriPath: base },
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {
base,

View File

@ -9,7 +9,7 @@ test('should enable prometheus', async () => {
expect.assertions(0);
const stores = createStores();
const config = createTestConfig();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);

View File

@ -14,7 +14,7 @@ async function getSetup() {
const config = createTestConfig({
server: { baseUriPath: base },
});
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);

View File

@ -10,7 +10,7 @@ async function getSetup(opts?: IUnleashOptions) {
const stores = createStores();
const config = createTestConfig(opts);
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -8,7 +8,7 @@ import { createServices } from '../../services';
async function getSetup() {
const stores = createStores();
const config = createTestConfig();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -9,7 +9,7 @@ import getApp from '../app';
async function getSetup() {
const stores = createStores();
const config = createTestConfig();
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
return {

View File

@ -25,7 +25,7 @@ describe('Public Signup API', () => {
removeRolesOfTypeForUser: jest.fn(),
};
const services = createServices(stores, config);
const services = createServices(stores, config, undefined);
const app = await getApp(config, stores, services);
await stores.roleStore.create({

View File

@ -35,7 +35,7 @@ async function createApp(
const serverVersion = version;
const db = createDb(config);
const stores = createStores(config, db);
const services = createServices(stores, config);
const services = createServices(stores, config, db);
const metricsMonitor = createMetricsMonitor();
const unleashSession = sessionDb(config, db);

View File

@ -30,13 +30,14 @@ export class GroupService {
constructor(
stores: Pick<IUnleashStores, 'groupStore' | 'eventStore' | 'userStore'>,
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>, // db: Knex,
{ getLogger }: Pick<IUnleashConfig, 'getLogger'>,
db: Knex,
) {
this.logger = getLogger('service/group-service.js');
this.groupStore = stores.groupStore;
this.eventStore = stores.eventStore;
this.userStore = stores.userStore;
// this.db = db;
this.db = db;
}
async getAll(): Promise<IGroupModel[]> {
@ -106,23 +107,24 @@ export class GroupService {
const preData = await this.groupStore.get(group.id);
await this.validateGroup(group, preData);
return this.db.transaction(async (tx) => {
const newGroup = await this.groupStore
.transactional(tx)
.update(group);
const newGroup = await this.groupStore.update(group);
const existingUsers = await this.groupStore
.transactional(tx)
.getAllUsersByGroups([group.id]);
const existingUserIds = existingUsers.map((g) => g.userId);
const existingUsers = await this.groupStore.getAllUsersByGroups([
group.id,
]);
const existingUserIds = existingUsers.map((g) => g.userId);
const deletableUsers = existingUsers.filter(
(existingUser) =>
!group.users.some(
(groupUser) => groupUser.user.id == existingUser.userId,
),
);
const deletableUserIds = deletableUsers.map((g) => g.userId);
const deletableUsers = existingUsers.filter(
(existingUser) =>
!group.users.some(
(groupUser) => groupUser.user.id == existingUser.userId,
),
);
const deletableUserIds = deletableUsers.map((g) => g.userId);
this.db.transaction(async (tx) => {
await this.groupStore.transactional(tx).updateGroupUsers(
newGroup.id,
group.users.filter(
@ -136,16 +138,14 @@ export class GroupService {
deletableUsers,
userName,
);
await this.eventStore.transactional(tx).store({
type: GROUP_UPDATED,
createdBy: userName,
data: newGroup,
preData,
});
return newGroup;
});
await this.eventStore.store({
type: GROUP_UPDATED,
createdBy: userName,
data: newGroup,
preData,
});
return newGroup;
}
async getProjectGroups(
@ -226,19 +226,21 @@ export class GroupService {
userId: number,
externalGroups: string[],
): Promise<void> {
let newGroups = await this.groupStore.getNewGroupsForExternalUser(
userId,
externalGroups,
);
await this.groupStore.addUserToGroups(
userId,
newGroups.map((g) => g.id),
);
let oldGroups = await this.groupStore.getOldGroupsForExternalUser(
userId,
externalGroups,
);
await this.groupStore.deleteUsersFromGroup(oldGroups);
await this.db.transaction(async (trx) => {
let newGroups = await this.groupStore
.transactional(trx)
.getNewGroupsForExternalUser(userId, externalGroups);
await this.groupStore.transactional(trx).addUserToGroups(
userId,
newGroups.map((g) => g.id),
);
let oldGroups = await this.groupStore
.transactional(trx)
.getOldGroupsForExternalUser(userId, externalGroups);
await this.groupStore
.transactional(trx)
.deleteUsersFromGroup(oldGroups);
});
}
async getGroupsForUser(userId: number): Promise<IGroup[]> {

View File

@ -36,11 +36,13 @@ import EdgeService from './edge-service';
import PatService from './pat-service';
import { PublicSignupTokenService } from './public-signup-token-service';
import { LastSeenService } from './client-metrics/last-seen-service';
import { Knex } from 'knex';
export const createServices = (
stores: IUnleashStores,
config: IUnleashConfig,
db: Knex,
): IUnleashServices => {
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db);
const accessService = new AccessService(stores, config, groupService);
const apiTokenService = new ApiTokenService(stores, config);
const clientInstanceService = new ClientInstanceService(stores, config);

View File

@ -2,8 +2,12 @@ import { IBaseEvent, IEvent } from '../events';
import { Store } from './store';
import { SearchEventsSchema } from '../../openapi/spec/search-events-schema';
import EventEmitter from 'events';
import { Transactional } from './transactional';
export interface IEventStore extends Store<IEvent, number>, EventEmitter {
export interface IEventStore
extends Store<IEvent, number>,
Transactional<IEventStore>,
EventEmitter {
store(event: IBaseEvent): Promise<void>;
batchStore(events: IBaseEvent[]): Promise<void>;
getEvents(): Promise<IEvent[]>;

View File

@ -9,7 +9,7 @@ let db;
beforeAll(async () => {
db = await dbInit('addon_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -37,7 +37,7 @@ test('editor users should only get client tokens', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await stores.apiTokenStore.insert({
username: 'test',
@ -78,7 +78,7 @@ test('viewer users should not be allowed to fetch tokens', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await stores.apiTokenStore.insert({
username: 'test',
@ -114,7 +114,7 @@ test('Only token-admins should be allowed to create token', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await request
.post('/api/admin/api-tokens')
@ -142,7 +142,7 @@ test('Token-admin should be allowed to create token', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await request
.post('/api/admin/api-tokens')

View File

@ -9,7 +9,7 @@ let app;
beforeAll(async () => {
db = await dbInit('token_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('archive_test_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -9,7 +9,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('client_metrics_serial', getLogger);
app = await setupAppWithCustomConfig(db.stores, {});
app = await setupAppWithCustomConfig(db, {});
});
afterAll(async () => {

View File

@ -9,7 +9,7 @@ let app: IUnleashTest;
beforeAll(async () => {
db = await dbInit('config_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -9,7 +9,7 @@ const PATH = '/api/admin/constraints/validate';
beforeAll(async () => {
db = await dbInit('constraints', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let app;
beforeAll(async () => {
db = await dbInit('context_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -8,7 +8,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('environment_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -11,7 +11,7 @@ let eventStore: IEventStore;
beforeAll(async () => {
db = await dbInit('event_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
eventStore = db.stores.eventStore;
});

View File

@ -7,7 +7,7 @@ let db;
beforeAll(async () => {
db = await dbInit('archive_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
await app.services.featureToggleServiceV2.createFeatureToggle(
'default',
{

View File

@ -9,7 +9,7 @@ let db;
beforeAll(async () => {
db = await dbInit('feature_type_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -15,7 +15,7 @@ afterAll(async () => {
test('creates new feature toggle with createdBy', async () => {
expect.assertions(1);
const { request, destroy } = await setupAppWithAuth(db.stores);
const { request, destroy } = await setupAppWithAuth(db);
// Login
await request.post('/auth/demo/login').send({
@ -41,7 +41,7 @@ test('creates new feature toggle with createdBy', async () => {
test('should require authenticated user', async () => {
expect.assertions(0);
const { request, destroy } = await setupAppWithAuth(db.stores);
const { request, destroy } = await setupAppWithAuth(db);
await request.get('/api/admin/features').expect(401);
await destroy();
});

View File

@ -4,12 +4,10 @@ import AuthenticationRequired from '../../../../lib/types/authentication-require
import dbInit from '../../helpers/database-init';
import getLogger from '../../../fixtures/no-logger';
let stores;
let db;
beforeAll(async () => {
db = await dbInit('feature_api_custom_auth', getLogger);
stores = db.stores;
});
afterAll(async () => {
@ -34,7 +32,7 @@ test('should require authenticated user', async () => {
.end(),
);
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await request.get('/api/admin/features').expect(401);
await destroy();
});
@ -49,7 +47,7 @@ test('creates new feature toggle with createdBy', async () => {
next();
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
// create toggle
await request

View File

@ -24,7 +24,7 @@ const defaultStrategy = {
beforeAll(async () => {
db = await dbInit('feature_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
const createToggle = async (
toggle: FeatureToggleDTO,
@ -770,12 +770,9 @@ test('marks feature toggle as stale', async () => {
});
test('should not hit endpoints if disable configuration is set', async () => {
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(
db.stores,
{
disableLegacyFeaturesApi: true,
},
);
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(db, {
disableLegacyFeaturesApi: true,
});
await appWithDisabledLegacyFeatures.request
.get('/api/admin/features/featureX')
@ -789,12 +786,9 @@ test('should not hit endpoints if disable configuration is set', async () => {
});
test('should hit validate and tags endpoint if legacy api is disabled', async () => {
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(
db.stores,
{
disableLegacyFeaturesApi: true,
},
);
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(db, {
disableLegacyFeaturesApi: true,
});
const feature = {
name: 'test.feature.disabled.api',
@ -826,12 +820,9 @@ test('should hit validate and tags endpoint if legacy api is disabled', async ()
});
test('should have access to the get all features endpoint even if api is disabled', async () => {
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(
db.stores,
{
disableLegacyFeaturesApi: true,
},
);
const appWithDisabledLegacyFeatures = await setupAppWithCustomConfig(db, {
disableLegacyFeaturesApi: true,
});
await appWithDisabledLegacyFeatures.request
.get('/api/admin/features')

View File

@ -5,13 +5,11 @@ import getLogger from '../../../fixtures/no-logger';
import { IUnleashConfig } from '../../../../lib/types/option';
import { IUnleashServices } from '../../../../lib/types/services';
let stores;
let db;
let app;
beforeAll(async () => {
db = await dbInit('feedback_api_serial', getLogger);
stores = db.stores;
const email = 'custom-user@mail.com';
@ -33,7 +31,7 @@ beforeAll(async () => {
);
};
app = await setupAppWithCustomAuth(stores, preHook);
app = await setupAppWithCustomAuth(db, preHook);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('metrics_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
beforeEach(async () => {

View File

@ -21,7 +21,7 @@ let token: IApiToken;
beforeAll(async () => {
db = await dbInit('playground_api_serial', getLogger);
app = await setupAppWithAuth(db.stores);
app = await setupAppWithAuth(db);
const { apiTokenService } = app.services;
token = await apiTokenService.createApiTokenWithProjects({
type: ApiTokenType.ADMIN,

View File

@ -8,7 +8,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('project_environments_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterEach(async () => {

View File

@ -10,7 +10,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('feature_strategy_auth_api_serial', getLogger);
app = await setupAppWithAuth(db.stores);
app = await setupAppWithAuth(db);
});
afterEach(async () => {

View File

@ -26,7 +26,7 @@ const sortOrderDefault = 9999;
beforeAll(async () => {
db = await dbInit('feature_strategy_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterEach(async () => {

View File

@ -8,7 +8,7 @@ let user;
beforeAll(async () => {
db = await dbInit('project_health_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
user = await db.stores.userStore.insert({
name: 'Some Name',
email: 'test@getunleash.io',

View File

@ -10,7 +10,7 @@ let projectStore: ProjectStore;
beforeAll(async () => {
db = await dbInit('projects_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
projectStore = db.stores.projectStore;
});

View File

@ -9,7 +9,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('project_feature_variants_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -54,7 +54,7 @@ test('admin users should be able to create a token', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
const tokenCreate: PublicSignupTokenCreateSchema = {
name: 'some-name',
@ -88,7 +88,7 @@ test('no permission to validate a token', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await stores.publicSignupTokenStore.insert({
name: 'some-name',
@ -116,7 +116,7 @@ test('should return 400 if token can not be validate', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await request.get('/invite/some-invalid-secret/validate').expect(400);
@ -138,7 +138,7 @@ test('users can signup with invite-link', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await stores.publicSignupTokenStore.insert({
name: 'some-name',
@ -183,7 +183,7 @@ test('can get a token with users', async () => {
});
};
const { request, destroy } = await setupAppWithCustomAuth(stores, preHook);
const { request, destroy } = await setupAppWithCustomAuth(db, preHook);
await stores.publicSignupTokenStore.insert({
name: 'some-name',

View File

@ -5,13 +5,11 @@ import getLogger from '../../../fixtures/no-logger';
import { IUnleashConfig } from '../../../../lib/types/option';
import { IUnleashServices } from '../../../../lib/types/services';
let stores;
let db;
let app;
beforeAll(async () => {
db = await dbInit('splash_api_serial', getLogger);
stores = db.stores;
const email = 'custom-user@mail.com';
@ -33,7 +31,7 @@ beforeAll(async () => {
);
};
app = await setupAppWithCustomAuth(stores, preHook);
app = await setupAppWithCustomAuth(db, preHook);
});
afterAll(async () => {

View File

@ -12,7 +12,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('state_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let db;
beforeAll(async () => {
db = await dbInit('strategy_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let db;
beforeAll(async () => {
db = await dbInit('tag_types_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -7,7 +7,7 @@ let db;
beforeAll(async () => {
db = await dbInit('tag_api_serial', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -29,7 +29,7 @@ let adminRole: IRole;
beforeAll(async () => {
db = await dbInit('user_admin_api_serial', getLogger);
stores = db.stores;
app = await setupApp(stores);
app = await setupApp(db);
userStore = stores.userStore;
eventStore = stores.eventStore;
@ -278,7 +278,7 @@ test('Creates a user and includes inviteLink and emailConfigured', async () => {
});
test('Creates a user but does not send email if sendEmail is set to false', async () => {
const myAppConfig = await setupAppWithCustomConfig(stores, {
const myAppConfig = await setupAppWithCustomConfig(db, {
email: {
host: 'smtp.ethereal.email',
smtpuser: 'rafaela.pouros@ethereal.email',

View File

@ -16,7 +16,7 @@ tomorrow.setDate(tomorrow.getDate() + 1);
beforeAll(async () => {
db = await dbInit('user_pat', getLogger);
patStore = db.stores.patStore;
app = await setupAppWithAuth(db.stores, {
app = await setupAppWithAuth(db, {
experimental: { flags: { personalAccessTokens: true } },
});

View File

@ -9,7 +9,7 @@ const email = 'user@getunleash.io';
beforeAll(async () => {
db = await dbInit('user_api_serial', getLogger);
app = await setupAppWithAuth(db.stores);
app = await setupAppWithAuth(db);
});
afterAll(async () => {

View File

@ -48,8 +48,8 @@ const getBackendResetUrl = (url: URL): string => {
beforeAll(async () => {
db = await dbInit('reset_password_api_serial', getLogger);
stores = db.stores;
app = await setupApp(stores);
const groupService = new GroupService(stores, config);
app = await setupApp(db);
const groupService = new GroupService(stores, config, db.db);
accessService = new AccessService(stores, config, groupService);
const emailService = new EmailService(config.email, config.getLogger);
const sessionStore = new SessionStore(
@ -181,7 +181,7 @@ test('Invalid token should yield 401', async () =>
test('Calling validate endpoint with already existing session should destroy session', async () => {
expect.assertions(0);
const { request, destroy } = await setupAppWithAuth(stores);
const { request, destroy } = await setupAppWithAuth(db);
await request
.post('/auth/demo/login')
.send({
@ -202,7 +202,7 @@ test('Calling validate endpoint with already existing session should destroy ses
test('Calling reset endpoint with already existing session should logout/destroy existing session', async () => {
expect.assertions(0);
const { request, destroy } = await setupAppWithAuth(stores);
const { request, destroy } = await setupAppWithAuth(db);
const url = await resetTokenService.createResetPasswordUrl(
user.id,
adminUser.username,

View File

@ -33,8 +33,8 @@ let adminUser: IUser;
beforeAll(async () => {
db = await dbInit('simple_password_provider_api_serial', getLogger);
stores = db.stores;
app = await setupApp(stores);
const groupService = new GroupService(stores, config);
app = await setupApp(db);
const groupService = new GroupService(stores, config, db.db);
const accessService = new AccessService(stores, config, groupService);
const resetTokenService = new ResetTokenService(stores, config);
const emailService = new EmailService(undefined, config.getLogger);

View File

@ -8,7 +8,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('feature_api_client', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
await app.services.featureToggleServiceV2.createFeatureToggle(
'default',
{

View File

@ -12,7 +12,7 @@ const projectId = 'default';
beforeAll(async () => {
db = await dbInit('feature_env_api_client', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
await app.services.featureToggleServiceV2.createFeatureToggle(
projectId,

View File

@ -20,7 +20,7 @@ const feature3 = 'f3.p2.token.access';
beforeAll(async () => {
db = await dbInit('feature_api_api_access_client', getLogger);
app = await setupAppWithAuth(db.stores);
app = await setupAppWithAuth(db);
apiTokenService = app.services.apiTokenService;
const { featureToggleServiceV2, environmentService } = app.services;

View File

@ -9,7 +9,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('metrics_api_e2e_access_client', getLogger);
app = await setupAppWithAuth(db.stores);
app = await setupAppWithAuth(db);
});
afterAll(async () => {

View File

@ -8,7 +8,7 @@ let db;
beforeAll(async () => {
db = await dbInit('metrics_api_client', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -11,7 +11,7 @@ let defaultToken;
beforeAll(async () => {
db = await dbInit('metrics_two_api_client', getLogger);
app = await setupAppWithAuth(db.stores, {});
app = await setupAppWithAuth(db, {});
defaultToken = await app.services.apiTokenService.createApiToken({
type: ApiTokenType.CLIENT,
project: 'default',

View File

@ -15,7 +15,7 @@ let db;
beforeAll(async () => {
db = await dbInit('register_client', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -115,7 +115,7 @@ const createTestSegments = async () => {
beforeAll(async () => {
db = await dbInit('segments', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -11,7 +11,7 @@ let db;
beforeAll(async () => {
db = await dbInit('openapi', getLogger);
app = await setupApp(db.stores);
app = await setupApp(db);
});
afterAll(async () => {

View File

@ -16,7 +16,7 @@ let db: ITestDb;
beforeAll(async () => {
db = await dbInit('proxy', getLogger);
app = await setupAppWithAuth(db.stores, {
app = await setupAppWithAuth(db, {
frontendApiOrigins: ['https://example.com'],
});
});

View File

@ -2,19 +2,14 @@ import dbInit from './helpers/database-init';
import { setupAppWithCustomAuth } from './helpers/test-helper';
let db;
let stores;
beforeAll(async () => {
db = await dbInit('custom_auth_serial');
stores = db.stores;
});
test('Using custom auth type without defining custom middleware causes default DENY ALL policy to take effect', async () => {
jest.spyOn(global.console, 'error').mockImplementation(() => jest.fn());
const { request, destroy } = await setupAppWithCustomAuth(
stores,
undefined,
);
const { request, destroy } = await setupAppWithCustomAuth(db, undefined);
await request
.get('/api/admin/features')
.expect(401)
@ -28,7 +23,7 @@ test('Using custom auth type without defining custom middleware causes default D
test('If actually configuring a custom middleware should configure the middleware', async () => {
expect.assertions(0);
const { request, destroy } = await setupAppWithCustomAuth(stores, () => {});
const { request, destroy } = await setupAppWithCustomAuth(db, () => {});
await request.get('/api/admin/features').expect(200);
await destroy();
});

View File

@ -2,12 +2,10 @@ import { setupApp } from './helpers/test-helper';
import dbInit from './helpers/database-init';
import getLogger from '../fixtures/no-logger';
let stores;
let db;
beforeAll(async () => {
db = await dbInit('health_api', getLogger);
stores = db.stores;
});
afterAll(async () => {
@ -16,7 +14,7 @@ afterAll(async () => {
test('returns health good', async () => {
expect.assertions(0);
const { request, destroy } = await setupApp(stores);
const { request, destroy } = await setupApp(db);
await request
.get('/health')
.expect('Content-Type', /json/)

View File

@ -7,8 +7,8 @@ import { createTestConfig } from '../../config/test-config';
import { IAuthType } from '../../../lib/types/option';
import { createServices } from '../../../lib/services';
import sessionDb from '../../../lib/middleware/session-db';
import { IUnleashStores } from '../../../lib/types';
import { IUnleashServices } from '../../../lib/types/services';
import { ITestDb } from './database-init';
process.env.NODE_ENV = 'test';
@ -19,7 +19,7 @@ export interface IUnleashTest {
}
async function createApp(
stores,
db: ITestDb,
adminAuthentication = IAuthType.NONE,
preHook?: Function,
customOptions?: any,
@ -34,11 +34,11 @@ async function createApp(
},
...customOptions,
});
const services = createServices(stores, config);
const services = createServices(db.stores, config, db.db);
const unleashSession = sessionDb(config, undefined);
const emitter = new EventEmitter();
emitter.setMaxListeners(0);
const app = await getApp(config, stores, services, unleashSession);
const app = await getApp(config, db.stores, services, unleashSession);
const request = supertest.agent(app);
const destroy = async () => {
@ -52,34 +52,32 @@ async function createApp(
return { request, destroy, services };
}
export async function setupApp(stores: IUnleashStores): Promise<IUnleashTest> {
return createApp(stores);
export async function setupApp(db: ITestDb): Promise<IUnleashTest> {
return createApp(db);
}
export async function setupAppWithCustomConfig(
stores: IUnleashStores,
db: ITestDb,
customOptions: any,
): Promise<IUnleashTest> {
return createApp(stores, undefined, undefined, customOptions);
return createApp(db, undefined, undefined, customOptions);
}
export async function setupAppWithAuth(
stores: IUnleashStores,
db: ITestDb,
customOptions?: any,
): Promise<IUnleashTest> {
return createApp(stores, IAuthType.DEMO, undefined, customOptions);
return createApp(db, IAuthType.DEMO, undefined, customOptions);
}
export async function setupAppWithCustomAuth(
stores: IUnleashStores,
db: ITestDb,
preHook: Function,
): Promise<IUnleashTest> {
return createApp(stores, IAuthType.CUSTOM, preHook);
return createApp(db, IAuthType.CUSTOM, preHook);
}
export async function setupAppWithBaseUrl(
stores: IUnleashStores,
): Promise<IUnleashTest> {
return createApp(stores, undefined, undefined, {
export async function setupAppWithBaseUrl(db: ITestDb): Promise<IUnleashTest> {
return createApp(db, undefined, undefined, {
server: {
unleashUrl: 'http://localhost:4242',
basePathUri: '/hosted',

View File

@ -7,7 +7,7 @@ let app;
beforeAll(async () => {
db = await dbInit('routes_test_serial');
app = await setupAppWithBaseUrl(db.stores);
app = await setupAppWithBaseUrl(db);
});
afterAll(async () => {

View File

@ -139,7 +139,7 @@ const seedSegmentsDatabase = async (
const main = async (): Promise<void> => {
const db = await dbInit(seedSchema, getLogger);
const app = await setupApp(db.stores);
const app = await setupApp(db);
await seedSegmentsDatabase(app, seedSegmentSpec);
await app.destroy();

View File

@ -208,7 +208,7 @@ beforeAll(async () => {
// @ts-ignore
experimental: { environments: { enabled: true } },
});
groupService = new GroupService(stores, { getLogger });
groupService = new GroupService(stores, { getLogger }, db.db);
accessService = new AccessService(stores, { getLogger }, groupService);
const roles = await accessService.getRootRoles();
editorRole = roles.find((r) => r.name === RoleName.EDITOR);

View File

@ -22,7 +22,7 @@ beforeAll(async () => {
});
db = await dbInit('api_token_service_serial', getLogger);
stores = db.stores;
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db.db);
const accessService = new AccessService(stores, config, groupService);
const featureToggleService = new FeatureToggleService(
stores,

View File

@ -30,7 +30,7 @@ beforeAll(async () => {
);
stores = db.stores;
segmentService = new SegmentService(stores, config);
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db.db);
const accessService = new AccessService(stores, config, groupService);
service = new FeatureToggleService(
stores,

View File

@ -19,7 +19,7 @@ beforeAll(async () => {
const config = createTestConfig({
getLogger,
});
groupService = new GroupService(stores, config);
groupService = new GroupService(stores, config, db.db);
await stores.groupStore.create({
name: 'dev_group',

View File

@ -32,7 +32,7 @@ beforeAll(async () => {
db = await dbInit('playground_service_serial', config.getLogger);
stores = db.stores;
segmentService = new SegmentService(stores, config);
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db.db);
const accessService = new AccessService(stores, config, groupService);
featureToggleService = new FeatureToggleService(
stores,

View File

@ -27,7 +27,7 @@ beforeAll(async () => {
name: 'Some Name',
email: 'test@getunleash.io',
});
groupService = new GroupService(stores, config);
groupService = new GroupService(stores, config, db.db);
accessService = new AccessService(stores, config, groupService);
featureToggleService = new FeatureToggleService(
stores,

View File

@ -34,7 +34,7 @@ beforeAll(async () => {
// @ts-ignore
experimental: { environments: { enabled: true } },
});
groupService = new GroupService(stores, config);
groupService = new GroupService(stores, config, db.db);
accessService = new AccessService(stores, config, groupService);
featureToggleService = new FeatureToggleService(
stores,

View File

@ -28,7 +28,7 @@ let sessionService: SessionService;
beforeAll(async () => {
db = await dbInit('reset_token_service_serial', getLogger);
stores = db.stores;
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db);
accessService = new AccessService(stores, config, groupService);
resetTokenService = new ResetTokenService(stores, config);
sessionService = new SessionService(stores, config);

View File

@ -29,7 +29,7 @@ beforeAll(async () => {
db = await dbInit('user_service_serial', getLogger);
stores = db.stores;
const config = createTestConfig();
const groupService = new GroupService(stores, config);
const groupService = new GroupService(stores, config, db);
const accessService = new AccessService(stores, config, groupService);
const resetTokenService = new ResetTokenService(stores, config);
const emailService = new EmailService(undefined, config.getLogger);

View File

@ -1,6 +1,7 @@
import { IEventStore } from '../../lib/types/stores/event-store';
import { IEvent } from '../../lib/types/events';
import { AnyEventEmitter } from '../../lib/util/anyEventEmitter';
import { Knex } from 'knex';
class FakeEventStore extends AnyEventEmitter implements IEventStore {
events: IEvent[];
@ -65,6 +66,11 @@ class FakeEventStore extends AnyEventEmitter implements IEventStore {
async searchEvents(): Promise<IEvent[]> {
throw new Error('Method not implemented.');
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
transactional(transaction: Knex.Transaction<any, any[]>): IEventStore {
throw new Error('Method not implemented.');
}
}
module.exports = FakeEventStore;