From 9bccdaeb676f03dd3e8a86c0671bea1d7b45eb1b Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 15:17:52 +0200 Subject: [PATCH 01/12] Enable FiltersConfig and ScientificConditions on the BE --- src/users/schemas/user-settings.schema.ts | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index d0682b629..f365d2f83 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -5,6 +5,31 @@ import { Document } from "mongoose"; export type UserSettingsDocument = UserSettings & Document; +// Define possible filter component types as a union of string literals +export type FilterComponentType = + | "LocationFilterComponent" + | "PidFilterComponent" + | "PidFilterContainsComponent" + | "PidFilterStartsWithComponent" + | "GroupFilterComponent" + | "TypeFilterComponent" + | "KeywordFilterComponent" + | "DateRangeFilterComponent" + | "TextFilterComponent"; + +// Define the Filter interface +export interface FilterConfig { + type: FilterComponentType; + visible: boolean; +} + +// Define the Condition interface +export interface ScientificCondition { + field: string; + value: string; + operator: string; +} + @Schema({ collection: "UserSetting", toJSON: { @@ -43,6 +68,22 @@ export class UserSettings { @ApiProperty({ type: String, required: true }) @Prop({ type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }) userId: string; + + @ApiProperty({ + type: [Object], + default: [], + description: "Array of filters the user has set", + }) + @Prop({ type: [{ type: Object }], default: [] }) + filters: FilterConfig[]; + + @ApiProperty({ + type: [Object], + default: [], + description: "Array of conditions the user has set", + }) + @Prop({ type: [{ type: Object }], default: [] }) + conditions: ScientificCondition[]; } export const UserSettingsSchema = SchemaFactory.createForClass(UserSettings); From 3df26971dd22c4c6e0adcd11df4e047865281795 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 15:24:55 +0200 Subject: [PATCH 02/12] Add default value --- src/users/schemas/user-settings.schema.ts | 27 +++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index f365d2f83..c93c473d0 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -71,10 +71,33 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: [], + default: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], description: "Array of filters the user has set", }) - @Prop({ type: [{ type: Object }], default: [] }) + @Prop({ + type: [{ type: Object }], + default: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + }) filters: FilterConfig[]; @ApiProperty({ From 680317c7939f437689588d57d9f94d16acf5a8e7 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Mon, 29 Jul 2024 16:32:34 +0200 Subject: [PATCH 03/12] Fix cp non existing file --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62021d8b6..0b7c48859 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start\"", "test:api:jest": "jest --config ./test/config/jest-e2e.json --maxWorkers=50%", "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js ", - "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.json.test functionalAccounts.json" + "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.test.json functionalAccounts.json" }, "dependencies": { "@casl/ability": "^6.3.2", From 1c428ae47424c2c5777f864508afdb372032bc1e Mon Sep 17 00:00:00 2001 From: ingvord Date: Tue, 30 Jul 2024 20:56:08 +0200 Subject: [PATCH 04/12] Add test for filters and conditions in user settings --- src/users/dto/update-user-settings.dto.ts | 10 ++++++ .../create-user-settings.interceptor.ts | 3 ++ src/users/schemas/user-settings.schema.ts | 36 ++++++++----------- test/Users.js | 4 ++- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index 9c6741b9e..5aac97f77 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -1,4 +1,8 @@ import { ApiProperty, PartialType } from "@nestjs/swagger"; +import { + FilterConfig, + ScientificCondition, +} from "../schemas/user-settings.schema"; export class UpdateUserSettingsDto { @ApiProperty() @@ -9,6 +13,12 @@ export class UpdateUserSettingsDto { @ApiProperty({ type: Number, required: false, default: 25 }) readonly jobCount?: number; + + @ApiProperty() + readonly filters: FilterConfig[]; + + @ApiProperty() + readonly conditions: ScientificCondition[]; } export class PartialUpdateUserSettingsDto extends PartialType( diff --git a/src/users/interceptors/create-user-settings.interceptor.ts b/src/users/interceptors/create-user-settings.interceptor.ts index d059602db..2ecb7bbc0 100644 --- a/src/users/interceptors/create-user-settings.interceptor.ts +++ b/src/users/interceptors/create-user-settings.interceptor.ts @@ -8,6 +8,7 @@ import { import { Observable, tap } from "rxjs"; import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; import { UsersService } from "../users.service"; +import { kDefaultFilters } from "../schemas/user-settings.schema"; @Injectable() export class CreateUserSettingsInterceptor implements NestInterceptor { @@ -34,6 +35,8 @@ export class CreateUserSettingsInterceptor implements NestInterceptor { const createUserSettingsDto: CreateUserSettingsDto = { userId, columns: [], + filters: kDefaultFilters, + conditions: [], }; return this.usersService.createUserSettings( userId, diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index c93c473d0..fc56df5af 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -30,6 +30,18 @@ export interface ScientificCondition { operator: string; } +export const kDefaultFilters: FilterConfig[] = [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, +]; + @Schema({ collection: "UserSetting", toJSON: { @@ -71,32 +83,12 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, - ], + default: kDefaultFilters, description: "Array of filters the user has set", }) @Prop({ type: [{ type: Object }], - default: [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, - ], + default: kDefaultFilters, }) filters: FilterConfig[]; diff --git a/test/Users.js b/test/Users.js index 12c8c9691..72147ba09 100644 --- a/test/Users.js +++ b/test/Users.js @@ -53,7 +53,7 @@ describe("2360: Users settings", () => { ); }); - it("0010: Update users settings with valid value should sucess ", async () => { + it("0010: Update users settings with valid value should success ", async () => { return request(appUrl) .put(`/api/v3/Users/${userIdUser1}/settings`) .set("Accept", "application/json") @@ -64,6 +64,8 @@ describe("2360: Users settings", () => { res.body.should.have.property("userId", userIdUser1); res.body.should.have.property("datasetCount"); res.body.should.have.property("jobCount"); + res.body.should.have.property("filters"); + res.body.should.have.property("conditions"); }); }); }); From b107c708aee02a712fed960fde447e67c02aceb1 Mon Sep 17 00:00:00 2001 From: ingvord Date: Tue, 30 Jul 2024 22:17:40 +0200 Subject: [PATCH 05/12] Add tests --- src/users/users.controller.spec.ts | 75 ++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/users/users.controller.spec.ts b/src/users/users.controller.spec.ts index 1b22d0350..6bedb6203 100644 --- a/src/users/users.controller.spec.ts +++ b/src/users/users.controller.spec.ts @@ -3,17 +3,43 @@ import { AuthService } from "src/auth/auth.service"; import { CaslModule } from "src/casl/casl.module"; import { UsersController } from "./users.controller"; import { UsersService } from "./users.service"; +import { UpdateUserSettingsDto } from "./dto/update-user-settings.dto"; class UsersServiceMock { findByIdUserIdentity(id: string) { return { id }; } + + async findByIdUserSettings(userId: string) { + return mockUserSettings; + } + + async findOneAndUpdateUserSettings( + userId: string, + updateUserSettingsDto: UpdateUserSettingsDto, + ) { + return { ...updateUserSettingsDto, _id: userId }; + } } +const mockUserSettings = { + _id: "user1", + userId: "user1", + columns: [], + datasetCount: 25, + jobCount: 25, + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + ], + conditions: [{ field: "status", value: "active", operator: "equals" }], +}; + class AuthServiceMock {} describe("UsersController", () => { let controller: UsersController; + let usersService: UsersService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -26,9 +52,58 @@ describe("UsersController", () => { }).compile(); controller = module.get(UsersController); + usersService = module.get(UsersService); + + // bypass authorization + jest + .spyOn(controller as UsersController, "checkUserAuthorization") + .mockImplementation(() => Promise.resolve()); }); it("should be defined", () => { expect(controller).toBeDefined(); }); + + it("should return user settings with filters and conditions", async () => { + jest + .spyOn(usersService, "findByIdUserSettings") + .mockResolvedValue(mockUserSettings); + + const userId = "user1"; + const result = await controller.getSettings( + { user: { _id: userId } }, + userId, + ); + + expect(result).toEqual(mockUserSettings); + expect(result.filters).toBeDefined(); + expect(result.filters.length).toBeGreaterThan(0); + expect(result.conditions).toBeDefined(); + expect(result.conditions.length).toBeGreaterThan(0); + }); + + it("should update user settings with filters and conditions", async () => { + const updatedSettings = { + ...mockUserSettings, + filters: [{ type: "PidFilterContainsComponent", visible: false }], + conditions: [{ field: "status", value: "inactive", operator: "equals" }], + }; + + jest + .spyOn(usersService, "findOneAndUpdateUserSettings") + .mockResolvedValue(updatedSettings); + + const userId = "user-id"; + const result = await controller.updateSettings( + { user: { _id: userId } }, + userId, + updatedSettings, + ); + + expect(result).toEqual(updatedSettings); + expect(result.filters).toBeDefined(); + expect(result.filters.length).toBe(1); + expect(result.conditions).toBeDefined(); + expect(result.conditions.length).toBe(1); + }); }); From 0a0c792737683067434c433e101372caf490bc4e Mon Sep 17 00:00:00 2001 From: ingvord Date: Thu, 1 Aug 2024 18:19:57 +0200 Subject: [PATCH 06/12] Fix #1347 --- src/users/dto/create-user-settings.dto.ts | 2 ++ src/users/dto/update-user-settings.dto.ts | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/users/dto/create-user-settings.dto.ts b/src/users/dto/create-user-settings.dto.ts index 923d616bf..63095f1c2 100644 --- a/src/users/dto/create-user-settings.dto.ts +++ b/src/users/dto/create-user-settings.dto.ts @@ -1,7 +1,9 @@ import { ApiProperty } from "@nestjs/swagger"; import { UpdateUserSettingsDto } from "./update-user-settings.dto"; +import { IsString } from "class-validator"; export class CreateUserSettingsDto extends UpdateUserSettingsDto { @ApiProperty({ type: String, required: true }) + @IsString() readonly userId: string; } diff --git a/src/users/dto/update-user-settings.dto.ts b/src/users/dto/update-user-settings.dto.ts index 5aac97f77..8458e4e84 100644 --- a/src/users/dto/update-user-settings.dto.ts +++ b/src/users/dto/update-user-settings.dto.ts @@ -3,21 +3,27 @@ import { FilterConfig, ScientificCondition, } from "../schemas/user-settings.schema"; +import { IsArray, IsNumber } from "class-validator"; export class UpdateUserSettingsDto { @ApiProperty() + @IsArray() readonly columns: Record[]; @ApiProperty({ type: Number, required: false, default: 25 }) + @IsNumber() readonly datasetCount?: number; @ApiProperty({ type: Number, required: false, default: 25 }) + @IsNumber() readonly jobCount?: number; @ApiProperty() + @IsArray() readonly filters: FilterConfig[]; @ApiProperty() + @IsArray() readonly conditions: ScientificCondition[]; } From 7bf41f1ed3b9285cbf99a06b7434a2f648b2981a Mon Sep 17 00:00:00 2001 From: ingvord Date: Thu, 1 Aug 2024 19:24:37 +0200 Subject: [PATCH 07/12] Add default endpoints --- .../default-user-settings.interceptor.ts | 34 ++++++++++++++ src/users/users.controller.ts | 44 ++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/users/interceptors/default-user-settings.interceptor.ts diff --git a/src/users/interceptors/default-user-settings.interceptor.ts b/src/users/interceptors/default-user-settings.interceptor.ts new file mode 100644 index 000000000..f9eb647f1 --- /dev/null +++ b/src/users/interceptors/default-user-settings.interceptor.ts @@ -0,0 +1,34 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + Logger, + NestInterceptor, +} from "@nestjs/common"; +import { map, Observable, tap } from "rxjs"; +import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; +import { UsersService } from "../users.service"; +import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; + +@Injectable() +export class DefaultUserSettingsInterceptor implements NestInterceptor { + constructor(private usersService: UsersService) {} + async intercept( + context: ExecutionContext, + next: CallHandler, + ): Promise> { + return next.handle().pipe( + map(async () => { + Logger.log("DefaultUserSettingsInterceptor"); + const defaultUserSettings: UpdateUserSettingsDto = { + columns: [], + filters: kDefaultFilters, + conditions: [], + }; + console.log(defaultUserSettings); + return defaultUserSettings; + }), + ); + } +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index f5438de8b..b797ea2b4 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -12,6 +12,7 @@ import { Body, ForbiddenException, HttpCode, + CanActivate, } from "@nestjs/common"; import { ApiBearerAuth, @@ -31,7 +32,10 @@ import { Request } from "express"; import { JWTUser } from "../auth/interfaces/jwt-user.interface"; import { UserSettings } from "./schemas/user-settings.schema"; import { CreateUserSettingsDto } from "./dto/create-user-settings.dto"; -import { PartialUpdateUserSettingsDto } from "./dto/update-user-settings.dto"; +import { + PartialUpdateUserSettingsDto, + UpdateUserSettingsDto, +} from "./dto/update-user-settings.dto"; import { User } from "./schemas/user.schema"; import { CreateUserSettingsInterceptor } from "./interceptors/create-user-settings.interceptor"; import { AuthService } from "src/auth/auth.service"; @@ -44,6 +48,8 @@ import { CreateCustomJwt } from "./dto/create-custom-jwt.dto"; import { AuthenticatedPoliciesGuard } from "../casl/guards/auth-check.guard"; import { ReturnedUserDto } from "./dto/returned-user.dto"; import { ReturnedAuthLoginDto } from "src/auth/dto/returnedLogin.dto"; +import { PoliciesGuard } from "src/casl/guards/policies.guard"; +import { DefaultUserSettingsInterceptor } from "./interceptors/default-user-settings.interceptor"; @ApiBearerAuth() @ApiTags("users") @@ -307,6 +313,42 @@ export class UsersController { return this.usersService.findOneAndDeleteUserSettings(id); } + @UseInterceptors(DefaultUserSettingsInterceptor) + @UseGuards( + class ByPassAuthenticatedPoliciesGuard + extends PoliciesGuard + implements CanActivate + { + async canActivate(): Promise { + return Promise.resolve(true); + } + }, + ) + @Get("/settings/default") + async getDefaultSettings(): Promise { + return Promise.resolve(new UserSettings()); + } + + @UseGuards(AuthenticatedPoliciesGuard) + @CheckPolicies((ability: AppAbility) => + ability.can(Action.UserCreateAny, User), + ) + @Post("/settings/default") + async postDefaultSettings( + @Req() request: Request, + @Body() createUserSettingsDto: CreateUserSettingsDto, + ): Promise { + await this.checkUserAuthorization( + request, + [Action.UserCreateAny], + createUserSettingsDto.userId, + ); + return this.usersService.createUserSettings( + "default", + createUserSettingsDto, + ); + } + @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => { return ( From 9a1e643c0c3a096bc072bd023b8eb9f2b67edb47 Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:28:20 +0200 Subject: [PATCH 08/12] Rename constant as per Google TypeScript convention --- src/users/interceptors/create-user-settings.interceptor.ts | 4 ++-- .../interceptors/default-user-settings.interceptor.ts | 7 +++---- src/users/schemas/user-settings.schema.ts | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/users/interceptors/create-user-settings.interceptor.ts b/src/users/interceptors/create-user-settings.interceptor.ts index 2ecb7bbc0..e22d4f881 100644 --- a/src/users/interceptors/create-user-settings.interceptor.ts +++ b/src/users/interceptors/create-user-settings.interceptor.ts @@ -8,7 +8,7 @@ import { import { Observable, tap } from "rxjs"; import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; import { UsersService } from "../users.service"; -import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; @Injectable() export class CreateUserSettingsInterceptor implements NestInterceptor { @@ -35,7 +35,7 @@ export class CreateUserSettingsInterceptor implements NestInterceptor { const createUserSettingsDto: CreateUserSettingsDto = { userId, columns: [], - filters: kDefaultFilters, + filters: FILTER_CONFIGS, conditions: [], }; return this.usersService.createUserSettings( diff --git a/src/users/interceptors/default-user-settings.interceptor.ts b/src/users/interceptors/default-user-settings.interceptor.ts index f9eb647f1..61b8049e9 100644 --- a/src/users/interceptors/default-user-settings.interceptor.ts +++ b/src/users/interceptors/default-user-settings.interceptor.ts @@ -5,10 +5,9 @@ import { Logger, NestInterceptor, } from "@nestjs/common"; -import { map, Observable, tap } from "rxjs"; -import { CreateUserSettingsDto } from "../dto/create-user-settings.dto"; +import { map, Observable } from "rxjs"; import { UsersService } from "../users.service"; -import { kDefaultFilters } from "../schemas/user-settings.schema"; +import { FILTER_CONFIGS } from "../schemas/user-settings.schema"; import { UpdateUserSettingsDto } from "../dto/update-user-settings.dto"; @Injectable() @@ -23,7 +22,7 @@ export class DefaultUserSettingsInterceptor implements NestInterceptor { Logger.log("DefaultUserSettingsInterceptor"); const defaultUserSettings: UpdateUserSettingsDto = { columns: [], - filters: kDefaultFilters, + filters: FILTER_CONFIGS, conditions: [], }; console.log(defaultUserSettings); diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index fc56df5af..edceaa30d 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -30,7 +30,7 @@ export interface ScientificCondition { operator: string; } -export const kDefaultFilters: FilterConfig[] = [ +export const FILTER_CONFIGS: FilterConfig[] = [ { type: "LocationFilterComponent", visible: true }, { type: "PidFilterComponent", visible: true }, { type: "PidFilterContainsComponent", visible: false }, @@ -83,12 +83,12 @@ export class UserSettings { @ApiProperty({ type: [Object], - default: kDefaultFilters, + default: FILTER_CONFIGS, description: "Array of filters the user has set", }) @Prop({ type: [{ type: Object }], - default: kDefaultFilters, + default: FILTER_CONFIGS, }) filters: FilterConfig[]; From a0ea170f6442cc96d5c76232088a7d6c7b9c8bcc Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:42:12 +0200 Subject: [PATCH 09/12] Load default filters config from a json file --- src/config/default-filters.config.json | 11 +++++++++++ src/users/schemas/user-settings.schema.ts | 13 ++----------- 2 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 src/config/default-filters.config.json diff --git a/src/config/default-filters.config.json b/src/config/default-filters.config.json new file mode 100644 index 000000000..848bb1970 --- /dev/null +++ b/src/config/default-filters.config.json @@ -0,0 +1,11 @@ +[ + { "type": "LocationFilterComponent", "visible": true }, + { "type": "PidFilterComponent", "visible": true }, + { "type": "PidFilterContainsComponent", "visible": false }, + { "type": "PidFilterStartsWithComponent", "visible": false }, + { "type": "GroupFilterComponent", "visible": true }, + { "type": "TypeFilterComponent", "visible": true }, + { "type": "KeywordFilterComponent", "visible": true }, + { "type": "DateRangeFilterComponent", "visible": true }, + { "type": "TextFilterComponent", "visible": true } +] \ No newline at end of file diff --git a/src/users/schemas/user-settings.schema.ts b/src/users/schemas/user-settings.schema.ts index edceaa30d..9cfe2cae2 100644 --- a/src/users/schemas/user-settings.schema.ts +++ b/src/users/schemas/user-settings.schema.ts @@ -2,6 +2,7 @@ import * as mongoose from "mongoose"; import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose"; import { ApiProperty } from "@nestjs/swagger"; import { Document } from "mongoose"; +import filterConfigs from "../../config/default-filters.config.json"; export type UserSettingsDocument = UserSettings & Document; @@ -30,17 +31,7 @@ export interface ScientificCondition { operator: string; } -export const FILTER_CONFIGS: FilterConfig[] = [ - { type: "LocationFilterComponent", visible: true }, - { type: "PidFilterComponent", visible: true }, - { type: "PidFilterContainsComponent", visible: false }, - { type: "PidFilterStartsWithComponent", visible: false }, - { type: "GroupFilterComponent", visible: true }, - { type: "TypeFilterComponent", visible: true }, - { type: "KeywordFilterComponent", visible: true }, - { type: "DateRangeFilterComponent", visible: true }, - { type: "TextFilterComponent", visible: true }, -]; +export const FILTER_CONFIGS: FilterConfig[] = filterConfigs as FilterConfig[]; @Schema({ collection: "UserSetting", From 5acacbe8f3b8a8b0dfbc7945c5bf517bd63a8615 Mon Sep 17 00:00:00 2001 From: ingvord Date: Fri, 16 Aug 2024 15:44:46 +0200 Subject: [PATCH 10/12] Remove default user settings POST entry point --- src/users/users.controller.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index b797ea2b4..56e415374 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -329,26 +329,6 @@ export class UsersController { return Promise.resolve(new UserSettings()); } - @UseGuards(AuthenticatedPoliciesGuard) - @CheckPolicies((ability: AppAbility) => - ability.can(Action.UserCreateAny, User), - ) - @Post("/settings/default") - async postDefaultSettings( - @Req() request: Request, - @Body() createUserSettingsDto: CreateUserSettingsDto, - ): Promise { - await this.checkUserAuthorization( - request, - [Action.UserCreateAny], - createUserSettingsDto.userId, - ); - return this.usersService.createUserSettings( - "default", - createUserSettingsDto, - ); - } - @UseGuards(AuthenticatedPoliciesGuard) @CheckPolicies((ability: AppAbility) => { return ( From bb9c3351883c56119e24c5dfae3917139f318fa6 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Tue, 20 Aug 2024 16:30:45 +0200 Subject: [PATCH 11/12] Add test defaults --- src/users/users.service.spec.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts index 24a65a86d..d69ca6012 100644 --- a/src/users/users.service.spec.ts +++ b/src/users/users.service.spec.ts @@ -29,6 +29,18 @@ const mockUser: User = { datasetCount: 25, jobCount: 25, userId: "testUserId", + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + conditions: [], }, }; @@ -58,6 +70,18 @@ const mockUserSettings: UserSettings = { datasetCount: 25, jobCount: 25, userId: "testUserId", + filters: [ + { type: "LocationFilterComponent", visible: true }, + { type: "PidFilterComponent", visible: true }, + { type: "PidFilterContainsComponent", visible: false }, + { type: "PidFilterStartsWithComponent", visible: false }, + { type: "GroupFilterComponent", visible: true }, + { type: "TypeFilterComponent", visible: true }, + { type: "KeywordFilterComponent", visible: true }, + { type: "DateRangeFilterComponent", visible: true }, + { type: "TextFilterComponent", visible: true }, + ], + conditions: [], }; describe("UsersService", () => { From 7d3a298d38a7d3582dce20ac522cde2dc77989e8 Mon Sep 17 00:00:00 2001 From: Ingvord Date: Tue, 20 Aug 2024 16:32:38 +0200 Subject: [PATCH 12/12] Revert "Fix cp non existing file" This reverts commit 680317c7939f437689588d57d9f94d16acf5a8e7. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 122c1b424..f81c13691 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "test:api": "npm run test:api:jest --maxWorkers=50% && concurrently -k -s first \"wait-on http://localhost:3000/explorer/ && npm run test:api:mocha\" \"npm run start\"", "test:api:jest": "jest --config ./test/config/jest-e2e.json --maxWorkers=50%", "test:api:mocha": "mocha --config ./test/config/.mocharc.json -r chai/register-should.js ", - "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.test.json functionalAccounts.json" + "prepare:local": "docker-compose -f CI/E2E/docker-compose-local.yaml --env-file CI/E2E/.env.elastic-search up -d && cp functionalAccounts.json.test functionalAccounts.json" }, "dependencies": { "@casl/ability": "^6.3.2",