1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-08-27 13:49:10 +02:00

Merge remote-tracking branch 'origin/4.22' into v4

# Conflicts:
#	.github/workflows/e2e.frontend.yaml
#	frontend/cypress/integration/projects/notifications.spec.ts
#	frontend/cypress/integration/projects/settings.spec.ts
#	frontend/src/component/feature/StrategyTypes/FlexibleStrategy/StickinessSelect/StickinessSelect.tsx
#	frontend/src/interfaces/uiConfig.ts
#	package.json
#	src/lib/__snapshots__/create-config.test.ts.snap
#	src/lib/types/experimental.ts
This commit is contained in:
andreas-unleash 2023-04-26 17:25:43 +03:00
commit 2d2f158bfd
No known key found for this signature in database
GPG Key ID: DB82A1577B38F66B
7 changed files with 127 additions and 9 deletions

View File

@ -132,7 +132,6 @@
"pkginfo": "^0.4.1",
"prom-client": "^14.0.0",
"response-time": "^2.3.2",
"sanitize-filename": "^1.6.3",
"semver": "^7.3.5",
"serve-favicon": "^2.5.0",
"stoppable": "^1.1.0",

View File

@ -228,6 +228,16 @@ class FeatureToggleService {
'You can not change the featureName for an activation strategy.',
);
}
if (
strategy.parameters &&
'stickiness' in strategy.parameters &&
strategy.parameters.stickiness === ''
) {
throw new InvalidOperationError(
'You can not have an empty string for stickiness.',
);
}
}
async validateProjectCanAccessSegments(
@ -413,6 +423,14 @@ class FeatureToggleService {
);
}
if (
strategyConfig.parameters &&
'stickiness' in strategyConfig.parameters &&
strategyConfig.parameters.stickiness === ''
) {
strategyConfig.parameters.stickiness = 'default';
}
try {
const newFeatureStrategy =
await this.featureStrategiesStore.createStrategyFeatureEnv({

View File

@ -0,0 +1,22 @@
'use strict';
exports.up = function (db, callback) {
db.runSql(
`
INSERT INTO context_fields(name, description, sort_order, stickiness) VALUES('sessionId', 'Allows you to constrain on sessionId', 4, true) ON CONFLICT DO NOTHING;
UPDATE context_fields
SET stickiness = true
WHERE name LIKE 'userId' AND stickiness is null;
`,
callback,
);
};
exports.down = function (db, callback) {
db.runSql(
`
`,
callback,
);
};

View File

@ -17,8 +17,11 @@ let app: IUnleashTest;
let db: ITestDb;
const defaultStrategy = {
name: 'default',
parameters: {},
name: 'flexibleRollout',
parameters: {
rollout: '100',
stickiness: '',
},
constraints: [],
};
@ -844,3 +847,77 @@ test('Can add and remove tags at the same time', async () => {
expect(res.body.tags).toHaveLength(1);
});
});
test('Should return "default" for stickiness when creating a flexibleRollout strategy with "" for stickiness', async () => {
const username = 'toggle-feature';
const feature = {
name: 'test-featureA',
description: 'the #1 feature',
};
const projectId = 'default';
await app.services.featureToggleServiceV2.createFeatureToggle(
projectId,
feature,
username,
);
await app.services.featureToggleServiceV2.createStrategy(
defaultStrategy,
{ projectId, featureName: feature.name, environment: DEFAULT_ENV },
username,
);
await app.request
.get(
`/api/admin/projects/${projectId}/features/${feature.name}/environments/${DEFAULT_ENV}`,
)
.expect((res) => {
const toggle = res.body;
expect(toggle.strategies).toHaveLength(1);
expect(toggle.strategies[0].parameters.stickiness).toBe('default');
});
await app.request
.get(`/api/admin/features/${feature.name}`)
.expect((res) => {
const toggle = res.body;
expect(toggle.strategies).toHaveLength(1);
expect(toggle.strategies[0].parameters.stickiness).toBe('default');
});
});
test('Should throw error when updating a flexibleRollout strategy with "" for stickiness', async () => {
const username = 'toggle-feature';
const feature = {
name: 'test-featureB',
description: 'the #1 feature',
};
const projectId = 'default';
await app.services.featureToggleServiceV2.createFeatureToggle(
projectId,
feature,
username,
);
await app.services.featureToggleServiceV2.createStrategy(
defaultStrategy,
{ projectId, featureName: feature.name, environment: DEFAULT_ENV },
username,
);
const featureToggle =
await app.services.featureToggleServiceV2.getFeatureToggle(
feature.name,
);
await app.request
.patch(
`/api/admin/projects/${projectId}/features/${feature.name}/environments/${DEFAULT_ENV}/strategies/${featureToggle.environments[0].strategies[0].id}`,
)
.send(defaultStrategy)
.expect((res) => {
const result = res.body;
expect(res.status).toBe(400);
expect(result.error).toBe('Request validation failed');
});
});

View File

@ -43,13 +43,15 @@ The UI shows the currently available projects. To create a new project, use the
The configuration of a new Project is now available. the following input is available to create the new Project.
![A project creation form. The form fields are labeled "project ID", "name", and "description". The "Create" button is highlighted.](/img/projects_save_new_project.png)
![A project creation form. The "Create" button is highlighted.](/img/projects_save_new_project_v2.png)
| Item | Description |
| ------------ | ---------------------------------- |
| Project Id | Id for this Project |
| Project name | The name of the Project. |
| Description | A short description of the project |
| Item | Description |
|--------------------|---------------------------------------------------------------------------------------------|
| Project Id | Id for this Project |
| Project name | The name of the Project. |
| Description | A short description of the project |
| Mode | The project [collaboration mode](/reference/project-collaboration-mode.md) |
| Default Stickiness | The default stickiness for the project. This setting controls the default stickiness value for variants and for the gradual rollout strategy. |
## Deleting an existing project {#deleting-an-existing-project}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB