From 5a3bb1ffc3826e357b08adbb4986fd757480aa2b Mon Sep 17 00:00:00 2001 From: Christopher Kolstad Date: Fri, 12 Jan 2024 10:25:59 +0100 Subject: [PATCH] Biome1.5.1 (#5867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lots of work here, mostly because I didn't want to turn off the `noImplicitAnyLet` lint. This PR tries its best to type all the untyped lets biome complained about (Don't ask me how many hours that took or how many lints that was >200...), which in the future will force test authors to actually type their global variables setup in `beforeAll`. --------- Co-authored-by: Gastón Fournier --- biome.json | 2 +- frontend/package.json | 2 +- .../InstanceStats/InstanceStats.tsx | 4 +- .../ApplicationList/ApplicationList.tsx | 10 ++- .../ChangeRequestTimeline.tsx | 2 +- .../MultiActionButton/MultiActionButton.tsx | 1 - .../ChangeRequestsTabs/ChangeRequestsTabs.tsx | 7 +- .../common/PermissionHOC/PermissionHOC.tsx | 2 +- .../common/UserAvatar/UserAvatar.tsx | 2 +- .../ContextList/ContextList/ContextList.tsx | 12 ++- .../component/demo/DemoSteps/DemoSteps.tsx | 21 +++-- .../component/events/EventDiff/EventDiff.tsx | 6 +- .../EnvironmentVariantsTable.tsx | 6 +- .../featureTypes/FeatureTypesList.tsx | 6 +- .../IntegrationHowToSection.tsx | 10 +-- .../VariantInformation/VariantInformation.tsx | 22 +++-- .../ProjectDoraMetrics/ProjectDoraMetrics.tsx | 6 +- .../ProjectAccessAssign.tsx | 3 +- .../SegmentDeleteUsedSegment.tsx | 1 - .../segments/SegmentProjectAlert.tsx | 1 - .../segments/SegmentTable/SegmentTable.tsx | 6 +- .../StrategiesList/StrategiesList.tsx | 4 +- .../tags/TagTypeList/TagTypeList.tsx | 6 +- .../user/Authentication/Authentication.tsx | 4 +- frontend/src/themes/themeTypes.ts | 5 -- frontend/src/utils/routePathHelpers.ts | 2 +- frontend/yarn.lock | 80 +++++++++++-------- package.json | 2 +- src/lib/addons/addon.ts | 1 + src/lib/addons/datadog.ts | 2 +- src/lib/addons/slack-app.test.ts | 13 ++- src/lib/addons/webhook.ts | 2 +- src/lib/app.ts | 2 +- src/lib/db/access-store.test.ts | 4 +- src/lib/db/client-metrics-store-v2.test.ts | 8 +- src/lib/db/feature-strategy-store.test.ts | 44 +++++----- src/lib/db/segment-store.test.ts | 13 ++- src/lib/error/permission-error.ts | 6 +- .../tests/client-feature-toggle.e2e.test.ts | 10 ++- .../tests/client-feature-toggles.e2e.test.ts | 3 +- .../export-import-permissions.e2e.test.ts | 3 +- .../feature-toggle/feature-toggle-service.ts | 3 +- .../feature-toggle/feature-toggle-store.ts | 2 +- .../tests/feature-toggle-service.e2e.test.ts | 12 ++- .../tests/feature-toggle-store.e2e.test.ts | 12 ++- ...eature-toggle-strategies-store.e2e.test.ts | 11 ++- .../tests/feature-toggles.e2e.test.ts | 21 +++-- .../repository/storage-provider.ts | 2 +- .../playground/feature-evaluator/variant.ts | 2 +- .../environment-service.test.ts | 4 +- .../features/tag-type/tag-types.e2e.test.ts | 11 ++- src/lib/metrics.test.ts | 6 +- src/lib/middleware/response-time-metrics.ts | 2 +- src/lib/middleware/session-db.ts | 2 +- src/lib/routes/admin-api/api-token.ts | 4 +- src/lib/routes/admin-api/config.test.ts | 4 +- src/lib/routes/admin-api/context.test.ts | 4 +- src/lib/routes/admin-api/metrics.test.ts | 5 +- .../routes/admin-api/public-signup.test.ts | 22 +++-- src/lib/routes/admin-api/state.ts | 1 + src/lib/routes/admin-api/tag.test.ts | 7 +- src/lib/routes/client-api/metrics.test.ts | 12 +-- src/lib/routes/client-api/register.test.ts | 2 +- src/lib/routes/controller.ts | 3 +- src/lib/routes/health-check.test.ts | 2 +- src/lib/routes/public-invite.test.ts | 16 ++-- .../client-metrics/instance-service.test.ts | 30 ++++--- src/lib/services/context-service.ts | 2 +- src/lib/services/reset-token-service.ts | 2 +- src/lib/services/scheduler-service.test.ts | 4 +- src/lib/services/state-service.ts | 1 + src/lib/services/state-util.ts | 19 +++-- src/lib/services/user-service.ts | 2 +- src/lib/types/models/api-token.ts | 4 +- src/lib/util/omit-keys.ts | 5 +- src/lib/util/timer.test.ts | 2 +- src/test/e2e/api/admin/addon.e2e.test.ts | 13 +-- .../e2e/api/admin/api-token.auth.e2e.test.ts | 78 +++++++++++++++++- src/test/e2e/api/admin/api-token.e2e.test.ts | 17 +++- .../e2e/api/admin/client-metrics.e2e.test.ts | 7 +- .../e2e/api/admin/constraints.e2e.test.ts | 11 ++- src/test/e2e/api/admin/context.e2e.test.ts | 4 +- src/test/e2e/api/admin/favorites.e2e.test.ts | 5 +- src/test/e2e/api/admin/feature-type.test.ts | 4 +- .../e2e/api/admin/feature.auth.e2e.test.ts | 4 +- .../api/admin/feature.custom-auth.e2e.test.ts | 7 +- src/test/e2e/api/admin/feedback.e2e.test.ts | 14 ++-- .../e2e/api/admin/instance-admin.e2e.test.ts | 8 +- .../api/admin/project/api-token.e2e.test.ts | 15 ++-- .../admin/project/project.health.e2e.test.ts | 14 ++-- .../api/admin/public-signup-token.e2e.test.ts | 17 ++-- src/test/e2e/api/admin/segment.e2e.test.ts | 7 +- src/test/e2e/api/admin/splash.e2e.test.ts | 14 ++-- src/test/e2e/api/admin/strategy.e2e.test.ts | 11 ++- src/test/e2e/api/admin/tags.e2e.test.ts | 13 +-- src/test/e2e/api/admin/user-admin.e2e.test.ts | 16 ++-- src/test/e2e/api/admin/user/pat.e2e.test.ts | 8 +- src/test/e2e/api/admin/user/user.test.ts | 8 +- .../reset-password-controller.e2e.test.ts | 25 +++--- .../auth/simple-password-provider.e2e.test.ts | 12 +-- src/test/e2e/api/client/metrics.e2e.test.ts | 8 +- src/test/e2e/api/client/metricsV2.e2e.test.ts | 20 +++-- src/test/e2e/api/client/register.e2e.test.ts | 21 +++-- src/test/e2e/api/openapi/openapi.e2e.test.ts | 14 ++-- src/test/e2e/custom-auth.test.ts | 8 +- src/test/e2e/health.e2e.test.ts | 7 +- src/test/e2e/routes/routes.test.ts | 8 +- .../e2e/services/access-service.e2e.test.ts | 39 +++++---- .../e2e/services/addon-service.e2e.test.ts | 4 +- .../services/api-token-service.e2e.test.ts | 7 +- .../client-metrics-service.e2e.test.ts | 7 +- .../e2e/services/group-service.e2e.test.ts | 8 +- .../project-health-service.e2e.test.ts | 17 +--- .../services/reset-token-service.e2e.test.ts | 23 +++--- .../e2e/services/session-service.e2e.test.ts | 9 ++- src/test/e2e/services/setting-service.test.ts | 4 +- .../e2e/services/state-service.e2e.test.ts | 23 +++--- .../e2e/services/user-service.e2e.test.ts | 17 ++-- .../client-application-store.e2e.test.ts | 30 ++++--- .../client-metrics-store-v2.e2e.test.ts | 4 +- src/test/e2e/stores/event-store.e2e.test.ts | 4 +- .../feature-environment-store.e2e.test.ts | 4 +- .../e2e/stores/feature-tag-store.e2e.test.ts | 7 +- .../feature-toggle-client-store.e2e.test.ts | 15 ++-- .../e2e/stores/feature-type-store.e2e.test.ts | 9 ++- src/test/e2e/stores/project-store.e2e.test.ts | 7 +- src/test/e2e/stores/setting-store.e2e.test.ts | 7 +- .../stores/user-feedback-store.e2e.test.ts | 9 ++- .../e2e/stores/user-splash-store.e2e.test.ts | 9 ++- src/test/e2e/stores/user-store.e2e.test.ts | 16 ++-- src/test/fixtures/fake-strategies-store.ts | 4 +- yarn.lock | 80 +++++++++++-------- 132 files changed, 836 insertions(+), 534 deletions(-) diff --git a/biome.json b/biome.json index 6233ed7955..668afd049f 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.4.0/schema.json", + "$schema": "https://biomejs.dev/schemas/1.5.1/schema.json", "linter": { "enabled": true, "rules": { diff --git a/frontend/package.json b/frontend/package.json index 9f54e2b89e..c780c1dffa 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,7 +32,7 @@ "gen:api:sandbox": "NODE_OPTIONS=\"${NODE_OPTIONS} --no-experimental-fetch\" UNLEASH_OPENAPI_URL=https://sandbox.getunleash.io/demo2/docs/openapi.json yarn run gen:api" }, "devDependencies": { - "@biomejs/biome": "1.4.1", + "@biomejs/biome": "1.5.1", "@codemirror/lang-json": "6.0.1", "@emotion/react": "11.11.3", "@emotion/styled": "11.11.0", diff --git a/frontend/src/component/admin/instance-admin/InstanceStats/InstanceStats.tsx b/frontend/src/component/admin/instance-admin/InstanceStats/InstanceStats.tsx index 240831f9ed..1ac303096f 100644 --- a/frontend/src/component/admin/instance-admin/InstanceStats/InstanceStats.tsx +++ b/frontend/src/component/admin/instance-admin/InstanceStats/InstanceStats.tsx @@ -17,8 +17,8 @@ import { PageHeader } from '../../../common/PageHeader/PageHeader'; export const InstanceStats: VFC = () => { const { stats } = useInstanceStats(); - let versionTitle; - let version; + let versionTitle: string; + let version: string | undefined; if (stats?.versionEnterprise) { versionTitle = 'Unleash Enterprise version'; diff --git a/frontend/src/component/application/ApplicationList/ApplicationList.tsx b/frontend/src/component/application/ApplicationList/ApplicationList.tsx index 35c0562234..c316390430 100644 --- a/frontend/src/component/application/ApplicationList/ApplicationList.tsx +++ b/frontend/src/component/application/ApplicationList/ApplicationList.tsx @@ -56,7 +56,11 @@ export const ApplicationList = () => { () => [ { id: 'Icon', - Cell: ({ row: { original: { icon } } }: any) => ( + Cell: ({ + row: { + original: { icon }, + }, + }: any) => ( @@ -72,7 +76,9 @@ export const ApplicationList = () => { accessor: 'appName', width: '50%', Cell: ({ - row: { original: { appName, description } }, + row: { + original: { appName, description }, + }, }: any) => ( = ({ scheduledAt, failureReason, }) => { - let data; + let data: ChangeRequestState[]; switch (state) { case 'Rejected': data = rejectedSteps; diff --git a/frontend/src/component/changeRequest/ChangeRequestOverview/MultiActionButton/MultiActionButton.tsx b/frontend/src/component/changeRequest/ChangeRequestOverview/MultiActionButton/MultiActionButton.tsx index a414a29321..22bdacdc83 100644 --- a/frontend/src/component/changeRequest/ChangeRequestOverview/MultiActionButton/MultiActionButton.tsx +++ b/frontend/src/component/changeRequest/ChangeRequestOverview/MultiActionButton/MultiActionButton.tsx @@ -80,7 +80,6 @@ export const MultiActionButton: FC<{ }} open={open} anchorEl={anchorRef.current} - role={undefined} transition disablePortal > diff --git a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx index e557ee8d85..e60143c264 100644 --- a/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx +++ b/frontend/src/component/changeRequest/ProjectChangeRequests/ChangeRequestsTabs/ChangeRequestsTabs.tsx @@ -137,7 +137,12 @@ export const ChangeRequestsTabs = ({ .includes(feature.name.toLowerCase()), ); }, - Cell: ({ value, row: { original: { title } } }: any) => ( + Cell: ({ + value, + row: { + original: { title }, + }, + }: any) => ( = ({ tooltipProps, }) => { const { hasAccess } = useContext(AccessContext); - let access; + let access: boolean; if (projectId && environmentId) { access = hasAccess(permission, projectId, environmentId); diff --git a/frontend/src/component/common/UserAvatar/UserAvatar.tsx b/frontend/src/component/common/UserAvatar/UserAvatar.tsx index 709348e88b..31a1a2f07e 100644 --- a/frontend/src/component/common/UserAvatar/UserAvatar.tsx +++ b/frontend/src/component/common/UserAvatar/UserAvatar.tsx @@ -44,7 +44,7 @@ export const UserAvatar: FC = ({ src = user?.imageUrl; } - let fallback; + let fallback: string | undefined; if (!children && user) { fallback = user?.name || user?.email || user?.username; if (fallback?.includes(' ')) { diff --git a/frontend/src/component/context/ContextList/ContextList/ContextList.tsx b/frontend/src/component/context/ContextList/ContextList/ContextList.tsx index a937af7bf5..2403a18e10 100644 --- a/frontend/src/component/context/ContextList/ContextList/ContextList.tsx +++ b/frontend/src/component/context/ContextList/ContextList/ContextList.tsx @@ -71,7 +71,11 @@ const ContextList: VFC = () => { Header: 'Name', accessor: 'name', width: '70%', - Cell: ({ row: { original: { name, description } } }: any) => ( + Cell: ({ + row: { + original: { name, description }, + }, + }: any) => ( { Header: 'Actions', id: 'Actions', align: 'center', - Cell: ({ row: { original: { name } } }: any) => ( + Cell: ({ + row: { + original: { name }, + }, + }: any) => ( { diff --git a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx index 8a5af36780..bb318e3218 100644 --- a/frontend/src/component/demo/DemoSteps/DemoSteps.tsx +++ b/frontend/src/component/demo/DemoSteps/DemoSteps.tsx @@ -211,18 +211,15 @@ export const DemoSteps = ({ const currentStep = currentTopic.steps[step]; if (!currentStep) return; - setTimeout( - () => { - if ( - currentStep.href && - !location.pathname.endsWith(currentStep.href.split('?')[0]) - ) { - navigate(currentStep.href); - } - waitForLoad(currentStep); - }, - currentStep.delay ?? 0, - ); + setTimeout(() => { + if ( + currentStep.href && + !location.pathname.endsWith(currentStep.href.split('?')[0]) + ) { + navigate(currentStep.href); + } + waitForLoad(currentStep); + }, currentStep.delay ?? 0); }, [topic, step]); useEffect(() => { diff --git a/frontend/src/component/events/EventDiff/EventDiff.tsx b/frontend/src/component/events/EventDiff/EventDiff.tsx index 211221e9b6..04447722dc 100644 --- a/frontend/src/component/events/EventDiff/EventDiff.tsx +++ b/frontend/src/component/events/EventDiff/EventDiff.tsx @@ -1,7 +1,7 @@ import { diff } from 'deep-diff'; import { IEvent } from 'interfaces/event'; import { useTheme } from '@mui/system'; -import { CSSProperties } from 'react'; +import { JSX, CSSProperties } from 'react'; const DIFF_PREFIXES: Record = { A: ' ', @@ -40,7 +40,7 @@ const EventDiff = ({ : undefined; const buildItemDiff = (diff: any, key: string) => { - let change; + let change: JSX.Element | undefined; if (diff.lhs !== undefined) { change = (
@@ -59,7 +59,7 @@ const EventDiff = ({ }; const buildDiff = (diff: any, index: number): IEventDiffResult => { - let change; + let change: JSX.Element | undefined; const key = diff.path?.join('.') ?? diff.index; if (diff.item) { diff --git a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx index d5deb79dc8..d8118d97d4 100644 --- a/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureVariants/FeatureEnvironmentVariants/EnvironmentVariantsCard/EnvironmentVariantsTable/EnvironmentVariantsTable.tsx @@ -70,7 +70,11 @@ export const EnvironmentVariantsTable = ({ { Header: 'Weight', accessor: 'weight', - Cell: ({ row: { original: { name, weight } } }: any) => { + Cell: ({ + row: { + original: { name, weight }, + }, + }: any) => { return ( {calculateVariantWeight(weight)} % diff --git a/frontend/src/component/featureTypes/FeatureTypesList.tsx b/frontend/src/component/featureTypes/FeatureTypesList.tsx index ebef75bd34..5469cfdc2a 100644 --- a/frontend/src/component/featureTypes/FeatureTypesList.tsx +++ b/frontend/src/component/featureTypes/FeatureTypesList.tsx @@ -54,7 +54,11 @@ export const FeatureTypesList = () => { Header: 'Name', accessor: 'name', width: '90%', - Cell: ({ row: { original: { name, description } } }: any) => { + Cell: ({ + row: { + original: { name, description }, + }, + }: any) => { return ( ({ - fontSize: theme.fontSizes.smallBody, - gap: theme.spacing(1.5), - }), -); +const StyledHowDoesItWorkSection = styled(StyledRaisedSection)(({ theme }) => ({ + fontSize: theme.fontSizes.smallBody, + gap: theme.spacing(1.5), +})); interface IIntegrationHowToSectionProps { provider?: Pick; diff --git a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx index a3de08257b..1ff57225e3 100644 --- a/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx +++ b/frontend/src/component/playground/Playground/PlaygroundResultsTable/VariantCell/VariantInformation/VariantInformation.tsx @@ -117,7 +117,11 @@ export const VariantInformation: VFC = ({ const COLUMNS = [ { id: 'Icon', - Cell: ({ row: { original: { selected } } }: any) => ( + Cell: ({ + row: { + original: { selected }, + }, + }: any) => ( <> ( - {name} - ), + Cell: ({ + row: { + original: { name }, + }, + }: any) => {name}, maxWidth: 175, width: 175, }, @@ -144,8 +150,10 @@ const COLUMNS = [ sortType: 'alphanumeric', searchable: true, maxWidth: 75, - Cell: ({ row: { original: { weight } } }: any) => ( - {weight} - ), + Cell: ({ + row: { + original: { weight }, + }, + }: any) => {weight}, }, ]; diff --git a/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx b/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx index 5cfb217d61..9219075a16 100644 --- a/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx +++ b/frontend/src/component/project/Project/ProjectDoraMetrics/ProjectDoraMetrics.tsx @@ -57,7 +57,11 @@ export const ProjectDoraMetrics = () => { Header: 'Name', accessor: 'name', width: '40%', - Cell: ({ row: { original: { name } } }: any) => { + Cell: ({ + row: { + original: { name }, + }, + }: any) => { return ( { - let optionGroup; - let optionUser; + let optionGroup: IGroup | undefined, optionUser: IUser | undefined; if (option.type === ENTITY_TYPE.GROUP) { optionGroup = option.entity as IGroup; } else { diff --git a/frontend/src/component/segments/SegmentDelete/SegmentDeleteUsedSegment/SegmentDeleteUsedSegment.tsx b/frontend/src/component/segments/SegmentDelete/SegmentDeleteUsedSegment/SegmentDeleteUsedSegment.tsx index 67ea0ce33b..3c45509d06 100644 --- a/frontend/src/component/segments/SegmentDelete/SegmentDeleteUsedSegment/SegmentDeleteUsedSegment.tsx +++ b/frontend/src/component/segments/SegmentDelete/SegmentDeleteUsedSegment/SegmentDeleteUsedSegment.tsx @@ -102,7 +102,6 @@ const strategyListItem = ( {`${formatStrategyNameParens( strategy, )} — in change request `} - [ Header: 'Name', accessor: 'name', width: '60%', - Cell: ({ row: { original: { name, description, id } } }: any) => ( + Cell: ({ + row: { + original: { name, description, id }, + }, + }: any) => ( { accessor: (row: any) => formatStrategyName(row.name), width: '90%', Cell: ({ - row: { original: { name, description, deprecated } }, + row: { + original: { name, description, deprecated }, + }, }: any) => { return ( { Header: 'Name', accessor: 'name', width: '90%', - Cell: ({ row: { original: { name, description } } }: any) => { + Cell: ({ + row: { + original: { name, description }, + }, + }: any) => { return ( diff --git a/frontend/src/themes/themeTypes.ts b/frontend/src/themes/themeTypes.ts index 1926a23ae9..4d9ffd2456 100644 --- a/frontend/src/themes/themeTypes.ts +++ b/frontend/src/themes/themeTypes.ts @@ -122,17 +122,12 @@ declare module '@mui/material/styles' { variants: string[]; } - // biome-ignore lint/suspicious/noEmptyInterface: interface Theme extends CustomTheme {} - // biome-ignore lint/suspicious/noEmptyInterface: interface ThemeOptions extends CustomTheme {} - // biome-ignore lint/suspicious/noEmptyInterface: interface Palette extends CustomPalette {} - // biome-ignore lint/suspicious/noEmptyInterface: interface PaletteOptions extends CustomPalette {} - // biome-ignore lint/suspicious/noEmptyInterface: interface TypeBackground extends CustomTypeBackground {} /* Extend the background object from MUI */ diff --git a/frontend/src/utils/routePathHelpers.ts b/frontend/src/utils/routePathHelpers.ts index 45ee8b5556..bab9a6c391 100644 --- a/frontend/src/utils/routePathHelpers.ts +++ b/frontend/src/utils/routePathHelpers.ts @@ -8,7 +8,7 @@ export const getCreateTogglePath = ( ) => { const path = `/projects/${projectId}/create-toggle`; - let queryString; + let queryString: string | undefined; if (query) { queryString = Object.keys(query).reduce((acc, curr) => { return `${acc}${curr}=${query[curr]}`; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index eb78a93c86..4c5041d082 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -510,47 +510,59 @@ "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" -"@biomejs/biome@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.4.1.tgz#b698c67ea8cd8141c8e27f857c8e6e794320a251" - integrity sha512-JccVAwPbhi37pdxbAGmaOBjUTKEwEjWAhl7rKkVVuXHo4MLASXJ5HR8BTgrImi4/7rTBsGz1tgVD1Kwv1CHGRg== +"@biomejs/biome@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.5.1.tgz#ed665a8693e3014bf8fa641ad58703c85dd575cc" + integrity sha512-rdMA/N1Zc1nxUtbXMVr+50Sg/Pezz+9qGQa2uyRWFtrCoyr3dv0pVz+0ifGGue18ip50ZH8x2r5CV7zo8Q/0mA== optionalDependencies: - "@biomejs/cli-darwin-arm64" "1.4.1" - "@biomejs/cli-darwin-x64" "1.4.1" - "@biomejs/cli-linux-arm64" "1.4.1" - "@biomejs/cli-linux-x64" "1.4.1" - "@biomejs/cli-win32-arm64" "1.4.1" - "@biomejs/cli-win32-x64" "1.4.1" + "@biomejs/cli-darwin-arm64" "1.5.1" + "@biomejs/cli-darwin-x64" "1.5.1" + "@biomejs/cli-linux-arm64" "1.5.1" + "@biomejs/cli-linux-arm64-musl" "1.5.1" + "@biomejs/cli-linux-x64" "1.5.1" + "@biomejs/cli-linux-x64-musl" "1.5.1" + "@biomejs/cli-win32-arm64" "1.5.1" + "@biomejs/cli-win32-x64" "1.5.1" -"@biomejs/cli-darwin-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.4.1.tgz#75f9c3c9b1abed8836c8f7bc8cd23ba153fb93d1" - integrity sha512-PZWy2Idndqux38p6AXSDQM2ldRAWi32bvb7bMbTN0ALzpWYMYnxd71ornatumSSJYoNhKmxzDLq+jct7nZJ79w== +"@biomejs/cli-darwin-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.5.1.tgz#ea33f009aaa4bca3ce281e010a6cb108249cb973" + integrity sha512-E9pLakmSVHP6UH2uqAghqEkr/IHAIDfDyCedqJVnyFc+uufNTHwB8id4XTiWy/eKIdgxHZsTSE+R+W0IqrTNVQ== -"@biomejs/cli-darwin-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.4.1.tgz#672fcce2d339de3bb7a7bd2997e94f03121a28a3" - integrity sha512-soj3BWhnsM1M2JlzR09cibUzG1owJqetwj/Oo7yg0foijo9lNH9XWXZfJBYDKgW/6Fomn+CC2EcUS+hisQzt9g== +"@biomejs/cli-darwin-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.5.1.tgz#c719a8615b380b25cd9a4bbdfc81d90dbec0996b" + integrity sha512-8O1F+FcoCi02JlocyilB6R3y3kT9sRkBCRwYddaBIScQe2hCme/mA2rVzrhCCHhskrclJ51GEKjkEORj4/8c2A== -"@biomejs/cli-linux-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.4.1.tgz#c816206089ad29ce866c58a6e00e9d3d64a3529d" - integrity sha512-YIZqfJUg4F+fPsBTXxgD7EU2E5OAYbmYSl/snf4PevwfQCWE/omOFZv+NnIQmjYj9I7ParDgcJvanoA3/kO0JQ== +"@biomejs/cli-linux-arm64-musl@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.1.tgz#c5364e08faca4826654b191e696425d5449a6fe3" + integrity sha512-Lw9G3LUdhRMp8L8RMeVevnfQCa7luT6ubQ8GRjLju32glxWKefpDrzgfHixGyvTQPlhnYjQ+V8/QQ/I7WPzOoA== -"@biomejs/cli-linux-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.4.1.tgz#2639daeab1be205cfe444a8d5a3f76aa3a59b956" - integrity sha512-9YOZw3qBd/KUj63A6Hn2zZgzGb2nbESM0qNmeMXgmqinVKM//uc4OgY5TuKITuGjMSvcVxxd4dX1IzYjV9qvNQ== +"@biomejs/cli-linux-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.5.1.tgz#1d9fe74cbc27aa784d8a3743ad1f77da883e2aef" + integrity sha512-25gwY4FMzmi1Rl6N835raLq7nzTk+PyEQd88k9Em6dqtI4qpljqmZlMmVjOiwXKe3Ee80J/Vlh7BM36lsHUTEg== -"@biomejs/cli-win32-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.4.1.tgz#ed5e749b2e0987cf16b545beaa01be6980ae8ce1" - integrity sha512-nWQbvkNKxYn/kCQ0yVF8kCaS3VzaGvtFSmItXiMknU4521LDjJ7tNWH12Gol+pIslrCbd4E1LhJa0a3ThRsBVg== +"@biomejs/cli-linux-x64-musl@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.1.tgz#7e6ef6c1308907f30909374f91c380e2c85bf393" + integrity sha512-5gapxc/VlwTgGRbTc9h8PMTpf8eNahIBauFUGSXncHgayi3VpezKSicgaQ1bb8FahVXf/5eNEVxVARq/or71Ag== -"@biomejs/cli-win32-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.4.1.tgz#dd8ee6e14a5d74cbeb2eb9824a43c61bb5c460e4" - integrity sha512-88fR2CQxQ4YLs2BUDuywWYQpUKgU3A3sTezANFc/4LGKQFFLV2yX+F7QAdZVkMHfA+RD9Xg178HomM/6mnTNPA== +"@biomejs/cli-linux-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.5.1.tgz#0f6afaf035c6a07fe757d58a315f3a75e49f8987" + integrity sha512-YDM0gZP4UbAuaBI3DVbUuj5X+Omm6uxzD1Qpc6hcduH1kzXzs9L0ee7cn/kJtNndoXR8MlmUS0O0/wWvZf2YaA== + +"@biomejs/cli-win32-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.5.1.tgz#196bdc1afd0945a0fad76719b601bf7f7a4aaf72" + integrity sha512-TVpLBOLUMLQmH2VRFBKFr3rgEkr7XvG4QZxHOxWB9Ivc/sQPvg4aHMd8qpgPKXABGUnultyc9t0+WvfIDxuALg== + +"@biomejs/cli-win32-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.5.1.tgz#b1996fa2dc6580f39fb2e1b6d126e93baf8da58d" + integrity sha512-qx8EKwScZmVYZjMPZ6GF3ZUmgg/N6zqh+d8vHA2E43opNCyqIPTl89sOqkc7zd1CyyABDWxsbqI9Ih6xTT6hnQ== "@braintree/sanitize-url@^6.0.0": version "6.0.2" diff --git a/package.json b/package.json index bf7b0484ac..cc9d9bbd0d 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "devDependencies": { "@apidevtools/swagger-parser": "10.1.0", "@babel/core": "7.23.7", - "@biomejs/biome": "1.4.1", + "@biomejs/biome": "1.5.1", "@swc/core": "1.3.102", "@swc/jest": "0.2.29", "@types/bcryptjs": "2.4.6", diff --git a/src/lib/addons/addon.ts b/src/lib/addons/addon.ts index 740400134f..5ea44beefe 100644 --- a/src/lib/addons/addon.ts +++ b/src/lib/addons/addon.ts @@ -42,6 +42,7 @@ export default abstract class Addon { options: any = {}, retries: number = 1, ): Promise { + // biome-ignore lint/suspicious/noImplicitAnyLet: Due to calling upstream, it's not easy knowing the real type here let res; try { res = await fetch(url, { diff --git a/src/lib/addons/datadog.ts b/src/lib/addons/datadog.ts index 9fac295689..9d98f5bf0d 100644 --- a/src/lib/addons/datadog.ts +++ b/src/lib/addons/datadog.ts @@ -52,7 +52,7 @@ export default class DatadogAddon extends Addon { event, }; - let text; + let text: string; if (typeof bodyTemplate === 'string' && bodyTemplate.length > 1) { text = Mustache.render(bodyTemplate, context); } else { diff --git a/src/lib/addons/slack-app.test.ts b/src/lib/addons/slack-app.test.ts index 4c49646483..b252dd6490 100644 --- a/src/lib/addons/slack-app.test.ts +++ b/src/lib/addons/slack-app.test.ts @@ -26,7 +26,7 @@ jest.mock('@slack/web-api', () => ({ })); describe('SlackAppAddon', () => { - let addon; + let addon: SlackAppAddon; const accessToken = 'test-access-token'; const loggerMock = { debug: jest.fn(), @@ -102,7 +102,10 @@ describe('SlackAppAddon', () => { ], }; - await addon.handleEvent(eventWith2Tags, { accessToken }); + await addon.handleEvent(eventWith2Tags, { + accessToken, + defaultChannels: '', + }); expect(slackApiCalls.length).toBe(2); expect(slackApiCalls[0].channel).toBe('general'); @@ -132,6 +135,7 @@ describe('SlackAppAddon', () => { it('should not post a message if there are no tagged channels and no defaultChannels', async () => { await addon.handleEvent(event, { accessToken, + defaultChannels: '', }); expect(slackApiCalls.length).toBe(0); @@ -167,7 +171,10 @@ describe('SlackAppAddon', () => { .mockResolvedValueOnce({ ok: true }) .mockRejectedValueOnce(mockError); - await addon.handleEvent(eventWith3Tags, { accessToken }); + await addon.handleEvent(eventWith3Tags, { + accessToken, + defaultChannels: '', + }); expect(postMessage).toHaveBeenCalledTimes(3); expect(loggerMock.warn).toHaveBeenCalledWith( diff --git a/src/lib/addons/webhook.ts b/src/lib/addons/webhook.ts index ae4000a57b..95a1465ba4 100644 --- a/src/lib/addons/webhook.ts +++ b/src/lib/addons/webhook.ts @@ -24,7 +24,7 @@ export default class Webhook extends Addon { event, }; - let body; + let body: string | undefined; if (typeof bodyTemplate === 'string' && bodyTemplate.length > 1) { body = Mustache.render(bodyTemplate, context); diff --git a/src/lib/app.ts b/src/lib/app.ts index 49408d385e..b658628fe1 100644 --- a/src/lib/app.ts +++ b/src/lib/app.ts @@ -10,7 +10,7 @@ import rbacMiddleware from './middleware/rbac-middleware'; import apiTokenMiddleware from './middleware/api-token-middleware'; import { IUnleashServices } from './types/services'; import { IAuthType, IUnleashConfig } from './types/option'; -import { IUnleashStores } from './types/stores'; +import { IUnleashStores } from './types'; import IndexRouter from './routes'; diff --git a/src/lib/db/access-store.test.ts b/src/lib/db/access-store.test.ts index 8f4c625c5c..0f3758b2e1 100644 --- a/src/lib/db/access-store.test.ts +++ b/src/lib/db/access-store.test.ts @@ -1,10 +1,10 @@ -import dbInit from '../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../test/e2e/helpers/database-init'; import getLogger from '../../test/fixtures/no-logger'; import { PermissionRef } from 'lib/services/access-service'; import { AccessStore } from './access-store'; import { BadDataError } from '../../lib/error'; -let db; +let db: ITestDb; beforeAll(async () => { db = await dbInit('access_store_serial', getLogger); diff --git a/src/lib/db/client-metrics-store-v2.test.ts b/src/lib/db/client-metrics-store-v2.test.ts index 6bdacac74b..2b83c3c17a 100644 --- a/src/lib/db/client-metrics-store-v2.test.ts +++ b/src/lib/db/client-metrics-store-v2.test.ts @@ -1,10 +1,10 @@ -import dbInit from '../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../test/e2e/helpers/database-init'; import getLogger from '../../test/fixtures/no-logger'; -import { IClientMetricsStoreV2 } from '../types'; +import { IClientMetricsStoreV2, IUnleashStores } from '../types'; import { endOfDay, setHours, startOfHour, subDays } from 'date-fns'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let clientMetricsStore: IClientMetricsStoreV2; beforeAll(async () => { diff --git a/src/lib/db/feature-strategy-store.test.ts b/src/lib/db/feature-strategy-store.test.ts index cabee6bc8b..76bb35805e 100644 --- a/src/lib/db/feature-strategy-store.test.ts +++ b/src/lib/db/feature-strategy-store.test.ts @@ -1,11 +1,14 @@ -import dbInit from '../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../test/e2e/helpers/database-init'; import getLogger from '../../test/fixtures/no-logger'; -import FeatureStrategiesStore from '../features/feature-toggle/feature-toggle-strategies-store'; -import FeatureToggleStore from '../features/feature-toggle/feature-toggle-store'; -import StrategyStore from './strategy-store'; -import { IFeatureStrategy, PartialSome } from '../types'; +import { + IFeatureStrategiesStore, + IFeatureStrategy, + IFeatureToggleStore, + IStrategyStore, + PartialSome, +} from '../types'; -let db; +let db: ITestDb; beforeAll(async () => { db = await dbInit('feature_strategy_store_serial', getLogger); @@ -21,7 +24,7 @@ afterAll(async () => { test('returns 0 if no custom strategies', async () => { // Arrange - const featureStrategiesStore: FeatureStrategiesStore = + const featureStrategiesStore: IFeatureStrategiesStore = db.stores.featureStrategiesStore; // Act @@ -34,22 +37,21 @@ test('returns 0 if no custom strategies', async () => { test('returns 0 if no custom strategies are in use', async () => { // Arrange - const featureToggleStore: FeatureToggleStore = db.stores.featureToggleStore; - const featureStrategiesStore: FeatureStrategiesStore = + const featureToggleStore: IFeatureToggleStore = + db.stores.featureToggleStore; + const featureStrategiesStore: IFeatureStrategiesStore = db.stores.featureStrategiesStore; - const strategyStore: StrategyStore = db.stores.strategyStore; + const strategyStore: IStrategyStore = db.stores.strategyStore; - featureToggleStore.create('default', { + await featureToggleStore.create('default', { name: 'test-toggle-2', createdByUserId: 9999, }); - strategyStore.createStrategy({ + await strategyStore.createStrategy({ name: 'strategy-2', - built_in: 0, parameters: [], description: '', - createdAt: '2023-06-09T09:00:12.242Z', }); // Act @@ -62,10 +64,11 @@ test('returns 0 if no custom strategies are in use', async () => { test('counts custom strategies in use', async () => { // Arrange - const featureToggleStore: FeatureToggleStore = db.stores.featureToggleStore; - const featureStrategiesStore: FeatureStrategiesStore = + const featureToggleStore: IFeatureToggleStore = + db.stores.featureToggleStore; + const featureStrategiesStore: IFeatureStrategiesStore = db.stores.featureStrategiesStore; - const strategyStore: StrategyStore = db.stores.strategyStore; + const strategyStore: IStrategyStore = db.stores.strategyStore; await featureToggleStore.create('default', { name: 'test-toggle', @@ -74,10 +77,8 @@ test('counts custom strategies in use', async () => { await strategyStore.createStrategy({ name: 'strategy-1', - built_in: 0, parameters: [], description: '', - createdAt: '2023-06-09T09:00:12.242Z', }); await featureStrategiesStore.createStrategyFeatureEnv({ @@ -108,8 +109,9 @@ const baseStrategy: PartialSome = { variants: [], }; test('increment sort order on each new insert', async () => { - const featureToggleStore: FeatureToggleStore = db.stores.featureToggleStore; - const featureStrategiesStore: FeatureStrategiesStore = + const featureToggleStore: IFeatureToggleStore = + db.stores.featureToggleStore; + const featureStrategiesStore: IFeatureStrategiesStore = db.stores.featureStrategiesStore; await featureToggleStore.create('default', { diff --git a/src/lib/db/segment-store.test.ts b/src/lib/db/segment-store.test.ts index d6e18d13f7..b1056e1158 100644 --- a/src/lib/db/segment-store.test.ts +++ b/src/lib/db/segment-store.test.ts @@ -1,10 +1,11 @@ import { ISegmentStore } from '../types/stores/segment-store'; -import dbInit from '../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../test/e2e/helpers/database-init'; import getLogger from '../../test/fixtures/no-logger'; import NotFoundError from '../error/notfound-error'; +import { IUnleashStores, IUser } from '../types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let segmentStore: ISegmentStore; beforeAll(async () => { @@ -36,7 +37,7 @@ describe('unexpected input handling for get segment', () => { }); describe('usage counting', () => { - let user; + let user: IUser; beforeAll(async () => { user = await db.stores.userStore.insert({ username: 'test', @@ -54,10 +55,12 @@ describe('usage counting', () => { const flag1 = await db.stores.featureToggleStore.create('default', { name: 'test', + createdByUserId: -1137, }); const flag2 = await db.stores.featureToggleStore.create('default', { name: 'test2', + createdByUserId: -1137, }); const segment = await segmentStore.create( @@ -142,6 +145,7 @@ describe('usage counting', () => { const flag = await db.stores.featureToggleStore.create('default', { name: 'test', + createdByUserId: -1137, }); const segment1 = await segmentStore.create( @@ -174,6 +178,7 @@ describe('usage counting', () => { rollout: '100', stickiness: 'default', }, + constraints: [], }); await db.rawDatabase.table('change_requests').insert({ diff --git a/src/lib/error/permission-error.ts b/src/lib/error/permission-error.ts index 8b5fb0094e..5938aeaf9b 100644 --- a/src/lib/error/permission-error.ts +++ b/src/lib/error/permission-error.ts @@ -19,9 +19,9 @@ class PermissionError extends UnleashError { .map((perm) => `"${perm}"`) .join(', ')}`; - const message = - `You don't have the required permissions to perform this operation. To perform this action, you need ${permissionsMessage}` + - (environment ? ` in the "${environment}" environment.` : `.`); + const message = `You don't have the required permissions to perform this operation. To perform this action, you need ${permissionsMessage}${ + environment ? ` in the "${environment}" environment.` : `.` + }`; super(message); diff --git a/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts b/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts index c2ec3f4150..68df2cd6af 100644 --- a/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts +++ b/src/lib/features/client-feature-toggles/tests/client-feature-toggle.e2e.test.ts @@ -7,8 +7,10 @@ import FeatureController from '../client-feature-toggle.controller'; import { createTestConfig } from '../../../../test/config/test-config'; import { secondsToMilliseconds } from 'date-fns'; import { ClientSpecService } from '../../../services/client-spec-service'; +import { Application } from 'express'; +import { IFlagResolver } from '../../../types'; -let app; +let app: Application; async function getSetup() { const base = `/random${Math.round(Math.random() * 1000)}`; @@ -38,10 +40,10 @@ const callGetAll = async (controller: FeatureController) => { ); }; -let base; -let request; +let base: string; +let request: supertest.SuperTest; -let flagResolver; +let flagResolver: Partial; beforeEach(async () => { const setup = await getSetup(); diff --git a/src/lib/features/client-feature-toggles/tests/client-feature-toggles.e2e.test.ts b/src/lib/features/client-feature-toggles/tests/client-feature-toggles.e2e.test.ts index 718d78c2b5..9140cbfc5a 100644 --- a/src/lib/features/client-feature-toggles/tests/client-feature-toggles.e2e.test.ts +++ b/src/lib/features/client-feature-toggles/tests/client-feature-toggles.e2e.test.ts @@ -6,10 +6,11 @@ import { } from '../../../../test/e2e/helpers/test-helper'; import getLogger from '../../../../test/fixtures/no-logger'; import { DEFAULT_ENV } from '../../../util/constants'; +import { IUserWithRootRole } from '../../../types'; let app: IUnleashTest; let db: ITestDb; -let dummyAdmin; +let dummyAdmin: IUserWithRootRole; const apiClientResponse = [ { diff --git a/src/lib/features/export-import-toggles/export-import-permissions.e2e.test.ts b/src/lib/features/export-import-toggles/export-import-permissions.e2e.test.ts index f33c7d5973..eaf32460c8 100644 --- a/src/lib/features/export-import-toggles/export-import-permissions.e2e.test.ts +++ b/src/lib/features/export-import-toggles/export-import-permissions.e2e.test.ts @@ -18,6 +18,7 @@ import { ImportTogglesSchema, VariantsSchema } from '../../openapi'; import { IContextFieldDto } from '../../types/stores/context-field-store'; import { AccessService } from '../../services'; import { DEFAULT_ENV } from '../../util'; +import { IRole } from '../../types/stores/access-store'; let app: IUnleashTest; let db: ITestDb; @@ -27,7 +28,7 @@ let contextFieldStore: IContextFieldStore; let projectStore: IProjectStore; let toggleStore: IFeatureToggleStore; let accessService: AccessService; -let adminRole; +let adminRole: IRole; let stores: IUnleashStores; const regularUserName = 'import-user'; diff --git a/src/lib/features/feature-toggle/feature-toggle-service.ts b/src/lib/features/feature-toggle/feature-toggle-service.ts index d0eed4cd3f..d5294c07a1 100644 --- a/src/lib/features/feature-toggle/feature-toggle-service.ts +++ b/src/lib/features/feature-toggle/feature-toggle-service.ts @@ -103,6 +103,7 @@ import { IPrivateProjectChecker } from '../private-project/privateProjectChecker import { IDependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model-type'; import EventService from '../../services/event-service'; import { DependentFeaturesService } from '../dependent-features/dependent-features-service'; +import { FeatureToggleInsert } from './feature-toggle-store'; interface IFeatureContext { featureName: string; @@ -1148,7 +1149,7 @@ class FeatureToggleService { ); } if (exists) { - let featureData; + let featureData: FeatureToggleInsert; if (isValidated) { featureData = { createdByUserId, ...value }; } else { diff --git a/src/lib/features/feature-toggle/feature-toggle-store.ts b/src/lib/features/feature-toggle/feature-toggle-store.ts index f325a09d48..a72916da98 100644 --- a/src/lib/features/feature-toggle/feature-toggle-store.ts +++ b/src/lib/features/feature-toggle/feature-toggle-store.ts @@ -269,7 +269,7 @@ export default class FeatureToggleStore implements IFeatureToggleStore { 'last_seen_at_metrics.environment as last_seen_at_env', ); - let rows; + let rows: any[]; if (project) { rows = await builder.internalQuery diff --git a/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts b/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts index f5e518398f..0cdef2a68f 100644 --- a/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts +++ b/src/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.ts @@ -1,11 +1,12 @@ import FeatureToggleService from '../feature-toggle-service'; import { createTestConfig } from '../../../../test/config/test-config'; -import dbInit from '../../../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../../../test/e2e/helpers/database-init'; import { DEFAULT_ENV } from '../../../util'; import { FeatureStrategySchema } from '../../../openapi'; import User from '../../../types/user'; import { IConstraint, + IUnleashConfig, IUnleashStores, IVariant, SKIP_CHANGE_REQUEST, @@ -17,18 +18,18 @@ import { ForbiddenError, PatternError, PermissionError } from '../../../error'; import { ISegmentService } from '../../../segments/segment-service-interface'; import { createFeatureToggleService, createSegmentService } from '../..'; import { - insertLastSeenAt, insertFeatureEnvironmentsLastSeen, + insertLastSeenAt, } from '../../../../test/e2e/helpers/test-helper'; import { EventService } from '../../../services'; let stores: IUnleashStores; -let db; +let db: ITestDb; let service: FeatureToggleService; let segmentService: ISegmentService; let eventService: EventService; let environmentService: EnvironmentService; -let unleashConfig; +let unleashConfig: IUnleashConfig; const TEST_USER_ID = -9999; const mockConstraints = (): IConstraint[] => { return Array.from({ length: 5 }).map(() => ({ @@ -276,6 +277,7 @@ test('adding and removing an environment preserves variants when variants per en stores, { ...unleashConfig, + // @ts-expect-error - incomplete flag resolver definition flagResolver: { // eslint-disable-next-line @typescript-eslint/no-unused-vars isEnabled: (toggleName: string) => false, @@ -472,6 +474,7 @@ test('If change requests are enabled, cannot change variants without going via C // Force all feature flags on to make sure we have Change requests on const customFeatureService = createFeatureToggleService(db.rawDatabase, { ...unleashConfig, + // @ts-expect-error - incomplete flag resolver definition flagResolver: { isEnabled: () => true, }, @@ -537,6 +540,7 @@ test('If CRs are protected for any environment in the project stops bulk update // Force all feature flags on to make sure we have Change requests on const customFeatureService = createFeatureToggleService(db.rawDatabase, { ...unleashConfig, + // @ts-expect-error - incomplete flag resolver definition flagResolver: { isEnabled: () => true, }, diff --git a/src/lib/features/feature-toggle/tests/feature-toggle-store.e2e.test.ts b/src/lib/features/feature-toggle/tests/feature-toggle-store.e2e.test.ts index 3035a9d94a..2ee5b000a5 100644 --- a/src/lib/features/feature-toggle/tests/feature-toggle-store.e2e.test.ts +++ b/src/lib/features/feature-toggle/tests/feature-toggle-store.e2e.test.ts @@ -1,10 +1,14 @@ -import dbInit from '../../../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../../../test/e2e/helpers/database-init'; import getLogger from '../../../../test/fixtures/no-logger'; -import { IFeatureToggleStore, IProjectStore } from '../../../types'; +import { + IFeatureToggleStore, + IProjectStore, + IUnleashStores, +} from '../../../types'; import { FeatureToggleInsert } from '../feature-toggle-store'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let featureToggleStore: IFeatureToggleStore; let projectStore: IProjectStore; diff --git a/src/lib/features/feature-toggle/tests/feature-toggle-strategies-store.e2e.test.ts b/src/lib/features/feature-toggle/tests/feature-toggle-strategies-store.e2e.test.ts index 0822cc11d2..b00d9bb0cf 100644 --- a/src/lib/features/feature-toggle/tests/feature-toggle-strategies-store.e2e.test.ts +++ b/src/lib/features/feature-toggle/tests/feature-toggle-strategies-store.e2e.test.ts @@ -1,10 +1,11 @@ import { IFeatureStrategiesStore } from 'lib/features/feature-toggle/types/feature-toggle-strategies-store-type'; import { IFeatureToggleStore } from 'lib/features/feature-toggle/types/feature-toggle-store-type'; -import dbInit from '../../../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../../../test/e2e/helpers/database-init'; import getLogger from '../../../../test/fixtures/no-logger'; +import { IUnleashStores } from '../../../types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let featureStrategiesStore: IFeatureStrategiesStore; let featureToggleStore: IFeatureToggleStore; @@ -85,7 +86,7 @@ test('Can query for features with tags', async () => { name: 'not-tagged', createdByUserId: 9999, }); - await stores.featureTagStore.tagFeature('to-be-tagged', tag); + await stores.featureTagStore.tagFeature('to-be-tagged', tag, -1337); const features = await featureStrategiesStore.getFeatureOverview({ projectId: 'default', tag: [[tag.type, tag.value]], @@ -127,10 +128,12 @@ test('Can query for features with namePrefix and tags', async () => { await stores.featureTagStore.tagFeature( 'to-be-tagged-nameprefix-and-tags', tag, + 9999, ); await stores.featureTagStore.tagFeature( 'tagged-but-not-hit-nameprefix-and-tags', tag, + 9999, ); const features = await featureStrategiesStore.getFeatureOverview({ projectId: 'default', diff --git a/src/lib/features/feature-toggle/tests/feature-toggles.e2e.test.ts b/src/lib/features/feature-toggle/tests/feature-toggles.e2e.test.ts index 35418f614b..8818fb4bd5 100644 --- a/src/lib/features/feature-toggle/tests/feature-toggles.e2e.test.ts +++ b/src/lib/features/feature-toggle/tests/feature-toggles.e2e.test.ts @@ -1375,6 +1375,7 @@ test('Can update a strategy based on id', async () => { .post('/api/admin/projects/default/features') .send({ name: featureName }) .expect(201); + // biome-ignore lint/suspicious/noImplicitAnyLet: Due to assigning from res.body later on. we ignore the type here let strategy; await app.request .post( @@ -1456,7 +1457,7 @@ test('Can patch a strategy based on id', async () => { .post(`${BASE_URI}/features`) .send({ name: featureName }) .expect(201); - let strategy; + let strategy: { id: number } | undefined; await app.request .post( `${BASE_URI}/features/${featureName}/environments/${envName}/strategies`, @@ -1476,13 +1477,17 @@ test('Can patch a strategy based on id', async () => { await app.request .patch( - `${BASE_URI}/features/${featureName}/environments/${envName}/strategies/${strategy.id}`, + `${BASE_URI}/features/${featureName}/environments/${envName}/strategies/${ + strategy!.id + }`, ) .send([{ op: 'replace', path: '/parameters/rollout', value: 42 }]) .expect(200); await app.request .get( - `${BASE_URI}/features/${featureName}/environments/${envName}/strategies/${strategy.id}`, + `${BASE_URI}/features/${featureName}/environments/${envName}/strategies/${ + strategy!.id + }`, ) .expect(200) .expect((res) => { @@ -1580,7 +1585,7 @@ test('Deleting a strategy should include name of feature strategy was deleted fr }) .set('Content-Type', 'application/json') .expect(201); - let strategyId; + let strategyId: number | undefined; await app.request .post( `/api/admin/projects/default/features/${featureName}/environments/${environment}/strategies`, @@ -1839,7 +1844,7 @@ test('Deleting last strategy for feature environment should disable that environ .post('/api/admin/projects/default/features') .send({ name: featureName }) .expect(201); - let strategyId; + let strategyId: number | undefined; await app.request .post( `/api/admin/projects/default/features/${featureName}/environments/${envName}/strategies`, @@ -1902,7 +1907,7 @@ test('Deleting strategy for feature environment should not disable that environm .post('/api/admin/projects/default/features') .send({ name: featureName }) .expect(201); - let strategyId; + let strategyId: number | undefined; await app.request .post( `/api/admin/projects/default/features/${featureName}/environments/${envName}/strategies`, @@ -3250,7 +3255,7 @@ test('Disabling last strategy for feature environment should disable that enviro .post('/api/admin/projects/default/features') .send({ name: featureName }) .expect(201); - let strategyId; + let strategyId: number | undefined; await app.request .post( `/api/admin/projects/default/features/${featureName}/environments/${envName}/strategies`, @@ -3322,7 +3327,7 @@ test('Enabling a feature environment should add the default strategy when only d .post('/api/admin/projects/default/features') .send({ name: featureName }) .expect(201); - let strategyId; + let strategyId: number | undefined; await app.request .post( `/api/admin/projects/default/features/${featureName}/environments/${envName}/strategies`, diff --git a/src/lib/features/playground/feature-evaluator/repository/storage-provider.ts b/src/lib/features/playground/feature-evaluator/repository/storage-provider.ts index 51118e3314..bbe4fee8e5 100644 --- a/src/lib/features/playground/feature-evaluator/repository/storage-provider.ts +++ b/src/lib/features/playground/feature-evaluator/repository/storage-provider.ts @@ -33,7 +33,7 @@ export class FileStorageProvider implements StorageProvider { async get(key: string): Promise { const path = this.getPath(key); - let data; + let data: string | undefined; try { data = await readFile(path, 'utf8'); } catch (error: any) { diff --git a/src/lib/features/playground/feature-evaluator/variant.ts b/src/lib/features/playground/feature-evaluator/variant.ts index 3630e8e745..0209d57307 100644 --- a/src/lib/features/playground/feature-evaluator/variant.ts +++ b/src/lib/features/playground/feature-evaluator/variant.ts @@ -45,7 +45,7 @@ function getSeed(context: Context, stickiness: string = 'default'): string { const value = resolveContextValue(context, stickiness); return value ? value.toString() : randomString(); } - let result; + let result: string | undefined; stickinessSelectors.some((key: string): boolean => { const value = context[key]; if (typeof value === 'string' && value !== '') { diff --git a/src/lib/features/project-environments/environment-service.test.ts b/src/lib/features/project-environments/environment-service.test.ts index 1c5d4be5ff..79eeb5be00 100644 --- a/src/lib/features/project-environments/environment-service.test.ts +++ b/src/lib/features/project-environments/environment-service.test.ts @@ -1,13 +1,13 @@ import EnvironmentService from './environment-service'; import { createTestConfig } from '../../../test/config/test-config'; -import dbInit from '../../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../../test/e2e/helpers/database-init'; import NotFoundError from '../../error/notfound-error'; import { IUnleashStores, SYSTEM_USER } from '../../types'; import NameExistsError from '../../error/name-exists-error'; import { EventService } from '../../services'; let stores: IUnleashStores; -let db; +let db: ITestDb; let service: EnvironmentService; let eventService: EventService; diff --git a/src/lib/features/tag-type/tag-types.e2e.test.ts b/src/lib/features/tag-type/tag-types.e2e.test.ts index 8b540d8574..acaec7409a 100644 --- a/src/lib/features/tag-type/tag-types.e2e.test.ts +++ b/src/lib/features/tag-type/tag-types.e2e.test.ts @@ -1,9 +1,12 @@ -import dbInit from '../../../test/e2e/helpers/database-init'; -import { setupAppWithCustomConfig } from '../../../test/e2e/helpers/test-helper'; +import dbInit, { ITestDb } from '../../../test/e2e/helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../../test/e2e/helpers/test-helper'; import getLogger from '../../../test/fixtures/no-logger'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('tag_types_api_serial', getLogger); diff --git a/src/lib/metrics.test.ts b/src/lib/metrics.test.ts index c0632f277c..e8ea2b1bdc 100644 --- a/src/lib/metrics.test.ts +++ b/src/lib/metrics.test.ts @@ -2,7 +2,7 @@ import { register } from 'prom-client'; import EventEmitter from 'events'; import { IEventStore } from './types/stores/event-store'; import { createTestConfig } from '../test/config/test-config'; -import { REQUEST_TIME, DB_TIME } from './metric-events'; +import { DB_TIME, REQUEST_TIME } from './metric-events'; import { CLIENT_METRICS, CLIENT_REGISTER, @@ -15,7 +15,7 @@ import { InstanceStatsService } from './features/instance-stats/instance-stats-s import VersionService from './services/version-service'; import { createFakeGetActiveUsers } from './features/instance-stats/getActiveUsers'; import { createFakeGetProductionChanges } from './features/instance-stats/getProductionChanges'; -import { IEnvironmentStore } from './types'; +import { IEnvironmentStore, IUnleashStores } from './types'; import FakeEnvironmentStore from './features/project-environments/fake-environment-store'; const monitor = createMetricsMonitor(); @@ -24,7 +24,7 @@ const prometheusRegister = register; let eventStore: IEventStore; let environmentStore: IEnvironmentStore; let statsService: InstanceStatsService; -let stores; +let stores: IUnleashStores; beforeAll(() => { const config = createTestConfig({ server: { diff --git a/src/lib/middleware/response-time-metrics.ts b/src/lib/middleware/response-time-metrics.ts index 33c7b9dbb3..5da362ec9a 100644 --- a/src/lib/middleware/response-time-metrics.ts +++ b/src/lib/middleware/response-time-metrics.ts @@ -18,7 +18,7 @@ export function responseTimeMetrics( const { statusCode } = res; const pathname = req.route ? req.baseUrl + req.route.path : '(hidden)'; - let appName; + let appName: string | undefined; if ( !flagResolver.isEnabled('responseTimeWithAppNameKillSwitch') && (instanceStatsService.getAppCountSnapshot('7d') ?? diff --git a/src/lib/middleware/session-db.ts b/src/lib/middleware/session-db.ts index 63bd0b668a..dc4fc93dfb 100644 --- a/src/lib/middleware/session-db.ts +++ b/src/lib/middleware/session-db.ts @@ -9,7 +9,7 @@ function sessionDb( config: Pick, knex: Knex, ): RequestHandler { - let store; + let store: session.Store; const { db, cookieName } = config.session; const age = hoursToMilliseconds(config.session.ttlHours) || hoursToMilliseconds(48); diff --git a/src/lib/routes/admin-api/api-token.ts b/src/lib/routes/admin-api/api-token.ts index a494c28590..dabd6ad2a1 100644 --- a/src/lib/routes/admin-api/api-token.ts +++ b/src/lib/routes/admin-api/api-token.ts @@ -338,7 +338,7 @@ export class ApiTokenController extends Controller { this.logger.error(req.body); return res.status(400).send(); } - let tokenToUpdate; + let tokenToUpdate: IApiToken | undefined; try { tokenToUpdate = await this.apiTokenService.getToken(token); } catch (error) {} @@ -374,7 +374,7 @@ export class ApiTokenController extends Controller { res: Response, ): Promise { const { token } = req.params; - let tokenToUpdate; + let tokenToUpdate: IApiToken | undefined; try { tokenToUpdate = await this.apiTokenService.getToken(token); } catch (error) {} diff --git a/src/lib/routes/admin-api/config.test.ts b/src/lib/routes/admin-api/config.test.ts index a73025a887..9a3395194f 100644 --- a/src/lib/routes/admin-api/config.test.ts +++ b/src/lib/routes/admin-api/config.test.ts @@ -31,8 +31,8 @@ async function getSetup() { }; } -let request; -let base; +let request: supertest.SuperTest; +let base: string; beforeEach(async () => { const setup = await getSetup(); diff --git a/src/lib/routes/admin-api/context.test.ts b/src/lib/routes/admin-api/context.test.ts index 0a584ad332..58baeb2fc9 100644 --- a/src/lib/routes/admin-api/context.test.ts +++ b/src/lib/routes/admin-api/context.test.ts @@ -23,8 +23,8 @@ async function getSetup() { }; } -let base; -let request; +let base: string; +let request: supertest.SuperTest; beforeEach(async () => { const setup = await getSetup(); diff --git a/src/lib/routes/admin-api/metrics.test.ts b/src/lib/routes/admin-api/metrics.test.ts index 2b704b7249..562ff2f041 100644 --- a/src/lib/routes/admin-api/metrics.test.ts +++ b/src/lib/routes/admin-api/metrics.test.ts @@ -4,6 +4,7 @@ import permissions from '../../../test/fixtures/permissions'; import getApp from '../../app'; import { createTestConfig } from '../../../test/config/test-config'; import { createServices } from '../../services'; +import { IUnleashStores } from '../../types'; async function getSetup() { const stores = createStores(); @@ -22,8 +23,8 @@ async function getSetup() { }; } -let stores; -let request; +let stores: IUnleashStores; +let request: supertest.SuperTest; beforeEach(async () => { const setup = await getSetup(); diff --git a/src/lib/routes/admin-api/public-signup.test.ts b/src/lib/routes/admin-api/public-signup.test.ts index be0bb80135..7980d4abac 100644 --- a/src/lib/routes/admin-api/public-signup.test.ts +++ b/src/lib/routes/admin-api/public-signup.test.ts @@ -5,6 +5,7 @@ import getApp from '../../app'; import supertest from 'supertest'; import permissions from '../../../test/fixtures/permissions'; import { RoleName, RoleType } from '../../types/model'; +import { IUnleashStores } from '../../types'; describe('Public Signup API', () => { async function getSetup() { @@ -36,8 +37,8 @@ describe('Public Signup API', () => { }; } - let stores; - let request; + let stores: IUnleashStores; + let request: supertest.SuperTest; const user = { username: 'some-username', @@ -67,7 +68,11 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); - stores.roleStore.create({ name: RoleName.VIEWER }); + stores.roleStore.create({ + description: '', + roleType: '', + name: RoleName.VIEWER, + }); const bodyCreate = createBody(); const res = await request @@ -86,8 +91,11 @@ describe('Public Signup API', () => { expect.assertions(2); const appName = '123!23'; - stores.clientApplicationsStore.upsert({ appName }); - stores.publicSignupTokenStore.insert({ + await stores.clientApplicationsStore.upsert({ appName }); + await stores.publicSignupTokenStore.insert({ + roleId: 0, + secret: '', + url: '', name: 'some-name', expiresAt: expireAt(), createdBy: 'johnDoe', @@ -108,6 +116,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - hacked in via fake store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), @@ -127,6 +136,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - hacked in via fake store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), @@ -151,6 +161,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - hacked in via fake store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), @@ -170,6 +181,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - hacked in via fake store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), diff --git a/src/lib/routes/admin-api/state.ts b/src/lib/routes/admin-api/state.ts index aeea572cdf..7b513bca5c 100644 --- a/src/lib/routes/admin-api/state.ts +++ b/src/lib/routes/admin-api/state.ts @@ -102,6 +102,7 @@ class StateController extends Controller { const userName = extractUsername(req); const { drop, keep } = req.query; // TODO: Should override request type so file is a type on request + // biome-ignore lint/suspicious/noImplicitAnyLet: let data; // @ts-expect-error if (req.file) { diff --git a/src/lib/routes/admin-api/tag.test.ts b/src/lib/routes/admin-api/tag.test.ts index 5a0b2169ca..a375752374 100644 --- a/src/lib/routes/admin-api/tag.test.ts +++ b/src/lib/routes/admin-api/tag.test.ts @@ -4,6 +4,7 @@ import permissions from '../../../test/fixtures/permissions'; import getApp from '../../app'; import { createTestConfig } from '../../../test/config/test-config'; import { createServices } from '../../services'; +import { ITagStore } from '../../types'; async function getSetup() { const base = `/random${Math.round(Math.random() * 1000)}`; @@ -24,9 +25,9 @@ async function getSetup() { }; } -let base; -let tagStore; -let request; +let base: string; +let tagStore: ITagStore; +let request: supertest.SuperTest; beforeEach(async () => { const setup = await getSetup(); diff --git a/src/lib/routes/client-api/metrics.test.ts b/src/lib/routes/client-api/metrics.test.ts index 7b32686ccc..144207a30e 100644 --- a/src/lib/routes/client-api/metrics.test.ts +++ b/src/lib/routes/client-api/metrics.test.ts @@ -9,11 +9,11 @@ import { IUnleashServices, IUnleashStores, } from '../../types'; -import dbInit from '../../../test/e2e/helpers/database-init'; +import dbInit, { ITestDb } from '../../../test/e2e/helpers/database-init'; import { subMinutes } from 'date-fns'; import { ApiTokenType } from '../../types/models/api-token'; -let db; +let db: ITestDb; async function getSetup(opts?: IUnleashOptions) { const config = createTestConfig(opts); @@ -30,10 +30,10 @@ async function getSetup(opts?: IUnleashOptions) { }; } -let request; +let request: supertest.SuperTest; let stores: IUnleashStores; let services: IUnleashServices; -let destroy; +let destroy: () => Promise; beforeAll(async () => { const setup = await getSetup(); @@ -43,8 +43,8 @@ beforeAll(async () => { services = setup.services; }); -afterAll(() => { - destroy(); +afterAll(async () => { + await destroy(); }); afterEach(async () => { diff --git a/src/lib/routes/client-api/register.test.ts b/src/lib/routes/client-api/register.test.ts index 6ed4f66a78..db0a667e32 100644 --- a/src/lib/routes/client-api/register.test.ts +++ b/src/lib/routes/client-api/register.test.ts @@ -16,7 +16,7 @@ async function getSetup() { stores, }; } -let request; +let request: supertest.SuperTest; beforeEach(async () => { const setup = await getSetup(); request = setup.request; diff --git a/src/lib/routes/controller.ts b/src/lib/routes/controller.ts index 092ccee797..db0c8e56df 100644 --- a/src/lib/routes/controller.ts +++ b/src/lib/routes/controller.ts @@ -39,7 +39,8 @@ interface IRouteOptionsNonGet extends IRouteOptionsBase { type IRouteOptions = IRouteOptionsNonGet | IRouteOptionsGet; const checkPermission = - (permission: Permission = []) => async (req, res, next) => { + (permission: Permission = []) => + async (req, res, next) => { const permissions = ( Array.isArray(permission) ? permission : [permission] ).filter((p) => p !== NONE); diff --git a/src/lib/routes/health-check.test.ts b/src/lib/routes/health-check.test.ts index a9b0ec657d..a7d26d65d2 100644 --- a/src/lib/routes/health-check.test.ts +++ b/src/lib/routes/health-check.test.ts @@ -17,7 +17,7 @@ async function getSetup() { stores, }; } -let request; +let request: supertest.SuperTest; beforeEach(async () => { const setup = await getSetup(); request = setup.request; diff --git a/src/lib/routes/public-invite.test.ts b/src/lib/routes/public-invite.test.ts index cd511aaa8d..99507e2fe8 100644 --- a/src/lib/routes/public-invite.test.ts +++ b/src/lib/routes/public-invite.test.ts @@ -5,6 +5,7 @@ import getApp from '../app'; import supertest from 'supertest'; import permissions from '../../test/fixtures/permissions'; import { RoleName, RoleType } from '../types/model'; +import { IUnleashStores } from 'lib/types'; describe('Public Signup API', () => { async function getSetup() { @@ -49,8 +50,8 @@ describe('Public Signup API', () => { }; } - let stores; - let request; + let stores: IUnleashStores; + let request: supertest.SuperTest; const user = { username: 'some-username', @@ -81,6 +82,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - This method is available on our fake store, but not our real store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), @@ -103,6 +105,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - We need more fields, but since this is a test. we get away with this call stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), @@ -129,14 +132,15 @@ describe('Public Signup API', () => { test('should not be able to send root role in signup request body', async () => { const appName = '123!23'; - stores.clientApplicationsStore.upsert({ appName }); - stores.publicSignupTokenStore.create({ + await stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - We need more fields, but since this is a test. we get away with this call + await stores.publicSignupTokenStore.insert({ name: 'some-name', expiresAt: expireAt(), }); const roles = await stores.roleStore.getAll(); - const adminId = roles.find((role) => role.name === RoleName.ADMIN).id; + const adminId = roles.find((role) => role.name === RoleName.ADMIN)!.id; return request .post('/invite/some-secret/signup') @@ -148,6 +152,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - This method is available on our fake store, but not our real store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(-1), @@ -163,6 +168,7 @@ describe('Public Signup API', () => { const appName = '123!23'; stores.clientApplicationsStore.upsert({ appName }); + // @ts-expect-error - This method is available on our fake store, but not our real store stores.publicSignupTokenStore.create({ name: 'some-name', expiresAt: expireAt(), diff --git a/src/lib/services/client-metrics/instance-service.test.ts b/src/lib/services/client-metrics/instance-service.test.ts index 4c5dbed0ce..e8802fcd13 100644 --- a/src/lib/services/client-metrics/instance-service.test.ts +++ b/src/lib/services/client-metrics/instance-service.test.ts @@ -3,8 +3,12 @@ import { IClientApp } from '../../types/model'; import FakeEventStore from '../../../test/fixtures/fake-event-store'; import { createTestConfig } from '../../../test/config/test-config'; import { FakePrivateProjectChecker } from '../../features/private-project/fakePrivateProjectChecker'; +import { IUnleashConfig } from '../../types'; +import FakeClientMetricsStoreV2 from '../../../test/fixtures/fake-client-metrics-store-v2'; +import FakeStrategiesStore from '../../../test/fixtures/fake-strategies-store'; +import FakeFeatureToggleStore from '../../features/feature-toggle/fakes/fake-feature-toggle-store'; -let config; +let config: IUnleashConfig; beforeAll(() => { config = createTestConfig({}); }); @@ -19,9 +23,9 @@ test('Multiple registrations of same appname and instanceid within same time per }; const clientMetrics = new ClientInstanceService( { - clientMetricsStoreV2: null, - strategyStore: null, - featureToggleStore: null, + clientMetricsStoreV2: new FakeClientMetricsStoreV2(), + strategyStore: new FakeStrategiesStore(), + featureToggleStore: new FakeFeatureToggleStore(), clientApplicationsStore, clientInstanceStore, eventStore: new FakeEventStore(), @@ -69,9 +73,9 @@ test('Multiple unique clients causes multiple registrations', async () => { const clientMetrics = new ClientInstanceService( { - clientMetricsStoreV2: null, - strategyStore: null, - featureToggleStore: null, + clientMetricsStoreV2: new FakeClientMetricsStoreV2(), + strategyStore: new FakeStrategiesStore(), + featureToggleStore: new FakeFeatureToggleStore(), clientApplicationsStore, clientInstanceStore, eventStore: new FakeEventStore(), @@ -119,9 +123,9 @@ test('Same client registered outside of dedup interval will be registered twice' const clientMetrics = new ClientInstanceService( { - clientMetricsStoreV2: null, - strategyStore: null, - featureToggleStore: null, + clientMetricsStoreV2: new FakeClientMetricsStoreV2(), + strategyStore: new FakeStrategiesStore(), + featureToggleStore: new FakeFeatureToggleStore(), clientApplicationsStore, clientInstanceStore, eventStore: new FakeEventStore(), @@ -169,9 +173,9 @@ test('No registrations during a time period will not call stores', async () => { }; const clientMetrics = new ClientInstanceService( { - clientMetricsStoreV2: null, - strategyStore: null, - featureToggleStore: null, + clientMetricsStoreV2: new FakeClientMetricsStoreV2(), + strategyStore: new FakeStrategiesStore(), + featureToggleStore: new FakeFeatureToggleStore(), clientApplicationsStore, clientInstanceStore, eventStore: new FakeEventStore(), diff --git a/src/lib/services/context-service.ts b/src/lib/services/context-service.ts index 2e59ec0787..554cd94869 100644 --- a/src/lib/services/context-service.ts +++ b/src/lib/services/context-service.ts @@ -164,7 +164,7 @@ class ContextService { async validateUniqueName({ name, }: Pick): Promise { - let msg; + let msg: string | undefined; try { await this.contextFieldStore.get(name); msg = 'A context field with that name already exist'; diff --git a/src/lib/services/reset-token-service.ts b/src/lib/services/reset-token-service.ts index efc5a32df8..7116128a24 100644 --- a/src/lib/services/reset-token-service.ts +++ b/src/lib/services/reset-token-service.ts @@ -66,7 +66,7 @@ export default class ResetTokenService { }; async isValid(token: string): Promise { - let t; + let t: IResetToken; try { t = await this.store.getActive(token); if (!t.usedAt) { diff --git a/src/lib/services/scheduler-service.test.ts b/src/lib/services/scheduler-service.test.ts index 344856f88b..7f96f80ac8 100644 --- a/src/lib/services/scheduler-service.test.ts +++ b/src/lib/services/scheduler-service.test.ts @@ -6,7 +6,7 @@ import SettingService from './setting-service'; import EventService from './event-service'; import MaintenanceService from '../features/maintenance/maintenance-service'; -function ms(timeMs) { +function ms(timeMs: number) { return new Promise((resolve) => setTimeout(resolve, timeMs)); } @@ -29,7 +29,7 @@ const getLogger = () => { }; let schedulerService: SchedulerService; -let getRecords; +let getRecords: () => any[]; beforeEach(() => { const config = createTestConfig(); diff --git a/src/lib/services/state-service.ts b/src/lib/services/state-service.ts index b548e26bfd..a03d78559c 100644 --- a/src/lib/services/state-service.ts +++ b/src/lib/services/state-service.ts @@ -205,6 +205,7 @@ export default class StateService { } if (importData.features) { + // biome-ignore lint/suspicious/noImplicitAnyLet: too many formats to consider here. Allowing this to be any let projectData; if (!importData.version || importData.version === 1) { projectData = await this.convertLegacyFeatures(importData); diff --git a/src/lib/services/state-util.ts b/src/lib/services/state-util.ts index 38993efece..730521c2a2 100644 --- a/src/lib/services/state-util.ts +++ b/src/lib/services/state-util.ts @@ -17,16 +17,19 @@ export const parseFile: (file: string, data: string) => any = ( export const filterExisting: ( keepExisting: boolean, existingArray: any[], -) => (item: any) => boolean = (keepExisting, existingArray = []) => (item) => { - if (keepExisting) { - const found = existingArray.find((t) => t.name === item.name); - return !found; - } - return true; -}; +) => (item: any) => boolean = + (keepExisting, existingArray = []) => + (item) => { + if (keepExisting) { + const found = existingArray.find((t) => t.name === item.name); + return !found; + } + return true; + }; export const filterEqual: (existingArray: any[]) => (item: any) => boolean = - (existingArray = []) => (item) => { + (existingArray = []) => + (item) => { const toggle = existingArray.find((t) => t.name === item.name); if (toggle) { return JSON.stringify(toggle) !== JSON.stringify(item); diff --git a/src/lib/services/user-service.ts b/src/lib/services/user-service.ts index 68391fc819..8044df29ff 100644 --- a/src/lib/services/user-service.ts +++ b/src/lib/services/user-service.ts @@ -317,7 +317,7 @@ class UserService { ? { email: usernameOrEmail } : { username: usernameOrEmail }; - let user, passwordHash; + let user: IUser | undefined, passwordHash: string | undefined; try { user = await this.store.getByQuery(idQuery); passwordHash = await this.store.getPasswordHash(user.id); diff --git a/src/lib/types/models/api-token.ts b/src/lib/types/models/api-token.ts index e0f0ef1648..7d2f240126 100644 --- a/src/lib/types/models/api-token.ts +++ b/src/lib/types/models/api-token.ts @@ -53,7 +53,7 @@ export const mapLegacyProjects = ( project?: string, projects?: string[], ): string[] => { - let cleanedProjects; + let cleanedProjects: string[]; if (project) { cleanedProjects = [project]; } else if (projects) { @@ -76,7 +76,7 @@ export const mapLegacyToken = ( return { tokenName: token.username ?? token.tokenName!, type: token.type, - environment: token.environment, + environment: token.environment || 'development', projects: cleanedProjects, expiresAt: token.expiresAt, }; diff --git a/src/lib/util/omit-keys.ts b/src/lib/util/omit-keys.ts index ded3ad4bc3..5268fbe7f2 100644 --- a/src/lib/util/omit-keys.ts +++ b/src/lib/util/omit-keys.ts @@ -1,5 +1,8 @@ export interface OmitKeys { - (obj: T, ...keys: K): { + ( + obj: T, + ...keys: K + ): { [K2 in Exclude]: T[K2]; }; } diff --git a/src/lib/util/timer.test.ts b/src/lib/util/timer.test.ts index 92e69d97fd..0ab2fe6fd7 100644 --- a/src/lib/util/timer.test.ts +++ b/src/lib/util/timer.test.ts @@ -19,7 +19,7 @@ test('should calculate the correct time in seconds', () => { test('timer should track the time', async () => { jest.useFakeTimers(); const tt = timer.new(); - let diff; + let diff: number | undefined; timeout(() => { diff = tt(); }, 20); diff --git a/src/test/e2e/api/admin/addon.e2e.test.ts b/src/test/e2e/api/admin/addon.e2e.test.ts index 595de3cf21..acf604ede0 100644 --- a/src/test/e2e/api/admin/addon.e2e.test.ts +++ b/src/test/e2e/api/admin/addon.e2e.test.ts @@ -1,11 +1,14 @@ -import dbInit from '../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; const MASKED_VALUE = '*****'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('addon_api_serial', getLogger); @@ -104,11 +107,11 @@ test('should update addon configuration', async () => { const { id } = res.body; const updatedConfig = { + ...config, parameters: { url: 'http://example.com', bodyTemplate: "{'name': '{{event.data.name}}' }", }, - ...config, }; await app.request 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 167e8a3d86..532c9eaa5a 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 @@ -1,5 +1,5 @@ import { setupAppWithCustomAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { ApiTokenType } from '../../../../lib/types/models/api-token'; import { RoleName } from '../../../../lib/types/model'; @@ -7,6 +7,7 @@ import { CREATE_CLIENT_API_TOKEN, CREATE_PROJECT_API_TOKEN, DELETE_CLIENT_API_TOKEN, + IUnleashStores, READ_CLIENT_API_TOKEN, READ_FRONTEND_API_TOKEN, SYSTEM_USER_ID, @@ -15,8 +16,8 @@ import { import { addDays } from 'date-fns'; import { AccessService, UserService } from 'lib/services'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { db = await dbInit('token_api_auth_serial', getLogger); @@ -51,18 +52,27 @@ test('editor users should only get client or frontend tokens', async () => { const { request, destroy } = await setupAppWithCustomAuth(stores, preHook); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'test', secret: '1234', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontend', secret: '12345', type: ApiTokenType.FRONTEND, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'test', secret: 'sdfsdf2d', type: ApiTokenType.ADMIN, @@ -99,12 +109,18 @@ test('viewer users should not be allowed to fetch tokens', async () => { const { request, destroy } = await setupAppWithCustomAuth(stores, preHook); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'test', secret: '1234', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'test', secret: 'sdfsdf2d', type: ApiTokenType.ADMIN, @@ -402,17 +418,27 @@ describe('Fine grained API token permissions', () => { preHook, ); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', + username: 'client', secret: 'client_secret', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'admin', secret: 'sdfsdf2admin_secret', type: ApiTokenType.ADMIN, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontender', secret: 'sdfsdf2dfrontend_Secret', type: ApiTokenType.FRONTEND, @@ -464,17 +490,26 @@ describe('Fine grained API token permissions', () => { preHook, ); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'client', secret: 'client_secret_1234', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'admin', secret: 'admin_secret_1234', type: ApiTokenType.ADMIN, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontender', secret: 'frontend_secret_1234', type: ApiTokenType.FRONTEND, @@ -508,17 +543,26 @@ describe('Fine grained API token permissions', () => { preHook, ); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'client', secret: 'client_secret_4321', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'admin', secret: 'admin_secret_4321', type: ApiTokenType.ADMIN, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontender', secret: 'frontend_secret_4321', type: ApiTokenType.FRONTEND, @@ -551,16 +595,25 @@ describe('Fine grained API token permissions', () => { preHook, ); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'client', secret: 'client_secret_4321', type: ApiTokenType.CLIENT, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'admin', secret: 'admin_secret_4321', type: ApiTokenType.ADMIN, }); await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontender', secret: 'frontend_secret_4321', type: ApiTokenType.FRONTEND, @@ -621,6 +674,9 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'cilent', secret: 'update_client_token', type: ApiTokenType.CLIENT, @@ -670,6 +726,9 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontend', secret: 'update_frontend_token', type: ApiTokenType.FRONTEND, @@ -720,6 +779,10 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', + username: 'admin', secret: 'update_admin_token', type: ApiTokenType.ADMIN, @@ -773,6 +836,9 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'cilent', secret: 'delete_client_token', type: ApiTokenType.CLIENT, @@ -822,6 +888,9 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'frontend', secret: 'delete_frontend_token', type: ApiTokenType.FRONTEND, @@ -871,6 +940,9 @@ describe('Fine grained API token permissions', () => { preHook, ); const token = await stores.apiTokenStore.insert({ + environment: '', + projects: [], + tokenName: '', username: 'admin', secret: 'delete_admin_token', type: ApiTokenType.ADMIN, 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 34ba4fd458..e6c43f9434 100644 --- a/src/test/e2e/api/admin/api-token.e2e.test.ts +++ b/src/test/e2e/api/admin/api-token.e2e.test.ts @@ -1,12 +1,15 @@ -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { ALL, ApiTokenType } from '../../../../lib/types/models/api-token'; import { DEFAULT_ENV } from '../../../../lib/util'; import { addDays } from 'date-fns'; -let db; -let app; +let db: ITestDb; +let app: IUnleashTest; beforeAll(async () => { db = await dbInit('token_api_serial', getLogger); @@ -123,8 +126,11 @@ test('update client token with expiry', async () => { await db.stores.apiTokenStore.insert({ username: 'test', + projects: ['*'], + tokenName: 'test_token', secret: tokenSecret, type: ApiTokenType.CLIENT, + environment: 'development', }); await app.request @@ -184,6 +190,9 @@ test('removes api token', async () => { const tokenSecret = 'random-secret'; await db.stores.apiTokenStore.insert({ + environment: 'development', + projects: ['*'], + tokenName: 'testtoken', username: 'test', secret: tokenSecret, type: ApiTokenType.CLIENT, 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 5f8b157e94..420d65fda9 100644 --- a/src/test/e2e/api/admin/client-metrics.e2e.test.ts +++ b/src/test/e2e/api/admin/client-metrics.e2e.test.ts @@ -1,10 +1,13 @@ import dbInit, { ITestDb } from '../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; import { IClientMetricsEnv } from '../../../../lib/types/stores/client-metrics-store-v2'; import { subHours } from 'date-fns'; -let app; +let app: IUnleashTest; let db: ITestDb; const fetchHoursBack = (hoursBack: number, feature: string = 'demo') => { diff --git a/src/test/e2e/api/admin/constraints.e2e.test.ts b/src/test/e2e/api/admin/constraints.e2e.test.ts index 009f1a65f0..b6fac62c47 100644 --- a/src/test/e2e/api/admin/constraints.e2e.test.ts +++ b/src/test/e2e/api/admin/constraints.e2e.test.ts @@ -1,9 +1,12 @@ -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; const PATH = '/api/admin/constraints/validate'; diff --git a/src/test/e2e/api/admin/context.e2e.test.ts b/src/test/e2e/api/admin/context.e2e.test.ts index 95b630e910..8c7a78b1b0 100644 --- a/src/test/e2e/api/admin/context.e2e.test.ts +++ b/src/test/e2e/api/admin/context.e2e.test.ts @@ -1,11 +1,11 @@ -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import { IUnleashTest, setupAppWithCustomConfig, } from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; -let db; +let db: ITestDb; let app: IUnleashTest; beforeAll(async () => { diff --git a/src/test/e2e/api/admin/favorites.e2e.test.ts b/src/test/e2e/api/admin/favorites.e2e.test.ts index 84e8a50151..0002715abd 100644 --- a/src/test/e2e/api/admin/favorites.e2e.test.ts +++ b/src/test/e2e/api/admin/favorites.e2e.test.ts @@ -3,12 +3,13 @@ import { IUnleashStores, RoleName } from '../../../../lib/types'; import { AccessService } from '../../../../lib/services'; import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; +import { IRole } from '../../../../lib/types/stores/access-store'; let app: IUnleashTest; let db: ITestDb; let stores: IUnleashStores; let accessService: AccessService; -let editorRole; +let editorRole: IRole; const regularUserName = 'favorites-user'; @@ -96,7 +97,7 @@ beforeAll(async () => { accessService = app.services.accessService; const roles = await accessService.getRootRoles(); - editorRole = roles.find((role) => role.name === RoleName.EDITOR); + editorRole = roles.find((role) => role.name === RoleName.EDITOR)!; await createUserEditorAccess( regularUserName, diff --git a/src/test/e2e/api/admin/feature-type.test.ts b/src/test/e2e/api/admin/feature-type.test.ts index 4b61e8d45c..78a7ac66db 100644 --- a/src/test/e2e/api/admin/feature-type.test.ts +++ b/src/test/e2e/api/admin/feature-type.test.ts @@ -1,4 +1,4 @@ -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { IUnleashTest, @@ -8,7 +8,7 @@ import { validateSchema } from '../../../../lib/openapi/validate'; import { featureTypesSchema } from '../../../../lib/openapi/spec/feature-types-schema'; let app: IUnleashTest; -let db; +let db: ITestDb; beforeAll(async () => { db = await dbInit('feature_type_api_serial', getLogger); 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 9d635bc127..3d8d938a80 100644 --- a/src/test/e2e/api/admin/feature.auth.e2e.test.ts +++ b/src/test/e2e/api/admin/feature.auth.e2e.test.ts @@ -1,8 +1,8 @@ import { setupAppWithAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; -let db; +let db: ITestDb; beforeAll(async () => { db = await dbInit('feature_api_auth', getLogger); 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 535213ae44..451a7590ec 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 @@ -1,11 +1,12 @@ import { setupAppWithCustomAuth } from '../../helpers/test-helper'; import AuthenticationRequired from '../../../../lib/types/authentication-required'; -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; +import { IUnleashStores } from '../../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { db = await dbInit('feature_api_custom_auth', getLogger); diff --git a/src/test/e2e/api/admin/feedback.e2e.test.ts b/src/test/e2e/api/admin/feedback.e2e.test.ts index cc57a597df..043f7bed49 100644 --- a/src/test/e2e/api/admin/feedback.e2e.test.ts +++ b/src/test/e2e/api/admin/feedback.e2e.test.ts @@ -1,13 +1,17 @@ import { Application, NextFunction, Request, Response } from 'express'; -import { setupAppWithCustomAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomAuth, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { IUnleashConfig } from '../../../../lib/types/option'; import { IUnleashServices } from '../../../../lib/types/services'; +import { IUnleashStores } from '../../../../lib/types'; -let stores; -let db; -let app; +let stores: IUnleashStores; +let db: ITestDb; +let app: IUnleashTest; beforeAll(async () => { db = await dbInit('feedback_api_serial', getLogger); diff --git a/src/test/e2e/api/admin/instance-admin.e2e.test.ts b/src/test/e2e/api/admin/instance-admin.e2e.test.ts index dea3000a5f..66a5777d76 100644 --- a/src/test/e2e/api/admin/instance-admin.e2e.test.ts +++ b/src/test/e2e/api/admin/instance-admin.e2e.test.ts @@ -1,10 +1,10 @@ -import dbInit from '../../helpers/database-init'; -import { setupApp } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; +import { IUnleashTest, setupApp } from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; import { IUnleashStores } from '../../../../lib/types'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; let stores: IUnleashStores; beforeAll(async () => { diff --git a/src/test/e2e/api/admin/project/api-token.e2e.test.ts b/src/test/e2e/api/admin/project/api-token.e2e.test.ts index d0dbf76957..5b527a7d89 100644 --- a/src/test/e2e/api/admin/project/api-token.e2e.test.ts +++ b/src/test/e2e/api/admin/project/api-token.e2e.test.ts @@ -1,12 +1,15 @@ -import dbInit from '../../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../../helpers/test-helper'; import getLogger from '../../../../fixtures/no-logger'; -import { ApiTokenStore } from '../../../../../lib/db/api-token-store'; +import { IApiTokenStore } from '../../../../../lib/types'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; -let apiTokenStore: ApiTokenStore; +let apiTokenStore: IApiTokenStore; beforeAll(async () => { db = await dbInit('projects_api_serial', getLogger); 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 5a7a6c4818..a5cd1c0896 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 @@ -1,10 +1,14 @@ -import dbInit from '../../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../../helpers/test-helper'; import getLogger from '../../../../fixtures/no-logger'; +import { IUser } from '../../../../../lib/types'; -let app; -let db; -let user; +let app: IUnleashTest; +let db: ITestDb; +let user: IUser; beforeAll(async () => { db = await dbInit('project_health_api_serial', getLogger); 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 7af09f0e21..6bd7226d6e 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 @@ -1,14 +1,15 @@ import { setupAppWithCustomAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { RoleName } from '../../../../lib/types/model'; import { PublicSignupTokenCreateSchema } from '../../../../lib/openapi/spec/public-signup-token-create-schema'; +import { IUnleashStores } from '../../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { - db = await dbInit('test', getLogger); + db = await dbInit('public_signup_test', getLogger); stores = db.stores; }); @@ -82,10 +83,10 @@ test('no permission to validate a token', async () => { const { request, destroy } = await setupAppWithCustomAuth(stores, preHook); await stores.publicSignupTokenStore.insert({ + url: 'http://localhost:4242/invite/some-secret/signup', name: 'some-name', expiresAt: expireAt(), secret: 'some-secret', - createAt: new Date(), createdBy: 'admin@example.com', roleId: 3, }); @@ -136,7 +137,6 @@ test('users can signup with invite-link', async () => { expiresAt: expireAt(), secret: 'some-secret', url: 'http://localhost:4242/invite/some-secret/signup', - createAt: new Date(), createdBy: 'admin@example.com', roleId: 3, }); @@ -177,10 +177,10 @@ test('can get a token with users', async () => { const { request, destroy } = await setupAppWithCustomAuth(stores, preHook); await stores.publicSignupTokenStore.insert({ + url: 'http://localhost:4242/invite/some-secret', name: 'some-name', expiresAt: expireAt(), secret: 'some-secret', - createAt: new Date(), createdBy: 'admin@example.com', roleId: 3, }); @@ -188,9 +188,6 @@ test('can get a token with users', async () => { const user = await stores.userStore.insert({ username: 'some-username', email: 'some@example.com', - password: 'eweggwEG', - sendEmail: false, - rootRole: 3, }); await stores.publicSignupTokenStore.addTokenUser('some-secret', user.id); diff --git a/src/test/e2e/api/admin/segment.e2e.test.ts b/src/test/e2e/api/admin/segment.e2e.test.ts index a237a5afd1..2d1c330a7c 100644 --- a/src/test/e2e/api/admin/segment.e2e.test.ts +++ b/src/test/e2e/api/admin/segment.e2e.test.ts @@ -12,6 +12,7 @@ import { setupAppWithCustomConfig, } from '../../helpers/test-helper'; import { StrategiesUsingSegment } from 'lib/segments/segment-service-interface'; +import { IUser } from '../../../../lib/types'; let app: IUnleashTest; let db: ITestDb; @@ -556,12 +557,12 @@ test('Should show usage in features and projects', async () => { describe('detect strategy usage in change requests', () => { const CR_TITLE = 'My change request'; const CR_ID = 54321; - let user; + let user: IUser; // Change request data is only counted for enterprise // instances, so we'll instantiate our own version of the app // for that. - let enterpriseApp; + let enterpriseApp: IUnleashTest; // likewise, we want to fetch from the right app to make sure // we get the right data @@ -611,7 +612,7 @@ describe('detect strategy usage in change requests', () => { }); }); afterAll(async () => { - user = await db.stores.userStore.delete(user.id); + await db.stores.userStore.delete(user.id); await db.rawDatabase.table('change_requests').delete(); }); diff --git a/src/test/e2e/api/admin/splash.e2e.test.ts b/src/test/e2e/api/admin/splash.e2e.test.ts index 8963b3ba9f..256e37df9c 100644 --- a/src/test/e2e/api/admin/splash.e2e.test.ts +++ b/src/test/e2e/api/admin/splash.e2e.test.ts @@ -1,13 +1,17 @@ import { Application, NextFunction, Request, Response } from 'express'; -import { setupAppWithCustomAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomAuth, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { IUnleashConfig } from '../../../../lib/types/option'; import { IUnleashServices } from '../../../../lib/types/services'; +import { IUnleashStores } from '../../../../lib/types'; -let stores; -let db; -let app; +let stores: IUnleashStores; +let db: ITestDb; +let app: IUnleashTest; beforeAll(async () => { db = await dbInit('splash_api_serial', getLogger); diff --git a/src/test/e2e/api/admin/strategy.e2e.test.ts b/src/test/e2e/api/admin/strategy.e2e.test.ts index 5d8cbe2522..b2acd1cc66 100644 --- a/src/test/e2e/api/admin/strategy.e2e.test.ts +++ b/src/test/e2e/api/admin/strategy.e2e.test.ts @@ -1,9 +1,12 @@ -import dbInit from '../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('strategy_api_serial', getLogger); diff --git a/src/test/e2e/api/admin/tags.e2e.test.ts b/src/test/e2e/api/admin/tags.e2e.test.ts index 3a5dc88344..a5bfe26bf4 100644 --- a/src/test/e2e/api/admin/tags.e2e.test.ts +++ b/src/test/e2e/api/admin/tags.e2e.test.ts @@ -1,9 +1,12 @@ -import dbInit from '../../helpers/database-init'; -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('tag_api_serial', getLogger); @@ -128,7 +131,7 @@ test('Can tag features', async () => { }); await db.stores.tagStore.createTag(removedTag); - await db.stores.featureTagStore.tagFeature(featureName, removedTag); + await db.stores.featureTagStore.tagFeature(featureName, removedTag, -1337); const initialTagState = await app.request.get( `/api/admin/features/${featureName}/tags`, 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 d2a0adb532..174f9e4bc0 100644 --- a/src/test/e2e/api/admin/user-admin.e2e.test.ts +++ b/src/test/e2e/api/admin/user-admin.e2e.test.ts @@ -1,5 +1,8 @@ -import { setupAppWithCustomConfig } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { USER_CREATED, @@ -14,10 +17,11 @@ import { IRoleStore } from 'lib/types/stores/role-store'; import { randomId } from '../../../../lib/util/random-id'; import { omitKeys } from '../../../../lib/util/omit-keys'; import { ISessionStore } from '../../../../lib/types/stores/session-store'; +import { IUnleashStores } from '../../../../lib/types'; -let stores; -let db; -let app; +let stores: IUnleashStores; +let db: ITestDb; +let app: IUnleashTest; let userStore: IUserStore; let eventStore: IEventStore; @@ -383,7 +387,7 @@ test('Anonymises name, username and email fields if anonymiseEventLog flag is se const anonymisedApp = await setupAppWithCustomConfig( stores, { experimental: { flags: { anonymiseEventLog: true } } }, - db, + db.rawDatabase, ); await anonymisedApp.request .post('/api/admin/user-admin') 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 561eee3172..7bb27e07ed 100644 --- a/src/test/e2e/api/admin/user/pat.e2e.test.ts +++ b/src/test/e2e/api/admin/user/pat.e2e.test.ts @@ -10,8 +10,8 @@ let db: ITestDb; let patStore: IPatStore; const tomorrow = new Date(); -let firstSecret; -let firstId; +let firstSecret: string; +let firstId: string; tomorrow.setDate(tomorrow.getDate() + 1); beforeAll(async () => { @@ -282,10 +282,10 @@ test('should fail creation of PAT when PAT limit has been reached', async () => }) .expect(200); - const tokenCreations = []; + const tokenCreations: Promise[] = []; for (let i = 0; i < PAT_LIMIT; i++) { tokenCreations.push( - await app.request + app.request .post('/api/admin/user/tokens') .send({ description: `my pat ${i}`, diff --git a/src/test/e2e/api/admin/user/user.test.ts b/src/test/e2e/api/admin/user/user.test.ts index 401af655bb..ffb8144f2a 100644 --- a/src/test/e2e/api/admin/user/user.test.ts +++ b/src/test/e2e/api/admin/user/user.test.ts @@ -1,9 +1,9 @@ -import dbInit from '../../../helpers/database-init'; +import dbInit, { ITestDb } from '../../../helpers/database-init'; import getLogger from '../../../../fixtures/no-logger'; -import { setupAppWithAuth } from '../../../helpers/test-helper'; +import { IUnleashTest, setupAppWithAuth } from '../../../helpers/test-helper'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; const email = 'user@getunleash.io'; 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 25d176da6f..2261b5b30a 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 @@ -6,8 +6,12 @@ import UserService from '../../../../lib/services/user-service'; import { AccessService } from '../../../../lib/services/access-service'; import ResetTokenService from '../../../../lib/services/reset-token-service'; import { IUser } from '../../../../lib/types/user'; -import { setupApp, setupAppWithAuth } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupApp, + setupAppWithAuth, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { EmailService } from '../../../../lib/services/email-service'; import SessionStore from '../../../../lib/db/session-store'; @@ -17,10 +21,11 @@ import SettingService from '../../../../lib/services/setting-service'; import FakeSettingStore from '../../../fixtures/fake-setting-store'; import { GroupService } from '../../../../lib/services/group-service'; import { EventService } from '../../../../lib/services'; +import { IUnleashStores } from '../../../../lib/types'; -let app; -let stores; -let db; +let app: IUnleashTest; +let stores: IUnleashStores; +let db: ITestDb; const config: IUnleashConfig = createTestConfig({ getLogger, server: { @@ -59,7 +64,7 @@ beforeAll(async () => { ); const emailService = new EmailService(config); const sessionStore = new SessionStore( - db, + db.rawDatabase, new EventEmitter(), config.getLogger, ); @@ -129,7 +134,7 @@ test('Can use token to reset password', async () => { userService.loginUser(user.email!, password), ).rejects.toThrow(Error); - let token; + let token: string | undefined; await app.request .get(relative) .expect(200) @@ -154,7 +159,7 @@ test('Trying to reset password with same token twice does not work', async () => adminUser.username!, ); const relative = getBackendResetUrl(url); - let token; + let token: string | undefined; await app.request .get(relative) .expect(200) @@ -215,7 +220,7 @@ test('Calling reset endpoint with already existing session should logout/destroy adminUser.username!, ); const relative = getBackendResetUrl(url); - let token; + let token: string | undefined; await request .get(relative) .expect(200) @@ -258,7 +263,7 @@ test('Trying to change password to undefined should yield 400 without crashing t adminUser.username!, ); const relative = getBackendResetUrl(url); - let token; + let token: string | undefined; await app.request .get(relative) .expect(200) 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 c87f3c5481..054dd15946 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 @@ -1,10 +1,10 @@ import { createTestConfig } from '../../../config/test-config'; -import { IUnleashConfig } from '../../../../lib/types'; +import { IUnleashConfig, IUnleashStores } from '../../../../lib/types'; import UserService from '../../../../lib/services/user-service'; import { AccessService } from '../../../../lib/services/access-service'; import { IUser } from '../../../../lib/types/user'; -import { setupApp } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { IUnleashTest, setupApp } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import { EmailService } from '../../../../lib/services/email-service'; import SessionService from '../../../../lib/services/session-service'; @@ -14,9 +14,9 @@ import { GroupService } from '../../../../lib/services/group-service'; import ResetTokenService from '../../../../lib/services/reset-token-service'; import { EventService } from '../../../../lib/services'; -let app; -let stores; -let db; +let app: IUnleashTest; +let stores: IUnleashStores; +let db: ITestDb; const config: IUnleashConfig = createTestConfig({ getLogger, server: { diff --git a/src/test/e2e/api/client/metrics.e2e.test.ts b/src/test/e2e/api/client/metrics.e2e.test.ts index da9e7f07e8..67e436d092 100644 --- a/src/test/e2e/api/client/metrics.e2e.test.ts +++ b/src/test/e2e/api/client/metrics.e2e.test.ts @@ -1,10 +1,10 @@ -import { setupApp } from '../../helpers/test-helper'; +import { IUnleashTest, setupApp } from '../../helpers/test-helper'; import metricsExample from '../../../examples/client-metrics.json'; -import dbInit from '../../helpers/database-init'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('metrics_api_client', getLogger); diff --git a/src/test/e2e/api/client/metricsV2.e2e.test.ts b/src/test/e2e/api/client/metricsV2.e2e.test.ts index dc8a9b4b9f..3b19cf722b 100644 --- a/src/test/e2e/api/client/metricsV2.e2e.test.ts +++ b/src/test/e2e/api/client/metricsV2.e2e.test.ts @@ -2,22 +2,26 @@ import { IUnleashTest, setupAppWithAuth } from '../../helpers/test-helper'; import metricsExample from '../../../examples/client-metrics.json'; import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; -import { ApiTokenType } from '../../../../lib/types/models/api-token'; +import { + ApiTokenType, + IApiToken, +} from '../../../../lib/types/models/api-token'; let app: IUnleashTest; let db: ITestDb; -let defaultToken; +let defaultToken: IApiToken; const TEST_USER_ID = -9999; beforeAll(async () => { db = await dbInit('metrics_two_api_client', getLogger); app = await setupAppWithAuth(db.stores, {}, db.rawDatabase); - defaultToken = await app.services.apiTokenService.createApiToken({ - type: ApiTokenType.CLIENT, - project: 'default', - environment: 'default', - tokenName: 'tester', - }); + defaultToken = + await app.services.apiTokenService.createApiTokenWithProjects({ + type: ApiTokenType.CLIENT, + projects: ['default'], + environment: 'default', + tokenName: 'tester', + }); }); afterEach(async () => { diff --git a/src/test/e2e/api/client/register.e2e.test.ts b/src/test/e2e/api/client/register.e2e.test.ts index 3243c1fd09..6b0a173c96 100644 --- a/src/test/e2e/api/client/register.e2e.test.ts +++ b/src/test/e2e/api/client/register.e2e.test.ts @@ -1,6 +1,6 @@ import faker from 'faker'; -import { setupApp } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { IUnleashTest, setupApp } from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import version from '../../../../lib/util/version'; @@ -10,8 +10,8 @@ const asyncFilter = async (arr, predicate) => { return arr.filter((_v, index) => results[index]); }; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('register_client', getLogger); @@ -61,6 +61,7 @@ test('should allow client to register multiple times', async () => { .expect(202); jest.advanceTimersByTime(6000); + // @ts-expect-error - Incomplete client registration expect(clientApplicationsStore.exists(clientRegistration)).toBeTruthy(); expect(clientInstanceStore.exists(clientRegistration)).toBeTruthy(); jest.useRealTimers(); @@ -69,7 +70,17 @@ test('should allow client to register multiple times', async () => { test.skip('Should handle a massive bulk registration', async () => { const { clientInstanceStore, clientApplicationsStore } = db.stores; - const clients = []; + const clients: { + appName: string; + instanceId: string; + strategies: string[]; + started: number; + interval: number; + sdkVersion: string; + icon: string; + description: string; + color: string; + }[] = []; while (clients.length < 2000) { const clientRegistration = { appName: faker.internet.domainName(), diff --git a/src/test/e2e/api/openapi/openapi.e2e.test.ts b/src/test/e2e/api/openapi/openapi.e2e.test.ts index db6924c75f..0a21c327a8 100644 --- a/src/test/e2e/api/openapi/openapi.e2e.test.ts +++ b/src/test/e2e/api/openapi/openapi.e2e.test.ts @@ -1,13 +1,17 @@ -import { setupApp, setupAppWithBaseUrl } from '../../helpers/test-helper'; -import dbInit from '../../helpers/database-init'; +import { + IUnleashTest, + setupApp, + setupAppWithBaseUrl, +} from '../../helpers/test-helper'; +import dbInit, { ITestDb } from '../../helpers/database-init'; import getLogger from '../../../fixtures/no-logger'; import SwaggerParser from '@apidevtools/swagger-parser'; import enforcer from 'openapi-enforcer'; import semver from 'semver'; import { openApiTags } from '../../../../lib/openapi/util/openapi-tags'; -let app; -let db; +let app: IUnleashTest; +let db: ITestDb; beforeAll(async () => { db = await dbInit('openapi', getLogger); @@ -58,7 +62,7 @@ test('should serve the OpenAPI spec with a `version` property', async () => { }); describe('subpath handling', () => { - let appWithSubPath; + let appWithSubPath: IUnleashTest; const subPath = '/absolute-nonsense'; beforeAll(async () => { diff --git a/src/test/e2e/custom-auth.test.ts b/src/test/e2e/custom-auth.test.ts index 05223104ab..708a2a5aba 100644 --- a/src/test/e2e/custom-auth.test.ts +++ b/src/test/e2e/custom-auth.test.ts @@ -1,9 +1,9 @@ -import dbInit from './helpers/database-init'; +import dbInit, { ITestDb } from './helpers/database-init'; import { setupAppWithCustomAuth } from './helpers/test-helper'; -import { RoleName } from '../../lib/types'; +import { IUnleashStores, RoleName } from '../../lib/types'; -let db; -let stores; +let db: ITestDb; +let stores: IUnleashStores; const preHook = (app, config, { userService, accessService }) => { app.use('/api/admin/', async (req, res, next) => { diff --git a/src/test/e2e/health.e2e.test.ts b/src/test/e2e/health.e2e.test.ts index be6dcef476..75ea4ae8b2 100644 --- a/src/test/e2e/health.e2e.test.ts +++ b/src/test/e2e/health.e2e.test.ts @@ -1,9 +1,10 @@ import { setupApp } from './helpers/test-helper'; -import dbInit from './helpers/database-init'; +import dbInit, { ITestDb } from './helpers/database-init'; import getLogger from '../fixtures/no-logger'; +import { IUnleashStores } from '../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { db = await dbInit('health_api', getLogger); diff --git a/src/test/e2e/routes/routes.test.ts b/src/test/e2e/routes/routes.test.ts index e8a5cbf140..0d4c4b4f29 100644 --- a/src/test/e2e/routes/routes.test.ts +++ b/src/test/e2e/routes/routes.test.ts @@ -1,9 +1,9 @@ -import { setupAppWithBaseUrl } from '../helpers/test-helper'; +import { IUnleashTest, setupAppWithBaseUrl } from '../helpers/test-helper'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; -let db; -let app; +let db: ITestDb; +let app: IUnleashTest; beforeAll(async () => { db = await dbInit('routes_test_serial'); diff --git a/src/test/e2e/services/access-service.e2e.test.ts b/src/test/e2e/services/access-service.e2e.test.ts index 709ab14d6d..a992f8dc9f 100644 --- a/src/test/e2e/services/access-service.e2e.test.ts +++ b/src/test/e2e/services/access-service.e2e.test.ts @@ -12,6 +12,7 @@ import { RoleName } from '../../../lib/types/model'; import { ICreateGroupUserModel, IUnleashStores, + IUser, IUserAccessOverview, } from '../../../lib/types'; import { createTestConfig } from '../../config/test-config'; @@ -23,16 +24,19 @@ import { createProjectService, } from '../../../lib/features'; import { BadDataError } from '../../../lib/error'; +import FeatureToggleService from '../../../lib/features/feature-toggle/feature-toggle-service'; +import { ProjectService } from '../../../lib/services'; +import { IRole } from '../../../lib/types/stores/access-store'; let db: ITestDb; let stores: IUnleashStores; let accessService: AccessService; -let featureToggleService; -let projectService; -let editorUser; -let editorRole; -let adminRole; -let readRole; +let featureToggleService: FeatureToggleService; +let projectService: ProjectService; +let editorUser: IUser; +let editorRole: IRole; +let adminRole: IRole; +let readRole: IRole; let userIndex = 0; const TEST_USER_ID = -9999; @@ -238,9 +242,9 @@ beforeAll(async () => { }); accessService = createAccessService(db.rawDatabase, config); const roles = await accessService.getRootRoles(); - editorRole = roles.find((r) => r.name === RoleName.EDITOR); - adminRole = roles.find((r) => r.name === RoleName.ADMIN); - readRole = roles.find((r) => r.name === RoleName.VIEWER); + editorRole = roles.find((r) => r.name === RoleName.EDITOR)!; + adminRole = roles.find((r) => r.name === RoleName.ADMIN)!; + readRole = roles.find((r) => r.name === RoleName.VIEWER)!; featureToggleService = createFeatureToggleService(db.rawDatabase, config); projectService = createProjectService(db.rawDatabase, config); @@ -252,7 +256,6 @@ beforeAll(async () => { { id: 'some-project', name: 'Some project', - description: 'Used in the test', }, testAdmin, ); @@ -261,7 +264,6 @@ beforeAll(async () => { { id: 'unusedprojectname', name: 'Another project not used', - description: 'Also used in the test', }, testAdmin, ); @@ -719,7 +721,7 @@ test('Should be denied access to delete a role that is in use', async () => { name: 'New project', description: 'Blah', }; - await projectService.createProject(project, user.id); + await projectService.createProject(project, user); const projectMember = await stores.userStore.insert({ name: 'CustomProjectMember', @@ -737,7 +739,12 @@ test('Should be denied access to delete a role that is in use', async () => { }, ]); - await projectService.addUser(project.id, customRole.id, projectMember.id); + await projectService.addUser( + project.id, + customRole.id, + projectMember.id, + 'systemuser', + ); try { await accessService.deleteRole(customRole.id, 'testuser', TEST_USER_ID); @@ -762,8 +769,8 @@ test('Should be denied move feature toggle to project where the user does not ha name: 'New project', description: 'Blah', }; - await projectService.createProject(projectOrigin, user.id); - await projectService.createProject(projectDest, editorUser2.id); + await projectService.createProject(projectOrigin, user); + await projectService.createProject(projectDest, editorUser2); const featureToggle = { name: 'moveableToggle' }; @@ -771,6 +778,7 @@ test('Should be denied move feature toggle to project where the user does not ha projectOrigin.id, featureToggle, user.username, + user.id, ); try { @@ -811,6 +819,7 @@ test('Should be allowed move feature toggle to project when the user has access' projectOrigin.id, featureToggle, user.username, + user.id, ); await projectService.changeProject( diff --git a/src/test/e2e/services/addon-service.e2e.test.ts b/src/test/e2e/services/addon-service.e2e.test.ts index 07347a6e56..536cf679fe 100644 --- a/src/test/e2e/services/addon-service.e2e.test.ts +++ b/src/test/e2e/services/addon-service.e2e.test.ts @@ -1,4 +1,4 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { createTestConfig } from '../../config/test-config'; import AddonService from '../../../lib/services/addon-service'; @@ -11,7 +11,7 @@ import { EventService } from '../../../lib/services'; const addonProvider = { simple: new SimpleAddon() }; -let db; +let db: ITestDb; let stores: IUnleashStores; let addonService: AddonService; const TEST_USER_ID = -9999; 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 9a0744f5f7..b7df749bed 100644 --- a/src/test/e2e/services/api-token-service.e2e.test.ts +++ b/src/test/e2e/services/api-token-service.e2e.test.ts @@ -1,4 +1,4 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { ApiTokenService } from '../../../lib/services/api-token-service'; import { createTestConfig } from '../../config/test-config'; @@ -8,9 +8,10 @@ import { addDays, subDays } from 'date-fns'; import ProjectService from '../../../lib/services/project-service'; import { createProjectService } from '../../../lib/features'; import { EventService } from '../../../lib/services'; +import { IUnleashStores } from 'lib/types'; -let db; -let stores; +let db: ITestDb; +let stores: IUnleashStores; let apiTokenService: ApiTokenService; let projectService: ProjectService; diff --git a/src/test/e2e/services/client-metrics-service.e2e.test.ts b/src/test/e2e/services/client-metrics-service.e2e.test.ts index e9088285dc..e61bf82a9b 100644 --- a/src/test/e2e/services/client-metrics-service.e2e.test.ts +++ b/src/test/e2e/services/client-metrics-service.e2e.test.ts @@ -2,16 +2,17 @@ import ClientInstanceService from '../../../lib/services/client-metrics/instance import { IClientApp } from '../../../lib/types/model'; import { secondsToMilliseconds } from 'date-fns'; import { createTestConfig } from '../../config/test-config'; -import { IUnleashConfig } from '../../../lib/types'; +import { IUnleashConfig, IUnleashStores } from '../../../lib/types'; import { FakePrivateProjectChecker } from '../../../lib/features/private-project/fakePrivateProjectChecker'; +import { ITestDb } from '../helpers/database-init'; const faker = require('faker'); const dbInit = require('../helpers/database-init'); const getLogger = require('../../fixtures/no-logger'); const { APPLICATION_CREATED } = require('../../../lib/types/events'); -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let clientInstanceService: ClientInstanceService; let config: IUnleashConfig; beforeAll(async () => { diff --git a/src/test/e2e/services/group-service.e2e.test.ts b/src/test/e2e/services/group-service.e2e.test.ts index f965568675..415534b4c4 100644 --- a/src/test/e2e/services/group-service.e2e.test.ts +++ b/src/test/e2e/services/group-service.e2e.test.ts @@ -2,16 +2,16 @@ import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { createTestConfig } from '../../config/test-config'; import { GroupService } from '../../../lib/services/group-service'; -import GroupStore from '../../../lib/db/group-store'; import { EventService } from '../../../lib/services'; +import { IGroupStore, IUnleashStores, IUser } from '../../../lib/types'; -let stores; +let stores: IUnleashStores; let db: ITestDb; let eventService: EventService; let groupService: GroupService; -let groupStore: GroupStore; -let user; +let groupStore: IGroupStore; +let user: IUser; beforeAll(async () => { db = await dbInit('group_service_serial', getLogger); 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 36e1118351..59e4bcfee1 100644 --- a/src/test/e2e/services/project-health-service.e2e.test.ts +++ b/src/test/e2e/services/project-health-service.e2e.test.ts @@ -4,18 +4,13 @@ import ProjectHealthService from '../../../lib/services/project-health-service'; import { createTestConfig } from '../../config/test-config'; import { IUnleashStores } from '../../../lib/types'; import { IUser } from '../../../lib/server-impl'; -import { - createFeatureToggleService, - createProjectService, -} from '../../../lib/features'; -import { EventService } from '../../../lib/services'; +import { createProjectService } from '../../../lib/features'; +import { ProjectService } from '../../../lib/services'; let stores: IUnleashStores; let db: ITestDb; -let projectService; -let eventService: EventService; -let projectHealthService; -let featureToggleService; +let projectService: ProjectService; +let projectHealthService: ProjectHealthService; let user: IUser; beforeAll(async () => { @@ -26,10 +21,6 @@ beforeAll(async () => { name: 'Some Name', email: 'test@getunleash.io', }); - eventService = new EventService(stores, config); - - featureToggleService = createFeatureToggleService(db.rawDatabase, config); - projectService = createProjectService(db.rawDatabase, config); projectHealthService = new ProjectHealthService( 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 b93e228e60..ddec47137c 100644 --- a/src/test/e2e/services/reset-token-service.e2e.test.ts +++ b/src/test/e2e/services/reset-token-service.e2e.test.ts @@ -1,4 +1,4 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import ResetTokenService from '../../../lib/services/reset-token-service'; import UserService from '../../../lib/services/user-service'; @@ -8,17 +8,18 @@ import { IUnleashConfig } from '../../../lib/types/option'; import { createTestConfig } from '../../config/test-config'; import SessionService from '../../../lib/services/session-service'; import InvalidTokenError from '../../../lib/error/invalid-token-error'; -import { IUser } from '../../../lib/types/user'; +import { IUser, IUserWithRootRole } from '../../../lib/types/user'; import SettingService from '../../../lib/services/setting-service'; import FakeSettingStore from '../../fixtures/fake-setting-store'; import { GroupService } from '../../../lib/services/group-service'; import { EventService } from '../../../lib/services'; +import { IUnleashStores } from '../../../lib/types'; const config: IUnleashConfig = createTestConfig(); -let stores; -let db; -let adminUser; +let stores: IUnleashStores; +let db: ITestDb; +let adminUser: IUserWithRootRole; let userToCreateResetFor: IUser; let userIdToCreateResetFor: number; let accessService: AccessService; @@ -77,7 +78,7 @@ afterAll(async () => { test('Should create a reset link', async () => { const url = await resetTokenService.createResetPasswordUrl( userIdToCreateResetFor, - adminUser, + adminUser.username, ); expect(url.toString().substring(0, url.toString().indexOf('='))).toBe( @@ -96,7 +97,7 @@ test('Should create a reset link with unleashUrl with context path', async () => const url = await resetToken.createResetPasswordUrl( userIdToCreateResetFor, - adminUser, + adminUser.username, ); expect(url.toString().substring(0, url.toString().indexOf('='))).toBe( `${localConfig.server.unleashUrl}/reset-password?token`, @@ -117,7 +118,7 @@ test('Should create a welcome link', async () => { test('Tokens should be one-time only', async () => { const token = await resetTokenService.createToken( userIdToCreateResetFor, - adminUser, + adminUser.username, ); const accessGranted = await resetTokenService.useAccessToken(token); @@ -129,11 +130,11 @@ test('Tokens should be one-time only', async () => { test('Creating a new token should expire older tokens', async () => { const firstToken = await resetTokenService.createToken( userIdToCreateResetFor, - adminUser, + adminUser.username, ); const secondToken = await resetTokenService.createToken( userIdToCreateResetFor, - adminUser, + adminUser.username, ); await expect(async () => resetTokenService.isValid(firstToken.token), @@ -145,7 +146,7 @@ test('Creating a new token should expire older tokens', async () => { test('Retrieving valid invitation links should retrieve an object with userid key and token value', async () => { const token = await resetTokenService.createToken( userIdToCreateResetFor, - adminUser, + adminUser.username, ); expect(token).toBeTruthy(); const activeInvitations = await resetTokenService.getActiveInvitations(); diff --git a/src/test/e2e/services/session-service.e2e.test.ts b/src/test/e2e/services/session-service.e2e.test.ts index 8e273b72ff..f149b2cbf6 100644 --- a/src/test/e2e/services/session-service.e2e.test.ts +++ b/src/test/e2e/services/session-service.e2e.test.ts @@ -1,12 +1,13 @@ import noLoggerProvider from '../../fixtures/no-logger'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import SessionService from '../../../lib/services/session-service'; import NotFoundError from '../../../lib/error/notfound-error'; import { addDays, minutesToMilliseconds } from 'date-fns'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; -let sessionService; +let stores: IUnleashStores; +let db: ITestDb; +let sessionService: SessionService; const newSession = { sid: 'abc123', sess: { diff --git a/src/test/e2e/services/setting-service.test.ts b/src/test/e2e/services/setting-service.test.ts index d96c203ebf..d10aea319e 100644 --- a/src/test/e2e/services/setting-service.test.ts +++ b/src/test/e2e/services/setting-service.test.ts @@ -1,6 +1,6 @@ import SettingService from '../../../lib/services/setting-service'; import { createTestConfig } from '../../config/test-config'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import { IUnleashStores } from '../../../lib/types/stores'; import { SETTING_CREATED, @@ -10,7 +10,7 @@ import { import { EventService } from '../../../lib/services'; let stores: IUnleashStores; -let db; +let db: ITestDb; let service: SettingService; const TEST_USER_ID = -9999; diff --git a/src/test/e2e/services/state-service.e2e.test.ts b/src/test/e2e/services/state-service.e2e.test.ts index 4fceb0c595..e2948b3527 100644 --- a/src/test/e2e/services/state-service.e2e.test.ts +++ b/src/test/e2e/services/state-service.e2e.test.ts @@ -1,12 +1,13 @@ import { createTestConfig } from '../../config/test-config'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import StateService from '../../../lib/services/state-service'; import oldFormat from '../../examples/variantsexport_v3.json'; import { WeightType } from '../../../lib/types/model'; import { EventService } from '../../../lib/services'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let stateService: StateService; beforeAll(async () => { @@ -36,9 +37,11 @@ test('Exporting featureEnvironmentVariants should work', async () => { }); await stores.featureToggleStore.create('fancy', { name: 'Some-feature', + createdByUserId: -1337, }); await stores.featureToggleStore.create('fancy', { name: 'another-feature', + createdByUserId: -1337, }); await stores.featureEnvironmentStore.addEnvironmentToFeature( 'Some-feature', @@ -87,19 +90,19 @@ test('Exporting featureEnvironmentVariants should work', async () => { name: 'purple', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'variable', }, { name: 'lilac', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'fix', }, { name: 'azure', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'fix', }, ], ); @@ -111,19 +114,19 @@ test('Exporting featureEnvironmentVariants should work', async () => { name: 'purple', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'fix', }, { name: 'lilac', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'fix', }, { name: 'azure', weight: 333, stickiness: 'default', - weightType: '', + weightType: 'variable', }, ], ); @@ -147,7 +150,7 @@ test('Should import variants from old format and convert to new format (per envi expect( featureEnvironments .filter((fE) => fE.featureName === 'variants-tester' && fE.enabled) - .every((e) => e.variants.length === 4), + .every((e) => e.variants?.length === 4), ).toBeTruthy(); }); test('Should import variants in new format (per environment)', async () => { diff --git a/src/test/e2e/services/user-service.e2e.test.ts b/src/test/e2e/services/user-service.e2e.test.ts index c030ddd0a2..dd7f370f9e 100644 --- a/src/test/e2e/services/user-service.e2e.test.ts +++ b/src/test/e2e/services/user-service.e2e.test.ts @@ -1,8 +1,7 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import UserService from '../../../lib/services/user-service'; import { AccessService } from '../../../lib/services/access-service'; -import UserStore from '../../../lib/db/user-store'; import ResetTokenService from '../../../lib/services/reset-token-service'; import { EmailService } from '../../../lib/services/email-service'; import { createTestConfig } from '../../config/test-config'; @@ -18,12 +17,18 @@ import { randomId } from '../../../lib/util/random-id'; import { BadDataError } from '../../../lib/error'; import PasswordMismatch from '../../../lib/error/password-mismatch'; import { EventService } from '../../../lib/services'; -import { USER_CREATED, USER_DELETED, USER_UPDATED } from '../../../lib/types'; +import { + IUnleashStores, + IUserStore, + USER_CREATED, + USER_DELETED, + USER_UPDATED, +} from '../../../lib/types'; -let db; -let stores; +let db: ITestDb; +let stores: IUnleashStores; let userService: UserService; -let userStore: UserStore; +let userStore: IUserStore; let adminRole: IRole; let viewerRole: IRole; let sessionService: SessionService; diff --git a/src/test/e2e/stores/client-application-store.e2e.test.ts b/src/test/e2e/stores/client-application-store.e2e.test.ts index e1d3c9c5bf..af28175406 100644 --- a/src/test/e2e/stores/client-application-store.e2e.test.ts +++ b/src/test/e2e/stores/client-application-store.e2e.test.ts @@ -1,10 +1,12 @@ import faker from 'faker'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IClientApplicationsStore, IUnleashStores } from 'lib/types'; +import { IClientApplication } from '../../../lib/types/stores/client-applications-store'; -let db; -let stores; -let clientApplicationsStore; +let db: ITestDb; +let stores: IUnleashStores; +let clientApplicationsStore: IClientApplicationsStore; beforeAll(async () => { db = await dbInit('client_application_store_e2e_serial', getLogger); @@ -61,7 +63,10 @@ test('Multiple instances should still only announce once per app', async () => { }); test('Multiple applications should also be possible to announce', async () => { - const clients = []; + const clients: Omit< + IClientApplication, + 'createdAt' | 'updatedAt' | 'lastSeen' | 'announced' | 'url' + >[] = []; while (clients.length < 10) { const clientRegistration = { appName: `${faker.internet.domainName()}_${clients.length}`, @@ -73,6 +78,8 @@ test('Multiple applications should also be possible to announce', async () => { icon: '', description: faker.company.catchPhrase(), color: faker.internet.color(), + createdBy: 'test', + createdByUserId: -1337, }; clients.push(clientRegistration); } @@ -125,7 +132,7 @@ test('Merge keeps value for single row in database', async () => { appName: clientRegistration.appName, description: 'new description', }); - const stored = await clientApplicationsStore.getApplication( + const stored = await clientApplicationsStore.get( clientRegistration.appName, ); expect(stored.color).toBe(clientRegistration.color); @@ -133,7 +140,10 @@ test('Merge keeps value for single row in database', async () => { }); test('Multi row merge also works', async () => { - const clients = []; + const clients: Omit< + IClientApplication, + 'createdAt' | 'updatedAt' | 'lastSeen' | 'announced' | 'url' + >[] = []; while (clients.length < 10) { const clientRegistration = { appName: `${faker.internet.domainName()}_${clients.length}`, @@ -143,6 +153,8 @@ test('Multi row merge also works', async () => { icon: faker.internet.color(), description: faker.company.catchPhrase(), color: faker.internet.color(), + createdBy: 'test-user', + createdByUserId: -1337, }; clients.push(clientRegistration); } @@ -153,9 +165,7 @@ test('Multi row merge also works', async () => { })); await clientApplicationsStore.bulkUpsert(alteredClients); const stored = await Promise.all( - clients.map(async (c) => - clientApplicationsStore.getApplication(c.appName), - ), + clients.map(async (c) => clientApplicationsStore.get(c.appName!)), ); stored.forEach((s, i) => { expect(s.description).toBe(clients[i].description); diff --git a/src/test/e2e/stores/client-metrics-store-v2.e2e.test.ts b/src/test/e2e/stores/client-metrics-store-v2.e2e.test.ts index 65ac83e440..b6ac40e049 100644 --- a/src/test/e2e/stores/client-metrics-store-v2.e2e.test.ts +++ b/src/test/e2e/stores/client-metrics-store-v2.e2e.test.ts @@ -1,5 +1,5 @@ import { addHours, set, subDays } from 'date-fns'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { IUnleashStores } from '../../../lib/types'; import { @@ -7,7 +7,7 @@ import { IClientMetricsStoreV2, } from '../../../lib/types/stores/client-metrics-store-v2'; -let db; +let db: ITestDb; let stores: IUnleashStores; let clientMetricsStore: IClientMetricsStoreV2; diff --git a/src/test/e2e/stores/event-store.e2e.test.ts b/src/test/e2e/stores/event-store.e2e.test.ts index cc64b16242..08999b1be7 100644 --- a/src/test/e2e/stores/event-store.e2e.test.ts +++ b/src/test/e2e/stores/event-store.e2e.test.ts @@ -7,12 +7,12 @@ import { IEvent, } from '../../../lib/types/events'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { IEventStore } from '../../../lib/types/stores/event-store'; import { IUnleashStores } from '../../../lib/types'; -let db; +let db: ITestDb; let stores: IUnleashStores; let eventStore: IEventStore; const TEST_USER_ID = -9999; diff --git a/src/test/e2e/stores/feature-environment-store.e2e.test.ts b/src/test/e2e/stores/feature-environment-store.e2e.test.ts index e87f69b0f3..dd96717240 100644 --- a/src/test/e2e/stores/feature-environment-store.e2e.test.ts +++ b/src/test/e2e/stores/feature-environment-store.e2e.test.ts @@ -1,11 +1,11 @@ import { IUnleashStores } from '../../../lib/types'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import { IFeatureEnvironmentStore } from '../../../lib/types/stores/feature-environment-store'; import { IFeatureToggleStore } from '../../../lib/features/feature-toggle/types/feature-toggle-store-type'; import { IEnvironmentStore } from '../../../lib/features/project-environments/environment-store-type'; -let db; +let db: ITestDb; let stores: IUnleashStores; let featureEnvironmentStore: IFeatureEnvironmentStore; let featureStore: IFeatureToggleStore; diff --git a/src/test/e2e/stores/feature-tag-store.e2e.test.ts b/src/test/e2e/stores/feature-tag-store.e2e.test.ts index 9692ad7f5e..b022f20ec7 100644 --- a/src/test/e2e/stores/feature-tag-store.e2e.test.ts +++ b/src/test/e2e/stores/feature-tag-store.e2e.test.ts @@ -1,11 +1,12 @@ import { IFeatureTagStore } from 'lib/types/stores/feature-tag-store'; import { IFeatureToggleStore } from 'lib/features/feature-toggle/types/feature-toggle-store-type'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; import NotFoundError from '../../../lib/error/notfound-error'; +import { IUnleashStores } from 'lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let featureTagStore: IFeatureTagStore; let featureToggleStore: IFeatureToggleStore; diff --git a/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts b/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts index 190fd2bc5f..19df5e14b5 100644 --- a/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts +++ b/src/test/e2e/stores/feature-toggle-client-store.e2e.test.ts @@ -1,11 +1,12 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; -import { setupApp } from '../helpers/test-helper'; +import { IUnleashTest, setupApp } from '../helpers/test-helper'; +import { IFeatureToggleClientStore, IUnleashStores } from '../../../lib/types'; -let stores; -let app; -let db; -let clientFeatureToggleStore; +let stores: IUnleashStores; +let app: IUnleashTest; +let db: ITestDb; +let clientFeatureToggleStore: IFeatureToggleClientStore; beforeAll(async () => { getLogger.setMuteError(true); @@ -27,6 +28,6 @@ test('should be able to fetch client toggles', async () => { expect(response.status).toBe(202); - const clientToggles = await clientFeatureToggleStore.getClient(); + const clientToggles = await clientFeatureToggleStore.getClient({}); expect(clientToggles).toHaveLength(1); }); diff --git a/src/test/e2e/stores/feature-type-store.e2e.test.ts b/src/test/e2e/stores/feature-type-store.e2e.test.ts index 8fe917ea6c..114fe879ef 100644 --- a/src/test/e2e/stores/feature-type-store.e2e.test.ts +++ b/src/test/e2e/stores/feature-type-store.e2e.test.ts @@ -1,9 +1,10 @@ import { IFeatureTypeStore } from 'lib/types/stores/feature-type-store'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let featureTypeStore: IFeatureTypeStore; beforeAll(async () => { @@ -34,7 +35,7 @@ test('should be possible to get by id', async () => { test('should be possible to delete by id', async () => { const types = await featureTypeStore.getAll(); - const deleteType = types.pop(); + const deleteType = types.pop()!; await featureTypeStore.delete(deleteType.id); const typesAfterDelete = await featureTypeStore.getAll(); expect(typesAfterDelete.length).toBe(4); diff --git a/src/test/e2e/stores/project-store.e2e.test.ts b/src/test/e2e/stores/project-store.e2e.test.ts index 0494d94866..b640611167 100644 --- a/src/test/e2e/stores/project-store.e2e.test.ts +++ b/src/test/e2e/stores/project-store.e2e.test.ts @@ -1,11 +1,12 @@ import { IProjectInsert, IProjectStore } from 'lib/types/stores/project-store'; import { IEnvironmentStore } from 'lib/features/project-environments/environment-store-type'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let projectStore: IProjectStore; let environmentStore: IEnvironmentStore; diff --git a/src/test/e2e/stores/setting-store.e2e.test.ts b/src/test/e2e/stores/setting-store.e2e.test.ts index ade6d5ee0a..bb1649c9df 100644 --- a/src/test/e2e/stores/setting-store.e2e.test.ts +++ b/src/test/e2e/stores/setting-store.e2e.test.ts @@ -1,8 +1,9 @@ -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { db = await dbInit('setting_store_serial', getLogger); diff --git a/src/test/e2e/stores/user-feedback-store.e2e.test.ts b/src/test/e2e/stores/user-feedback-store.e2e.test.ts index 78836c55f8..a0de4e188d 100644 --- a/src/test/e2e/stores/user-feedback-store.e2e.test.ts +++ b/src/test/e2e/stores/user-feedback-store.e2e.test.ts @@ -1,13 +1,14 @@ import { IUserFeedbackStore } from 'lib/types/stores/user-feedback-store'; import { IUserStore } from 'lib/types/stores/user-store'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores, IUser } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let userFeedbackStore: IUserFeedbackStore; let userStore: IUserStore; -let currentUser; +let currentUser: IUser; beforeAll(async () => { db = await dbInit('user_feedback_store', getLogger); diff --git a/src/test/e2e/stores/user-splash-store.e2e.test.ts b/src/test/e2e/stores/user-splash-store.e2e.test.ts index 60f02c0542..6aa85787a6 100644 --- a/src/test/e2e/stores/user-splash-store.e2e.test.ts +++ b/src/test/e2e/stores/user-splash-store.e2e.test.ts @@ -1,13 +1,14 @@ import { IUserSplashStore } from 'lib/types/stores/user-splash-store'; import { IUserStore } from 'lib/types/stores/user-store'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores, IUser } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; let userSplashStore: IUserSplashStore; let userStore: IUserStore; -let currentUser; +let currentUser: IUser; beforeAll(async () => { db = await dbInit('user_splash_store', getLogger); diff --git a/src/test/e2e/stores/user-store.e2e.test.ts b/src/test/e2e/stores/user-store.e2e.test.ts index 5984d5d3e9..2894e1a0b2 100644 --- a/src/test/e2e/stores/user-store.e2e.test.ts +++ b/src/test/e2e/stores/user-store.e2e.test.ts @@ -1,9 +1,10 @@ import NotFoundError from '../../../lib/error/notfound-error'; -import dbInit from '../helpers/database-init'; +import dbInit, { ITestDb } from '../helpers/database-init'; import getLogger from '../../fixtures/no-logger'; +import { IUnleashStores } from '../../../lib/types'; -let stores; -let db; +let stores: IUnleashStores; +let db: ITestDb; beforeAll(async () => { db = await dbInit('user_store_serial', getLogger); @@ -75,9 +76,9 @@ test('should not get password_hash for unknown userId', async () => { test('should update loginAttempts for user', async () => { const store = stores.userStore; const user = { email: 'admin@mail.com' }; - await store.upsert(user); - await store.incLoginAttempts(user); - await store.incLoginAttempts(user); + const updated_user = await store.upsert(user); + await store.incLoginAttempts(updated_user); + await store.incLoginAttempts(updated_user); const storedUser = await store.getByQuery(user); expect(storedUser.loginAttempts).toBe(2); @@ -87,6 +88,7 @@ test('should not increment for user unknown user', async () => { const store = stores.userStore; const user = { email: 'another@mail.com' }; await store.upsert(user); + // @ts-expect-error - Should just use email here await store.incLoginAttempts({ email: 'unknown@mail.com' }); const storedUser = await store.getByQuery(user); @@ -103,7 +105,7 @@ test('should reset user after successful login', async () => { const storedUser = await store.getByQuery(user); expect(storedUser.loginAttempts).toBe(0); - expect(storedUser.seenAt >= user.seenAt).toBe(true); + expect(storedUser.seenAt! >= user.seenAt!).toBe(true); }); test('should only update specified fields on user', async () => { diff --git a/src/test/fixtures/fake-strategies-store.ts b/src/test/fixtures/fake-strategies-store.ts index aa8e0a9c31..4e72c133e3 100644 --- a/src/test/fixtures/fake-strategies-store.ts +++ b/src/test/fixtures/fake-strategies-store.ts @@ -24,13 +24,13 @@ export default class FakeStrategiesStore implements IStrategyStore { strategies: IStrategy[] = [this.defaultStrategy]; async createStrategy(update: IMinimalStrategy): Promise { - let params; + let params: object[]; if ( typeof update.parameters === 'string' || typeof update.parameters === 'number' ) { if (update.parameters === '') { - params = {}; + params = []; } else { params = JSON.parse(update.parameters); } diff --git a/yarn.lock b/yarn.lock index 20781d5648..65f8da34da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -616,47 +616,59 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@biomejs/biome@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.4.1.tgz#b698c67ea8cd8141c8e27f857c8e6e794320a251" - integrity sha512-JccVAwPbhi37pdxbAGmaOBjUTKEwEjWAhl7rKkVVuXHo4MLASXJ5HR8BTgrImi4/7rTBsGz1tgVD1Kwv1CHGRg== +"@biomejs/biome@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.5.1.tgz#ed665a8693e3014bf8fa641ad58703c85dd575cc" + integrity sha512-rdMA/N1Zc1nxUtbXMVr+50Sg/Pezz+9qGQa2uyRWFtrCoyr3dv0pVz+0ifGGue18ip50ZH8x2r5CV7zo8Q/0mA== optionalDependencies: - "@biomejs/cli-darwin-arm64" "1.4.1" - "@biomejs/cli-darwin-x64" "1.4.1" - "@biomejs/cli-linux-arm64" "1.4.1" - "@biomejs/cli-linux-x64" "1.4.1" - "@biomejs/cli-win32-arm64" "1.4.1" - "@biomejs/cli-win32-x64" "1.4.1" + "@biomejs/cli-darwin-arm64" "1.5.1" + "@biomejs/cli-darwin-x64" "1.5.1" + "@biomejs/cli-linux-arm64" "1.5.1" + "@biomejs/cli-linux-arm64-musl" "1.5.1" + "@biomejs/cli-linux-x64" "1.5.1" + "@biomejs/cli-linux-x64-musl" "1.5.1" + "@biomejs/cli-win32-arm64" "1.5.1" + "@biomejs/cli-win32-x64" "1.5.1" -"@biomejs/cli-darwin-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.4.1.tgz#75f9c3c9b1abed8836c8f7bc8cd23ba153fb93d1" - integrity sha512-PZWy2Idndqux38p6AXSDQM2ldRAWi32bvb7bMbTN0ALzpWYMYnxd71ornatumSSJYoNhKmxzDLq+jct7nZJ79w== +"@biomejs/cli-darwin-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.5.1.tgz#ea33f009aaa4bca3ce281e010a6cb108249cb973" + integrity sha512-E9pLakmSVHP6UH2uqAghqEkr/IHAIDfDyCedqJVnyFc+uufNTHwB8id4XTiWy/eKIdgxHZsTSE+R+W0IqrTNVQ== -"@biomejs/cli-darwin-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.4.1.tgz#672fcce2d339de3bb7a7bd2997e94f03121a28a3" - integrity sha512-soj3BWhnsM1M2JlzR09cibUzG1owJqetwj/Oo7yg0foijo9lNH9XWXZfJBYDKgW/6Fomn+CC2EcUS+hisQzt9g== +"@biomejs/cli-darwin-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.5.1.tgz#c719a8615b380b25cd9a4bbdfc81d90dbec0996b" + integrity sha512-8O1F+FcoCi02JlocyilB6R3y3kT9sRkBCRwYddaBIScQe2hCme/mA2rVzrhCCHhskrclJ51GEKjkEORj4/8c2A== -"@biomejs/cli-linux-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.4.1.tgz#c816206089ad29ce866c58a6e00e9d3d64a3529d" - integrity sha512-YIZqfJUg4F+fPsBTXxgD7EU2E5OAYbmYSl/snf4PevwfQCWE/omOFZv+NnIQmjYj9I7ParDgcJvanoA3/kO0JQ== +"@biomejs/cli-linux-arm64-musl@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.1.tgz#c5364e08faca4826654b191e696425d5449a6fe3" + integrity sha512-Lw9G3LUdhRMp8L8RMeVevnfQCa7luT6ubQ8GRjLju32glxWKefpDrzgfHixGyvTQPlhnYjQ+V8/QQ/I7WPzOoA== -"@biomejs/cli-linux-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.4.1.tgz#2639daeab1be205cfe444a8d5a3f76aa3a59b956" - integrity sha512-9YOZw3qBd/KUj63A6Hn2zZgzGb2nbESM0qNmeMXgmqinVKM//uc4OgY5TuKITuGjMSvcVxxd4dX1IzYjV9qvNQ== +"@biomejs/cli-linux-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.5.1.tgz#1d9fe74cbc27aa784d8a3743ad1f77da883e2aef" + integrity sha512-25gwY4FMzmi1Rl6N835raLq7nzTk+PyEQd88k9Em6dqtI4qpljqmZlMmVjOiwXKe3Ee80J/Vlh7BM36lsHUTEg== -"@biomejs/cli-win32-arm64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.4.1.tgz#ed5e749b2e0987cf16b545beaa01be6980ae8ce1" - integrity sha512-nWQbvkNKxYn/kCQ0yVF8kCaS3VzaGvtFSmItXiMknU4521LDjJ7tNWH12Gol+pIslrCbd4E1LhJa0a3ThRsBVg== +"@biomejs/cli-linux-x64-musl@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.1.tgz#7e6ef6c1308907f30909374f91c380e2c85bf393" + integrity sha512-5gapxc/VlwTgGRbTc9h8PMTpf8eNahIBauFUGSXncHgayi3VpezKSicgaQ1bb8FahVXf/5eNEVxVARq/or71Ag== -"@biomejs/cli-win32-x64@1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.4.1.tgz#dd8ee6e14a5d74cbeb2eb9824a43c61bb5c460e4" - integrity sha512-88fR2CQxQ4YLs2BUDuywWYQpUKgU3A3sTezANFc/4LGKQFFLV2yX+F7QAdZVkMHfA+RD9Xg178HomM/6mnTNPA== +"@biomejs/cli-linux-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.5.1.tgz#0f6afaf035c6a07fe757d58a315f3a75e49f8987" + integrity sha512-YDM0gZP4UbAuaBI3DVbUuj5X+Omm6uxzD1Qpc6hcduH1kzXzs9L0ee7cn/kJtNndoXR8MlmUS0O0/wWvZf2YaA== + +"@biomejs/cli-win32-arm64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.5.1.tgz#196bdc1afd0945a0fad76719b601bf7f7a4aaf72" + integrity sha512-TVpLBOLUMLQmH2VRFBKFr3rgEkr7XvG4QZxHOxWB9Ivc/sQPvg4aHMd8qpgPKXABGUnultyc9t0+WvfIDxuALg== + +"@biomejs/cli-win32-x64@1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.5.1.tgz#b1996fa2dc6580f39fb2e1b6d126e93baf8da58d" + integrity sha512-qx8EKwScZmVYZjMPZ6GF3ZUmgg/N6zqh+d8vHA2E43opNCyqIPTl89sOqkc7zd1CyyABDWxsbqI9Ih6xTT6hnQ== "@colors/colors@1.5.0": version "1.5.0"