diff --git a/src/lib/db/event-store.ts b/src/lib/db/event-store.ts index 33e0650cf3..58d70fe14a 100644 --- a/src/lib/db/event-store.ts +++ b/src/lib/db/event-store.ts @@ -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 +{ 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; diff --git a/src/lib/middleware/oss-authentication.test.ts b/src/lib/middleware/oss-authentication.test.ts index 162e842672..5eb95a6fc8 100644 --- a/src/lib/middleware/oss-authentication.test.ts +++ b/src/lib/middleware/oss-authentication.test.ts @@ -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); diff --git a/src/lib/routes/admin-api/config.test.ts b/src/lib/routes/admin-api/config.test.ts index 16849a5ab5..4c38117d05 100644 --- a/src/lib/routes/admin-api/config.test.ts +++ b/src/lib/routes/admin-api/config.test.ts @@ -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); diff --git a/src/lib/routes/admin-api/context.test.ts b/src/lib/routes/admin-api/context.test.ts index fcb8683b91..a25551e593 100644 --- a/src/lib/routes/admin-api/context.test.ts +++ b/src/lib/routes/admin-api/context.test.ts @@ -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 { diff --git a/src/lib/routes/admin-api/email.test.ts b/src/lib/routes/admin-api/email.test.ts index ae1d39ac81..b8e08f84b6 100644 --- a/src/lib/routes/admin-api/email.test.ts +++ b/src/lib/routes/admin-api/email.test.ts @@ -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 { diff --git a/src/lib/routes/admin-api/events.test.ts b/src/lib/routes/admin-api/events.test.ts index 526cda2589..3ecf7bff66 100644 --- a/src/lib/routes/admin-api/events.test.ts +++ b/src/lib/routes/admin-api/events.test.ts @@ -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) }; diff --git a/src/lib/routes/admin-api/metrics.test.ts b/src/lib/routes/admin-api/metrics.test.ts index 27063b6283..62b4b7e447 100644 --- a/src/lib/routes/admin-api/metrics.test.ts +++ b/src/lib/routes/admin-api/metrics.test.ts @@ -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 { diff --git a/src/lib/routes/admin-api/playground.test.ts b/src/lib/routes/admin-api/playground.test.ts index da594a5065..b330edc223 100644 --- a/src/lib/routes/admin-api/playground.test.ts +++ b/src/lib/routes/admin-api/playground.test.ts @@ -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) }; } diff --git a/src/lib/routes/admin-api/public-signup.test.ts b/src/lib/routes/admin-api/public-signup.test.ts index 945f36711e..c79fec0f0a 100644 --- a/src/lib/routes/admin-api/public-signup.test.ts +++ b/src/lib/routes/admin-api/public-signup.test.ts @@ -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({ diff --git a/src/lib/routes/admin-api/strategy.test.ts b/src/lib/routes/admin-api/strategy.test.ts index 6f154053e8..5ac74dc880 100644 --- a/src/lib/routes/admin-api/strategy.test.ts +++ b/src/lib/routes/admin-api/strategy.test.ts @@ -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 = () => { diff --git a/src/lib/routes/admin-api/tag.test.ts b/src/lib/routes/admin-api/tag.test.ts index 229703efdd..48b88d0162 100644 --- a/src/lib/routes/admin-api/tag.test.ts +++ b/src/lib/routes/admin-api/tag.test.ts @@ -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 { diff --git a/src/lib/routes/admin-api/user/user.test.ts b/src/lib/routes/admin-api/user/user.test.ts index 313448c361..ee6b004b68 100644 --- a/src/lib/routes/admin-api/user/user.test.ts +++ b/src/lib/routes/admin-api/user/user.test.ts @@ -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, diff --git a/src/lib/routes/backstage.test.ts b/src/lib/routes/backstage.test.ts index 858b1b9118..76b5f0fd81 100644 --- a/src/lib/routes/backstage.test.ts +++ b/src/lib/routes/backstage.test.ts @@ -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); diff --git a/src/lib/routes/client-api/feature.test.ts b/src/lib/routes/client-api/feature.test.ts index 9519226207..709b506433 100644 --- a/src/lib/routes/client-api/feature.test.ts +++ b/src/lib/routes/client-api/feature.test.ts @@ -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); diff --git a/src/lib/routes/client-api/metrics.test.ts b/src/lib/routes/client-api/metrics.test.ts index a0568c4bd4..10648a279e 100644 --- a/src/lib/routes/client-api/metrics.test.ts +++ b/src/lib/routes/client-api/metrics.test.ts @@ -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 { diff --git a/src/lib/routes/client-api/register.test.ts b/src/lib/routes/client-api/register.test.ts index 3cf08b7029..a937eb5f6b 100644 --- a/src/lib/routes/client-api/register.test.ts +++ b/src/lib/routes/client-api/register.test.ts @@ -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 { diff --git a/src/lib/routes/health-check.test.ts b/src/lib/routes/health-check.test.ts index 8378da8083..e27acbef62 100644 --- a/src/lib/routes/health-check.test.ts +++ b/src/lib/routes/health-check.test.ts @@ -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 { diff --git a/src/lib/routes/public-invite.test.ts b/src/lib/routes/public-invite.test.ts index 1e4412394f..66e0d44804 100644 --- a/src/lib/routes/public-invite.test.ts +++ b/src/lib/routes/public-invite.test.ts @@ -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({ diff --git a/src/lib/server-impl.ts b/src/lib/server-impl.ts index 04c5422ca1..ad06077e41 100644 --- a/src/lib/server-impl.ts +++ b/src/lib/server-impl.ts @@ -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); diff --git a/src/lib/services/group-service.ts b/src/lib/services/group-service.ts index 8fcc11a54d..d12ef67382 100644 --- a/src/lib/services/group-service.ts +++ b/src/lib/services/group-service.ts @@ -30,13 +30,14 @@ export class GroupService { constructor( stores: Pick, - { getLogger }: Pick, // db: Knex, + { getLogger }: Pick, + 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 { @@ -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 { - 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 { diff --git a/src/lib/services/index.ts b/src/lib/services/index.ts index be559687a3..df4ab2ecd7 100644 --- a/src/lib/services/index.ts +++ b/src/lib/services/index.ts @@ -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); diff --git a/src/lib/types/stores/event-store.ts b/src/lib/types/stores/event-store.ts index 516783b7e0..405acad35f 100644 --- a/src/lib/types/stores/event-store.ts +++ b/src/lib/types/stores/event-store.ts @@ -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, EventEmitter { +export interface IEventStore + extends Store, + Transactional, + EventEmitter { store(event: IBaseEvent): Promise; batchStore(events: IBaseEvent[]): Promise; getEvents(): Promise; diff --git a/src/test/e2e/api/admin/addon.e2e.test.ts b/src/test/e2e/api/admin/addon.e2e.test.ts index ea3628ea8c..e378d1efab 100644 --- a/src/test/e2e/api/admin/addon.e2e.test.ts +++ b/src/test/e2e/api/admin/addon.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/api-token.auth.e2e.test.ts b/src/test/e2e/api/admin/api-token.auth.e2e.test.ts index 0c1803e019..821cd09a46 100644 --- a/src/test/e2e/api/admin/api-token.auth.e2e.test.ts +++ b/src/test/e2e/api/admin/api-token.auth.e2e.test.ts @@ -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') diff --git a/src/test/e2e/api/admin/api-token.e2e.test.ts b/src/test/e2e/api/admin/api-token.e2e.test.ts index c71c3fb185..ef3b125128 100644 --- a/src/test/e2e/api/admin/api-token.e2e.test.ts +++ b/src/test/e2e/api/admin/api-token.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/archive.test.ts b/src/test/e2e/api/admin/archive.test.ts index 80f20a8504..6e015b330a 100644 --- a/src/test/e2e/api/admin/archive.test.ts +++ b/src/test/e2e/api/admin/archive.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/client-metrics.e2e.test.ts b/src/test/e2e/api/admin/client-metrics.e2e.test.ts index 2294cc5c9f..9c42983246 100644 --- a/src/test/e2e/api/admin/client-metrics.e2e.test.ts +++ b/src/test/e2e/api/admin/client-metrics.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/config.e2e.test.ts b/src/test/e2e/api/admin/config.e2e.test.ts index 4bf36e8812..42273bc29b 100644 --- a/src/test/e2e/api/admin/config.e2e.test.ts +++ b/src/test/e2e/api/admin/config.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/constraints.e2e.test.ts b/src/test/e2e/api/admin/constraints.e2e.test.ts index 11a30f17d5..cb0af10245 100644 --- a/src/test/e2e/api/admin/constraints.e2e.test.ts +++ b/src/test/e2e/api/admin/constraints.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/context.e2e.test.ts b/src/test/e2e/api/admin/context.e2e.test.ts index b8bd9d316f..90951306e7 100644 --- a/src/test/e2e/api/admin/context.e2e.test.ts +++ b/src/test/e2e/api/admin/context.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/environment.test.ts b/src/test/e2e/api/admin/environment.test.ts index 840396bb46..2e3df8bb4f 100644 --- a/src/test/e2e/api/admin/environment.test.ts +++ b/src/test/e2e/api/admin/environment.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/event.e2e.test.ts b/src/test/e2e/api/admin/event.e2e.test.ts index 055f599370..7a1c9b645d 100644 --- a/src/test/e2e/api/admin/event.e2e.test.ts +++ b/src/test/e2e/api/admin/event.e2e.test.ts @@ -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; }); diff --git a/src/test/e2e/api/admin/feature-archive.e2e.test.ts b/src/test/e2e/api/admin/feature-archive.e2e.test.ts index 3ea36a034c..6c05052811 100644 --- a/src/test/e2e/api/admin/feature-archive.e2e.test.ts +++ b/src/test/e2e/api/admin/feature-archive.e2e.test.ts @@ -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', { diff --git a/src/test/e2e/api/admin/feature-type.test.ts b/src/test/e2e/api/admin/feature-type.test.ts index 4ceb529a9a..24f2a2f163 100644 --- a/src/test/e2e/api/admin/feature-type.test.ts +++ b/src/test/e2e/api/admin/feature-type.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/feature.auth.e2e.test.ts b/src/test/e2e/api/admin/feature.auth.e2e.test.ts index 894bc143d0..a5ae10e90e 100644 --- a/src/test/e2e/api/admin/feature.auth.e2e.test.ts +++ b/src/test/e2e/api/admin/feature.auth.e2e.test.ts @@ -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(); }); diff --git a/src/test/e2e/api/admin/feature.custom-auth.e2e.test.ts b/src/test/e2e/api/admin/feature.custom-auth.e2e.test.ts index f51767033f..c1e2b3842d 100644 --- a/src/test/e2e/api/admin/feature.custom-auth.e2e.test.ts +++ b/src/test/e2e/api/admin/feature.custom-auth.e2e.test.ts @@ -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 diff --git a/src/test/e2e/api/admin/feature.e2e.test.ts b/src/test/e2e/api/admin/feature.e2e.test.ts index c31e73fd3f..0405c5c1fc 100644 --- a/src/test/e2e/api/admin/feature.e2e.test.ts +++ b/src/test/e2e/api/admin/feature.e2e.test.ts @@ -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') diff --git a/src/test/e2e/api/admin/feedback.e2e.test.ts b/src/test/e2e/api/admin/feedback.e2e.test.ts index 3596712437..cb2d126016 100644 --- a/src/test/e2e/api/admin/feedback.e2e.test.ts +++ b/src/test/e2e/api/admin/feedback.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/metrics.e2e.test.ts b/src/test/e2e/api/admin/metrics.e2e.test.ts index 7d859101f1..9ee8b7a9b5 100644 --- a/src/test/e2e/api/admin/metrics.e2e.test.ts +++ b/src/test/e2e/api/admin/metrics.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/playground.e2e.test.ts b/src/test/e2e/api/admin/playground.e2e.test.ts index 96d48e05d1..e7e19b85d2 100644 --- a/src/test/e2e/api/admin/playground.e2e.test.ts +++ b/src/test/e2e/api/admin/playground.e2e.test.ts @@ -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, diff --git a/src/test/e2e/api/admin/project/environments.e2e.test.ts b/src/test/e2e/api/admin/project/environments.e2e.test.ts index e1b96eb2bb..f19e780bea 100644 --- a/src/test/e2e/api/admin/project/environments.e2e.test.ts +++ b/src/test/e2e/api/admin/project/environments.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/project/features.auth.e2e.test.ts b/src/test/e2e/api/admin/project/features.auth.e2e.test.ts index afa29f0c7b..3d4542e068 100644 --- a/src/test/e2e/api/admin/project/features.auth.e2e.test.ts +++ b/src/test/e2e/api/admin/project/features.auth.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/project/features.e2e.test.ts b/src/test/e2e/api/admin/project/features.e2e.test.ts index d40d257747..121ea16ef4 100644 --- a/src/test/e2e/api/admin/project/features.e2e.test.ts +++ b/src/test/e2e/api/admin/project/features.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/project/project.health.e2e.test.ts b/src/test/e2e/api/admin/project/project.health.e2e.test.ts index f303329e12..65febcf926 100644 --- a/src/test/e2e/api/admin/project/project.health.e2e.test.ts +++ b/src/test/e2e/api/admin/project/project.health.e2e.test.ts @@ -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', diff --git a/src/test/e2e/api/admin/project/projects.e2e.test.ts b/src/test/e2e/api/admin/project/projects.e2e.test.ts index 9bbae4ccff..6d7785e1be 100644 --- a/src/test/e2e/api/admin/project/projects.e2e.test.ts +++ b/src/test/e2e/api/admin/project/projects.e2e.test.ts @@ -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; }); diff --git a/src/test/e2e/api/admin/project/variants.e2e.test.ts b/src/test/e2e/api/admin/project/variants.e2e.test.ts index 5044bea52e..e292449668 100644 --- a/src/test/e2e/api/admin/project/variants.e2e.test.ts +++ b/src/test/e2e/api/admin/project/variants.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/public-signup-token.e2e.test.ts b/src/test/e2e/api/admin/public-signup-token.e2e.test.ts index e14643e08e..2a51f8a1d2 100644 --- a/src/test/e2e/api/admin/public-signup-token.e2e.test.ts +++ b/src/test/e2e/api/admin/public-signup-token.e2e.test.ts @@ -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', diff --git a/src/test/e2e/api/admin/splash.e2e.test.ts b/src/test/e2e/api/admin/splash.e2e.test.ts index 61d0c6db26..ea00a34ac7 100644 --- a/src/test/e2e/api/admin/splash.e2e.test.ts +++ b/src/test/e2e/api/admin/splash.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/state.e2e.test.ts b/src/test/e2e/api/admin/state.e2e.test.ts index 7ccf1856c7..32cea9ecde 100644 --- a/src/test/e2e/api/admin/state.e2e.test.ts +++ b/src/test/e2e/api/admin/state.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/strategy.e2e.test.ts b/src/test/e2e/api/admin/strategy.e2e.test.ts index af1ee8d1a4..0746e0eddc 100644 --- a/src/test/e2e/api/admin/strategy.e2e.test.ts +++ b/src/test/e2e/api/admin/strategy.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/tag-types.e2e.test.ts b/src/test/e2e/api/admin/tag-types.e2e.test.ts index 18d1a45392..cfc3cdde71 100644 --- a/src/test/e2e/api/admin/tag-types.e2e.test.ts +++ b/src/test/e2e/api/admin/tag-types.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/tags.e2e.test.ts b/src/test/e2e/api/admin/tags.e2e.test.ts index adf122203d..e29e9109ae 100644 --- a/src/test/e2e/api/admin/tags.e2e.test.ts +++ b/src/test/e2e/api/admin/tags.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/admin/user-admin.e2e.test.ts b/src/test/e2e/api/admin/user-admin.e2e.test.ts index 224555f552..bf74a4464c 100644 --- a/src/test/e2e/api/admin/user-admin.e2e.test.ts +++ b/src/test/e2e/api/admin/user-admin.e2e.test.ts @@ -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', diff --git a/src/test/e2e/api/admin/user/pat.e2e.test.ts b/src/test/e2e/api/admin/user/pat.e2e.test.ts index 5c217593f6..81882486c5 100644 --- a/src/test/e2e/api/admin/user/pat.e2e.test.ts +++ b/src/test/e2e/api/admin/user/pat.e2e.test.ts @@ -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 } }, }); diff --git a/src/test/e2e/api/admin/user/user.test.ts b/src/test/e2e/api/admin/user/user.test.ts index 401af655bb..134bab6a7e 100644 --- a/src/test/e2e/api/admin/user/user.test.ts +++ b/src/test/e2e/api/admin/user/user.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts b/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts index 8a70ef9413..9e3767b96e 100644 --- a/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts +++ b/src/test/e2e/api/auth/reset-password-controller.e2e.test.ts @@ -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, diff --git a/src/test/e2e/api/auth/simple-password-provider.e2e.test.ts b/src/test/e2e/api/auth/simple-password-provider.e2e.test.ts index 0b09d8babb..5b44bcd044 100644 --- a/src/test/e2e/api/auth/simple-password-provider.e2e.test.ts +++ b/src/test/e2e/api/auth/simple-password-provider.e2e.test.ts @@ -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); diff --git a/src/test/e2e/api/client/feature.e2e.test.ts b/src/test/e2e/api/client/feature.e2e.test.ts index 69dd13290d..fc0814535a 100644 --- a/src/test/e2e/api/client/feature.e2e.test.ts +++ b/src/test/e2e/api/client/feature.e2e.test.ts @@ -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', { diff --git a/src/test/e2e/api/client/feature.env.disabled.e2e.test.ts b/src/test/e2e/api/client/feature.env.disabled.e2e.test.ts index 0eeac5eb03..f7bbea884b 100644 --- a/src/test/e2e/api/client/feature.env.disabled.e2e.test.ts +++ b/src/test/e2e/api/client/feature.env.disabled.e2e.test.ts @@ -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, diff --git a/src/test/e2e/api/client/feature.token.access.e2e.test.ts b/src/test/e2e/api/client/feature.token.access.e2e.test.ts index 29097cc92c..47bd1cb4e9 100644 --- a/src/test/e2e/api/client/feature.token.access.e2e.test.ts +++ b/src/test/e2e/api/client/feature.token.access.e2e.test.ts @@ -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; diff --git a/src/test/e2e/api/client/metrics.e2e.access.e2e.test.ts b/src/test/e2e/api/client/metrics.e2e.access.e2e.test.ts index e3f613b1c4..6b0c1406d3 100644 --- a/src/test/e2e/api/client/metrics.e2e.access.e2e.test.ts +++ b/src/test/e2e/api/client/metrics.e2e.access.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/client/metrics.e2e.test.ts b/src/test/e2e/api/client/metrics.e2e.test.ts index da9e7f07e8..76e338c3b8 100644 --- a/src/test/e2e/api/client/metrics.e2e.test.ts +++ b/src/test/e2e/api/client/metrics.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/client/metricsV2.e2e.test.ts b/src/test/e2e/api/client/metricsV2.e2e.test.ts index 6fabf4ca69..c60ed15598 100644 --- a/src/test/e2e/api/client/metricsV2.e2e.test.ts +++ b/src/test/e2e/api/client/metricsV2.e2e.test.ts @@ -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', diff --git a/src/test/e2e/api/client/register.e2e.test.ts b/src/test/e2e/api/client/register.e2e.test.ts index 3243c1fd09..284af8271b 100644 --- a/src/test/e2e/api/client/register.e2e.test.ts +++ b/src/test/e2e/api/client/register.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/client/segment.e2e.test.ts b/src/test/e2e/api/client/segment.e2e.test.ts index d1d1894550..786644e94b 100644 --- a/src/test/e2e/api/client/segment.e2e.test.ts +++ b/src/test/e2e/api/client/segment.e2e.test.ts @@ -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 () => { diff --git a/src/test/e2e/api/openapi/openapi.e2e.test.ts b/src/test/e2e/api/openapi/openapi.e2e.test.ts index 732d270156..78d10b377e 100644 --- a/src/test/e2e/api/openapi/openapi.e2e.test.ts +++ b/src/test/e2e/api/openapi/openapi.e2e.test.ts @@ -11,7 +11,7 @@ let db; beforeAll(async () => { db = await dbInit('openapi', getLogger); - app = await setupApp(db.stores); + app = await setupApp(db); }); afterAll(async () => { diff --git a/src/test/e2e/api/proxy/proxy.e2e.test.ts b/src/test/e2e/api/proxy/proxy.e2e.test.ts index a6f34c248c..6d5df517f4 100644 --- a/src/test/e2e/api/proxy/proxy.e2e.test.ts +++ b/src/test/e2e/api/proxy/proxy.e2e.test.ts @@ -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'], }); }); diff --git a/src/test/e2e/custom-auth.test.ts b/src/test/e2e/custom-auth.test.ts index 49e36e668f..0f600f359e 100644 --- a/src/test/e2e/custom-auth.test.ts +++ b/src/test/e2e/custom-auth.test.ts @@ -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(); }); diff --git a/src/test/e2e/health.e2e.test.ts b/src/test/e2e/health.e2e.test.ts index be6dcef476..20957539e7 100644 --- a/src/test/e2e/health.e2e.test.ts +++ b/src/test/e2e/health.e2e.test.ts @@ -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/) diff --git a/src/test/e2e/helpers/test-helper.ts b/src/test/e2e/helpers/test-helper.ts index 33b62b7c18..68c4cafa0f 100644 --- a/src/test/e2e/helpers/test-helper.ts +++ b/src/test/e2e/helpers/test-helper.ts @@ -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 { - return createApp(stores); +export async function setupApp(db: ITestDb): Promise { + return createApp(db); } export async function setupAppWithCustomConfig( - stores: IUnleashStores, + db: ITestDb, customOptions: any, ): Promise { - return createApp(stores, undefined, undefined, customOptions); + return createApp(db, undefined, undefined, customOptions); } export async function setupAppWithAuth( - stores: IUnleashStores, + db: ITestDb, customOptions?: any, ): Promise { - 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 { - return createApp(stores, IAuthType.CUSTOM, preHook); + return createApp(db, IAuthType.CUSTOM, preHook); } -export async function setupAppWithBaseUrl( - stores: IUnleashStores, -): Promise { - return createApp(stores, undefined, undefined, { +export async function setupAppWithBaseUrl(db: ITestDb): Promise { + return createApp(db, undefined, undefined, { server: { unleashUrl: 'http://localhost:4242', basePathUri: '/hosted', diff --git a/src/test/e2e/routes/routes.test.ts b/src/test/e2e/routes/routes.test.ts index 75bc95ad6a..04076881d2 100644 --- a/src/test/e2e/routes/routes.test.ts +++ b/src/test/e2e/routes/routes.test.ts @@ -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 () => { diff --git a/src/test/e2e/seed/segment.seed.ts b/src/test/e2e/seed/segment.seed.ts index 9bdf5e6f90..d186e973b2 100644 --- a/src/test/e2e/seed/segment.seed.ts +++ b/src/test/e2e/seed/segment.seed.ts @@ -139,7 +139,7 @@ const seedSegmentsDatabase = async ( const main = async (): Promise => { const db = await dbInit(seedSchema, getLogger); - const app = await setupApp(db.stores); + const app = await setupApp(db); await seedSegmentsDatabase(app, seedSegmentSpec); await app.destroy(); diff --git a/src/test/e2e/services/access-service.e2e.test.ts b/src/test/e2e/services/access-service.e2e.test.ts index 167a793f48..6158ed472f 100644 --- a/src/test/e2e/services/access-service.e2e.test.ts +++ b/src/test/e2e/services/access-service.e2e.test.ts @@ -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); diff --git a/src/test/e2e/services/api-token-service.e2e.test.ts b/src/test/e2e/services/api-token-service.e2e.test.ts index 67d6c2c8f3..38fc7626bd 100644 --- a/src/test/e2e/services/api-token-service.e2e.test.ts +++ b/src/test/e2e/services/api-token-service.e2e.test.ts @@ -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, diff --git a/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts b/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts index ba53d411e7..b1827967d5 100644 --- a/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts +++ b/src/test/e2e/services/feature-toggle-service-v2.e2e.test.ts @@ -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, diff --git a/src/test/e2e/services/group-service.e2e.test.ts b/src/test/e2e/services/group-service.e2e.test.ts index 18a3c6a128..32088e72e9 100644 --- a/src/test/e2e/services/group-service.e2e.test.ts +++ b/src/test/e2e/services/group-service.e2e.test.ts @@ -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', diff --git a/src/test/e2e/services/playground-service.test.ts b/src/test/e2e/services/playground-service.test.ts index 2c66fbf7ac..5d23719395 100644 --- a/src/test/e2e/services/playground-service.test.ts +++ b/src/test/e2e/services/playground-service.test.ts @@ -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, diff --git a/src/test/e2e/services/project-health-service.e2e.test.ts b/src/test/e2e/services/project-health-service.e2e.test.ts index d6155d7ce1..66111ce69e 100644 --- a/src/test/e2e/services/project-health-service.e2e.test.ts +++ b/src/test/e2e/services/project-health-service.e2e.test.ts @@ -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, diff --git a/src/test/e2e/services/project-service.e2e.test.ts b/src/test/e2e/services/project-service.e2e.test.ts index 89ece175f9..eda41b875d 100644 --- a/src/test/e2e/services/project-service.e2e.test.ts +++ b/src/test/e2e/services/project-service.e2e.test.ts @@ -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, diff --git a/src/test/e2e/services/reset-token-service.e2e.test.ts b/src/test/e2e/services/reset-token-service.e2e.test.ts index a10fc8c421..ec28c05c4c 100644 --- a/src/test/e2e/services/reset-token-service.e2e.test.ts +++ b/src/test/e2e/services/reset-token-service.e2e.test.ts @@ -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); diff --git a/src/test/e2e/services/user-service.e2e.test.ts b/src/test/e2e/services/user-service.e2e.test.ts index 62ae96b4e9..e1cd028920 100644 --- a/src/test/e2e/services/user-service.e2e.test.ts +++ b/src/test/e2e/services/user-service.e2e.test.ts @@ -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); diff --git a/src/test/fixtures/fake-event-store.ts b/src/test/fixtures/fake-event-store.ts index 1feb298dc4..3c9d653e17 100644 --- a/src/test/fixtures/fake-event-store.ts +++ b/src/test/fixtures/fake-event-store.ts @@ -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 { throw new Error('Method not implemented.'); } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + transactional(transaction: Knex.Transaction): IEventStore { + throw new Error('Method not implemented.'); + } } module.exports = FakeEventStore;