diff --git a/src/lib/db/environment-store.ts b/src/lib/db/environment-store.ts index fcfbf57081..ca000b1e86 100644 --- a/src/lib/db/environment-store.ts +++ b/src/lib/db/environment-store.ts @@ -91,10 +91,14 @@ export default class EnvironmentStore implements IEnvironmentStore { throw new NotFoundError(`Could not find environment with name: ${key}`); } - async getAll(): Promise { - const rows = await this.db(TABLE) + async getAll(query?: Object): Promise { + let qB = this.db(TABLE) .select('*') .orderBy('sort_order', 'created_at'); + if (query) { + qB = qB.where(query); + } + const rows = await qB; return rows.map(mapRow); } diff --git a/src/lib/services/project-service.ts b/src/lib/services/project-service.ts index 7006c8100d..0750215ce4 100644 --- a/src/lib/services/project-service.ts +++ b/src/lib/services/project-service.ts @@ -30,7 +30,6 @@ import { IEventStore } from '../types/stores/event-store'; import FeatureToggleServiceV2 from './feature-toggle-service-v2'; import { CREATE_FEATURE, UPDATE_FEATURE } from '../types/permissions'; import NoAccessError from '../error/no-access-error'; -import { DEFAULT_ENV } from '../util/constants'; const getCreatedBy = (user: User) => user.email || user.username; @@ -123,8 +122,17 @@ export default class ProjectService { await this.store.create(data); - // TODO: we should only connect to enabled environments - await this.featureEnvironmentStore.connectProject(DEFAULT_ENV, data.id); + const enabledEnvironments = await this.environmentStore.getAll({ + enabled: true, + }); + await Promise.all( + enabledEnvironments.map(async (e) => { + await this.featureEnvironmentStore.connectProject( + e.name, + data.id, + ); + }), + ); await this.accessService.createDefaultProjectRoles(user, data.id); diff --git a/src/lib/types/model.ts b/src/lib/types/model.ts index f0eb7ad509..593520088b 100644 --- a/src/lib/types/model.ts +++ b/src/lib/types/model.ts @@ -113,6 +113,7 @@ export interface IEnvironmentCreate { name: string; type: string; sortOrder?: number; + enabled?: boolean; } export interface IEnvironmentOverview { diff --git a/src/migrations/20210928080601-add-development-and-production-environments.js b/src/migrations/20210928080601-add-development-and-production-environments.js new file mode 100644 index 0000000000..e7769a0dd5 --- /dev/null +++ b/src/migrations/20210928080601-add-development-and-production-environments.js @@ -0,0 +1,23 @@ +'use strict'; + +exports.up = function (db, cb) { + db.runSql( + ` + INSERT INTO environments(name, type, enabled) + VALUES ('development', 'development', true), + ('production', 'production', true); + `, + cb, + ); +}; + +exports.down = function (db, cb) { + db.runSql( + ` + DELETE + FROM environments + WHERE name IN ('development', 'production'); + `, + cb, + ); +}; diff --git a/src/migrations/20210928082228-connect-default-environment-to-all-existing-projects.js b/src/migrations/20210928082228-connect-default-environment-to-all-existing-projects.js new file mode 100644 index 0000000000..3165b9dfe2 --- /dev/null +++ b/src/migrations/20210928082228-connect-default-environment-to-all-existing-projects.js @@ -0,0 +1,22 @@ +exports.up = function (db, cb) { + db.runSql( + ` + INSERT INTO project_environments(project_id, environment_name) + SELECT id, 'default' + FROM projects + ON CONFLICT DO NOTHING; + `, + cb, + ); +}; + +exports.down = function (db, cb) { + db.runSql( + ` + DELETE + FROM project_environments + WHERE environment_name = 'default'; + `, + cb, + ); +}; diff --git a/src/test/e2e/helpers/database.json b/src/test/e2e/helpers/database.json index fc6ea665fc..8430a289d4 100644 --- a/src/test/e2e/helpers/database.json +++ b/src/test/e2e/helpers/database.json @@ -31,6 +31,7 @@ { "name": "default", "type": "production", + "sortOrder": 1, "enabled": true, "protected": true diff --git a/src/test/e2e/services/project-service.e2e.test.ts b/src/test/e2e/services/project-service.e2e.test.ts index 0062b8f741..aad1cf5a24 100644 --- a/src/test/e2e/services/project-service.e2e.test.ts +++ b/src/test/e2e/services/project-service.e2e.test.ts @@ -132,7 +132,7 @@ test('should validate name, legal', async () => { expect(result).toBe(true); }); -test('should not be able to create exiting project', async () => { +test('should not be able to create existing project', async () => { const project = { id: 'test-delete', name: 'New project', @@ -510,3 +510,29 @@ test('should change project when checks pass', async () => { expect(updatedFeature.project).toBe(projectDestination.id); }); + +test('A newly created project only gets connected to enabled environments', async () => { + const project = { + id: 'environment-test', + name: 'New environment project', + description: 'Blah', + }; + const enabledEnv = 'connection_test'; + await db.stores.environmentStore.create({ + name: enabledEnv, + type: 'test', + }); + const disabledEnv = 'do_not_connect'; + await db.stores.environmentStore.create({ + name: disabledEnv, + type: 'test', + enabled: false, + }); + + await projectService.createProject(project, user); + const connectedEnvs = + await db.stores.projectStore.getEnvironmentsForProject(project.id); + expect(connectedEnvs).toHaveLength(2); // default, connection_test + expect(connectedEnvs.some((e) => e === enabledEnv)).toBeTruthy(); + expect(connectedEnvs.some((e) => e === disabledEnv)).toBeFalsy(); +});