diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2a977c611..5b7067e54 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,7 @@ on: pull_request: branches: - master + - release-* jobs: install-and-cache: @@ -152,6 +153,9 @@ jobs: CREATE_DATASET_WITH_PID_GROUPS: "group2" CREATE_DATASET_PRIVILEGED_GROUPS: "datasetIngestor,group3" ACCESS_GROUPS_STATIC_VALUES: "ess" + CREATE_JOB_GROUPS: group1,group2 + UPDATE_JOB_GROUPS: group1 + DELETE_JOB_GROUPS: "archivemanager" PROPOSAL_GROUPS: "proposalingestor" SAMPLE_PRIVILEGED_GROUPS: "sampleingestor" SAMPLE_GROUPS: "group1" @@ -168,6 +172,7 @@ jobs: STACK_VERSION: 8.8.2 CLUSTER_NAME: es-cluster MEM_LIMIT: 4G + JOB_CONFIGURATION_FILE: test/config/jobconfig.json # Start mongo container and app before running api tests run: | diff --git a/src/casl/casl-ability.factory.ts b/src/casl/casl-ability.factory.ts index 6fcc1a93e..c0aa2de27 100644 --- a/src/casl/casl-ability.factory.ts +++ b/src/casl/casl-ability.factory.ts @@ -25,7 +25,10 @@ import { UserSettings } from "src/users/schemas/user-settings.schema"; import { User } from "src/users/schemas/user.schema"; import { AuthOp } from "./authop.enum"; import configuration from "src/config/configuration"; -import { CreateJobAuth, StatusUpdateJobAuth } from "src/jobs/types/jobs-auth.enum"; +import { + CreateJobAuth, + StatusUpdateJobAuth, +} from "src/jobs/types/jobs-auth.enum"; type Subjects = | string @@ -818,11 +821,14 @@ export class CaslAbilityFactory { ["configuration.create.auth" as string]: CreateJobAuth.DatasetPublic, datasetsValidation: true, }); + can(AuthOp.JobStatusUpdateConfiguration, JobClass, { + ["configuration.statusUpdate.auth" as string]: StatusUpdateJobAuth.All, + ownerGroup: undefined, + }); } else { /** * authenticated users */ - // check if this user is part of the admin group if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) @@ -830,24 +836,38 @@ export class CaslAbilityFactory { /** * authenticated users belonging to any of the group listed in ADMIN_GROUPS */ - // ------------------------------------- // endpoint authorization can(AuthOp.JobRead, JobClass); can(AuthOp.JobCreate, JobClass); can(AuthOp.JobStatusUpdate, JobClass); + cannot(AuthOp.JobDelete, JobClass); // ------------------------------------- // data instance authorization can(AuthOp.JobReadAny, JobClass); can(AuthOp.JobCreateAny, JobClass); can(AuthOp.JobStatusUpdateAny, JobClass); + } else if ( + user.currentGroups.some((g) => + configuration().deleteJobGroups.includes(g), + ) + ) { + /** + * authenticated users belonging to any of the group listed in DELETE_JOB_GROUPS + */ + // ------------------------------------- + // endpoint authorization + can(AuthOp.JobDelete, JobClass); + + // ------------------------------------- + // data instance authorization + can(AuthOp.JobDeleteAny, JobClass); } else { const jobUserAuthorizationValues = [ ...user.currentGroups.map((g) => "@" + g), user.username, ]; - if ( user.currentGroups.some((g) => configuration().createJobGroups.includes(g), @@ -880,7 +900,7 @@ export class CaslAbilityFactory { ]; const jobCreateInstanceAuthorizationValues = [ ...Object.values(CreateJobAuth).filter( - (v) => ~String(v).includes("#dataset"), + (v) => !String(v).includes("#dataset"), ), ...jobUserAuthorizationValues, ]; @@ -889,13 +909,17 @@ export class CaslAbilityFactory { String(v).includes("#dataset"), ), ]; - // ------------------------------------- // endpoint authorization can(AuthOp.JobRead, JobClass); + if ( configuration().jobConfiguration.some( - (j) => j.create.auth! in jobCreateEndPointAuthorizationValues, + (j) => + j.create.auth && + jobCreateEndPointAuthorizationValues.includes( + j.create.auth as string, + ), ) ) { can(AuthOp.JobCreate, JobClass); @@ -907,6 +931,7 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, ownerUser: user.username, }); + can(AuthOp.JobCreateConfiguration, JobClass, { ["configuration.create.auth" as string]: { $in: jobCreateInstanceAuthorizationValues, @@ -919,6 +944,16 @@ export class CaslAbilityFactory { datasetsValidation: true, }); } + const jobUpdateEndPointAuthorizationValues = [ + ...Object.values(StatusUpdateJobAuth), + ...jobUserAuthorizationValues, + ]; + const jobUpdateInstanceAuthorizationValues = [ + ...Object.values(StatusUpdateJobAuth).filter( + (v) => !String(v).includes("#job"), + ), + ...jobUserAuthorizationValues, + ]; if ( user.currentGroups.some((g) => @@ -931,6 +966,11 @@ export class CaslAbilityFactory { // ------------------------------------- // data instance authorization + can(AuthOp.JobStatusUpdateConfiguration, JobClass, { + ["configuration.statusUpdate.auth" as string]: { + $in: jobUpdateInstanceAuthorizationValues, + }, + }); can(AuthOp.JobStatusUpdateOwner, JobClass, { ownerUser: user.username, }); @@ -938,22 +978,15 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); } else { - const jobUpdateEndPointAuthorizationValues = [ - ...Object.values(StatusUpdateJobAuth), - ...jobUserAuthorizationValues, - ]; - const jobUpdateInstanceAuthorizationValues = [ - ...Object.values(StatusUpdateJobAuth).filter( - (v) => ~String(v).includes("#job"), - ), - ...jobUserAuthorizationValues, - ]; - // ------------------------------------- // endpoint authorization if ( configuration().jobConfiguration.some( - (j) => j.statusUpdate.auth! in jobUpdateEndPointAuthorizationValues, + (j) => + j.statusUpdate.auth && + jobUpdateEndPointAuthorizationValues.includes( + j.statusUpdate.auth as string, + ), ) ) { can(AuthOp.JobStatusUpdate, JobClass); @@ -975,6 +1008,7 @@ export class CaslAbilityFactory { ownerGroup: { $in: user.currentGroups }, }); } + cannot(AuthOp.JobDelete, JobClass); } } diff --git a/src/common/handlebars-helpers.ts b/src/common/handlebars-helpers.ts index 578a3c5be..b66e23235 100644 --- a/src/common/handlebars-helpers.ts +++ b/src/common/handlebars-helpers.ts @@ -40,6 +40,7 @@ export const formatCamelCase = (camelCase: string): string => { return words; }; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export const jsonify = (context: any): string => { return JSON.stringify(context, null, 3); }; diff --git a/src/config/configuration.ts b/src/config/configuration.ts index bf1352fcc..3fd5452c9 100644 --- a/src/config/configuration.ts +++ b/src/config/configuration.ts @@ -1,4 +1,3 @@ -import { Logger } from "@nestjs/common"; import { loadJobConfig, registerCreateAction, @@ -31,6 +30,7 @@ const configuration = () => { const createJobGroups = process.env.CREATE_JOB_GROUPS || ("" as string); const statusUpdateJobGroups = process.env.UPDATE_JOB_GROUPS || ("" as string); + const deleteJobGroups = process.env.DELETE_JOB_GROUPS || ("" as string); const proposalGroups = process.env.PROPOSAL_GROUPS || ("" as string); const sampleGroups = process.env.SAMPLE_GROUPS || ("#all" as string); @@ -44,7 +44,8 @@ const configuration = () => { process.env.OIDC_USERINFO_MAPPING_FIELD_USERNAME || ("" as string); const jobConfigurationFile = - process.env.JOB_CONFIGURATION_FILE || ("src/jobs/config/jobConfig.example.json" as string); + process.env.JOB_CONFIGURATION_FILE || + ("src/jobs/config/jobConfig.example.json" as string); const defaultLogger = { type: "DefaultLogger", @@ -109,6 +110,7 @@ const configuration = () => { datasetCreationValidationRegex: datasetCreationValidationRegex, createJobGroups: createJobGroups, statusUpdateJobGroups: statusUpdateJobGroups, + deleteJobGroups: deleteJobGroups, logoutURL: process.env.LOGOUT_URL ?? "", // Example: http://localhost:3000/ accessGroupsGraphQlConfig: { enabled: boolean(process.env?.ACCESS_GROUPS_GRAPHQL_ENABLED || false), diff --git a/src/elastic-search/elastic-search.service.ts b/src/elastic-search/elastic-search.service.ts index 59d9b4244..d3dbf1321 100644 --- a/src/elastic-search/elastic-search.service.ts +++ b/src/elastic-search/elastic-search.service.ts @@ -320,7 +320,7 @@ export class ElasticSearchService implements OnModuleInit { const totalCount = body.hits.hits.length || 0; - const data = body.hits.hits.map((item) => item._id); + const data = body.hits.hits.map((item) => item._id || ""); return { totalCount, data, @@ -361,13 +361,14 @@ export class ElasticSearchService implements OnModuleInit { } async updateInsertDocument(data: DatasetDocument) { //NOTE: Replace all keys with lower case, also replace spaces and dot with underscore - delete data._id; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { _id: unused, ...restData } = data; // type-safe delete _id const transformedScientificMetadata = transformKeysInObject( - data.scientificMetadata as Record, + restData.scientificMetadata as Record, ); const transformedData = { - ...data, + ...restData, scientificMetadata: transformedScientificMetadata, }; try { diff --git a/src/jobs/actions/emailaction.ts b/src/jobs/actions/emailaction.ts index 54d67a186..4c41587ee 100644 --- a/src/jobs/actions/emailaction.ts +++ b/src/jobs/actions/emailaction.ts @@ -9,6 +9,13 @@ import { JobClass } from "../schemas/job.schema"; import { createTransport, Transporter } from "nodemailer"; import { compile, TemplateDelegate } from "handlebars"; +type MailOptions = { + to: string; + from: string; + subject: string; + text?: string; +}; + /** * Send an email following a job */ @@ -25,7 +32,7 @@ export class EmailJobAction implements JobAction { return EmailJobAction.actionType; } - constructor(data: Record) { + constructor(data: Record) { Logger.log( "Initializing EmailJobAction. Params: " + JSON.stringify(data), "EmailJobAction", @@ -40,6 +47,9 @@ export class EmailJobAction implements JobAction { if (!data["from"]) { throw new NotFoundException("Param 'from' is undefined"); } + if (typeof data["from"] !== "string") { + throw new TypeError("from should be a string"); + } if (!data["subject"]) { throw new NotFoundException("Param 'subject' is undefined"); } @@ -69,7 +79,7 @@ export class EmailJobAction implements JobAction { ); // Fill templates - const mail: any = { + const mail: MailOptions = { to: this.toTemplate(job), from: this.from, subject: this.subjectTemplate(job), diff --git a/src/jobs/actions/logaction.ts b/src/jobs/actions/logaction.ts index b904f84ef..416f9e304 100644 --- a/src/jobs/actions/logaction.ts +++ b/src/jobs/actions/logaction.ts @@ -22,7 +22,7 @@ export class LogJobAction implements JobAction { Logger.log("Performing job: " + JSON.stringify(job), "LogJobAction"); } - constructor(data: Record) { + constructor(data: Record) { Logger.log( "Initializing LogJobAction. Params: " + JSON.stringify(data), "LogJobAction", diff --git a/src/jobs/actions/rabbitmqaction.ts b/src/jobs/actions/rabbitmqaction.ts index 9e945e3bc..cc5703fd7 100644 --- a/src/jobs/actions/rabbitmqaction.ts +++ b/src/jobs/actions/rabbitmqaction.ts @@ -3,7 +3,6 @@ import amqp, { Connection } from "amqplib/callback_api"; import { JobAction } from "../config/jobconfig"; import { JobClass } from "../schemas/job.schema"; - /** * Publish a message in a RabbitMQ queue */ @@ -12,23 +11,42 @@ export class RabbitMQJobAction implements JobAction { private connection; private binding; - constructor(data: Record) { + constructor(data: Record) { Logger.log( "Initializing RabbitMQJobAction. Params: " + JSON.stringify(data), "RabbitMQJobAction", ); + // Validate that all necessary params are present + const requiredConnectionParams = [ + "hostname", + "port", + "username", + "password", + ]; + for (const param of requiredConnectionParams) { + if (!data[param]) { + throw new NotFoundException(`Missing connection parameter: ${param}`); + } + } + + const requiredBindingParams = ["exchange", "queue", "key"]; + for (const param of requiredBindingParams) { + if (!data[param]) { + throw new NotFoundException(`Missing binding parameter: ${param}`); + } + } this.connection = { protocol: "amqp", - hostname: data.hostname, - port: data.port, - username: data.username, - password: data.password, + hostname: data.hostname as string, + port: data.port as number, + username: data.username as string, + password: data.password as string, }; this.binding = { - exchange: data.exchange, - queue: data.queue, - key: data.key + exchange: data.exchange as string, + queue: data.queue as string, + key: data.key as string, }; } @@ -36,22 +54,8 @@ export class RabbitMQJobAction implements JobAction { return RabbitMQJobAction.actionType; } - async validate(dto: T) { - Logger.log( - "Validating RabbitMQJobAction: " + JSON.stringify(dto), - "RabbitMQJobAction", - ); - - const connectionDetailsMissing = [undefined, ""].some(el => Object.values(this.connection).includes(el)); - if (connectionDetailsMissing) { - throw new NotFoundException("RabbitMQ configuration is missing connection details."); - } - - const bindingDetailsMissing = [undefined, ""].some(el => Object.values(this.binding).includes(el)); - if (bindingDetailsMissing) { - throw new NotFoundException("RabbitMQ binding is missing exchange/queue/key details."); - } - } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async validate(dto: T) {} async performJob(job: JobClass) { Logger.log( @@ -59,33 +63,47 @@ export class RabbitMQJobAction implements JobAction { "RabbitMQJobAction", ); - amqp.connect(this.connection, (connectionError: Error, connection: Connection) => { - if (connectionError) { - Logger.error( - "Connection error in RabbitMQJobAction: " + JSON.stringify(connectionError.message), - "RabbitMQJobAction", - ); - return; - } - - connection.createChannel((channelError: Error, channel) => { - if (channelError) { + amqp.connect( + this.connection, + (connectionError: Error, connection: Connection) => { + if (connectionError) { Logger.error( - "Channel error in RabbitMQJobAction: " + JSON.stringify(channelError.message), + "Connection error in RabbitMQJobAction: " + + JSON.stringify(connectionError.message), "RabbitMQJobAction", ); return; } - channel.assertQueue(this.binding.queue, { durable: true }); - channel.assertExchange(this.binding.exchange, "topic", { durable: true }); - channel.bindQueue(this.binding.queue, this.binding.exchange, this.binding.key); - channel.sendToQueue(this.binding.queue, Buffer.from(JSON.stringify(job))); + connection.createChannel((channelError: Error, channel) => { + if (channelError) { + Logger.error( + "Channel error in RabbitMQJobAction: " + + JSON.stringify(channelError.message), + "RabbitMQJobAction", + ); + return; + } - channel.close(() => { - connection.close(); + channel.assertQueue(this.binding.queue, { durable: true }); + channel.assertExchange(this.binding.exchange, "topic", { + durable: true, + }); + channel.bindQueue( + this.binding.queue, + this.binding.exchange, + this.binding.key, + ); + channel.sendToQueue( + this.binding.queue, + Buffer.from(JSON.stringify(job)), + ); + + channel.close(() => { + connection.close(); + }); }); - }); - }); + }, + ); } } diff --git a/src/jobs/actions/urlaction.ts b/src/jobs/actions/urlaction.ts index 0ffe9f68c..ac4266fb8 100644 --- a/src/jobs/actions/urlaction.ts +++ b/src/jobs/actions/urlaction.ts @@ -1,9 +1,4 @@ -import { - Logger, - NotFoundException, - BadRequestException, - HttpException, -} from "@nestjs/common"; +import { Logger, NotFoundException, HttpException } from "@nestjs/common"; import { JobAction } from "../config/jobconfig"; import { JobClass } from "../schemas/job.schema"; import * as Handlebars from "handlebars"; @@ -32,12 +27,13 @@ export class URLAction implements JobAction { private urlTemplate: Handlebars.TemplateDelegate; private method = "GET"; private headers: Record = {}; - private body: Record | null = null; + private body: Record | null = null; getActionType(): string { return URLAction.actionType; } + // eslint-disable-next-line @typescript-eslint/no-unused-vars async validate(dto: T) {} async performJob(job: JobClass) { @@ -75,6 +71,7 @@ export class URLAction implements JobAction { * * @throws {NotFoundException} If the 'url' parameter is not provided in the data object */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(data: Record) { if (!data["url"]) { throw new NotFoundException("Param 'url' is undefined in url action"); diff --git a/src/jobs/config/jobconfig.spec.ts b/src/jobs/config/jobconfig.spec.ts index 819c85182..7f7db98b4 100644 --- a/src/jobs/config/jobconfig.spec.ts +++ b/src/jobs/config/jobconfig.spec.ts @@ -14,8 +14,8 @@ describe("Job configuration", () => { const path = "test/config/jobconfig.json"; const config = await loadJobConfig(path); expect(config).toBeDefined(); - expect(config.length).toBe(1); - expect(config[0].jobType).toBe("archive"); + expect(config.length).toBe(7); + expect(config[0].jobType).toBe("all_access"); expect(config[0].create).toBeDefined(); const create = config[0].create; expect(create.actions.length).toBe(1); diff --git a/src/jobs/config/jobconfig.ts b/src/jobs/config/jobconfig.ts index 6621ceabf..06658ef53 100644 --- a/src/jobs/config/jobconfig.ts +++ b/src/jobs/config/jobconfig.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ /** * Job configuration * @@ -24,7 +23,6 @@ import { CreateJobAuth, JobsAuth } from "../types/jobs-auth.enum"; import Ajv from "ajv"; import { JobConfigSchema } from "./jobConfig.schema"; - /** * Encapsulates all responses to a particular job type (eg "archive") */ @@ -32,20 +30,17 @@ export class JobConfig { jobType: string; configVersion: string; create: JobOperation; - // read: JobOperation; statusUpdate: JobOperation; constructor( jobType: string, configVersion: string, create: JobOperation, - read = undefined, statusUpdate: JobOperation, ) { this.jobType = jobType; this.configVersion = configVersion; this.create = create; - // this.read = read; this.statusUpdate = statusUpdate; } @@ -55,24 +50,36 @@ export class JobConfig { * @returns */ static parse( - jobData: Record, - configVersion: string + jobData: Record, + configVersion: string, ): JobConfig { - const type = jobData[JobsConfigSchema.JobType]; + if ( + !(JobsConfigSchema.JobType in jobData) || + typeof jobData[JobsConfigSchema.JobType] !== "string" + ) { + throw new Error(`Invalid job type`); + } + const type = jobData[JobsConfigSchema.JobType] as string; + if (!(AuthOp.Create in jobData)) { + throw new Error(`No ${AuthOp.Create} configured for job type "${type}"`); + } + if (!(AuthOp.StatusUpdate in jobData)) { + throw new Error( + `No ${AuthOp.StatusUpdate} configured for job type "${type}"`, + ); + } const create = JobOperation.parse( createActions, - jobData[AuthOp.Create], + jobData[AuthOp.Create] as Record, ); - const read = undefined; const statusUpdate = JobOperation.parse( statusUpdateActions, - jobData[AuthOp.StatusUpdate], + jobData[AuthOp.StatusUpdate] as Record, ); - return new JobConfig(type, configVersion, create, read, statusUpdate); + return new JobConfig(type, configVersion, create, statusUpdate); } } - /** * Encapsulates all information for a particular job operation (eg "create", "statusUpdate") */ @@ -87,23 +94,36 @@ export class JobOperation { static parse( actionList: Record>, - data: Record, + data: Record, ): JobOperation { // if Auth is not defined, default to #authenticated - const auth = data[JobsConfigSchema.Auth] - ? data[JobsConfigSchema.Auth] - : CreateJobAuth.Authenticated; - const actionsData: any[] = data[JobsConfigSchema.Actions] - ? data[JobsConfigSchema.Actions] - : []; - const actions = actionsData.map((json) => - parseAction(actionList, json), - ); + let auth: JobsAuth = CreateJobAuth.Authenticated; + if (data[JobsConfigSchema.Auth]) { + // don't bother to validate auth value + if (typeof data[JobsConfigSchema.Auth] !== "string") { + throw new Error( + `Invalid auth value "${data[JobsConfigSchema.Auth]}" for job type`, + ); + } + auth = data[JobsConfigSchema.Auth] as JobsAuth; + } + let actionsData: unknown[] = []; + if (JobsConfigSchema.Actions in data) { + if (!Array.isArray(data[JobsConfigSchema.Actions])) { + throw new Error(`Expected array for ${JobsConfigSchema.Actions} value`); + } + actionsData = data[JobsConfigSchema.Actions]; + } + const actions = actionsData.map((json) => { + if (typeof json !== "object") { + throw new Error(`Expected object for job config action`); + } + return parseAction(actionList, json as Record); + }); return new JobOperation(actions, auth); } } - /** * Given a JSON object configuring a JobConfigAction. * @@ -114,11 +134,13 @@ export class JobOperation { */ function parseAction( actionList: Record>, - data: Record, + data: Record, ): JobAction { if (!(JobsConfigSchema.ActionType in data)) throw SyntaxError(`No action.actionType in ${JSON.stringify(data)}`); - + if (typeof data[JobsConfigSchema.ActionType] !== "string") { + throw SyntaxError(`Expected string for ${JobsConfigSchema.ActionType}`); + } const type = data[JobsConfigSchema.ActionType]; if (!(type in actionList)) { throw SyntaxError(`No handler found for actions of type ${type}`); @@ -128,7 +150,6 @@ function parseAction( return new actionClass(data); } - /** * Superclass for all responses to Job changes */ @@ -150,7 +171,6 @@ export interface JobAction { getActionType(): string; } - /** * Describes the constructor and static members for JobAction implementations */ @@ -159,28 +179,27 @@ export interface JobActionClass { * Action type, eg "url". Matched during parsing of the action */ readonly actionType: string; - new (json: Record): JobAction; + new (json: Record): JobAction; } export type JobCreateAction = JobAction; // export type JobReadAction = JobAction; export type JobStatusUpdateAction = JobAction; - /** * Action registration */ const createActions: Record> = {}; -// const readActions: Record> = {}; -const statusUpdateActions: Record> = {}; +const statusUpdateActions: Record< + string, + JobActionClass +> = {}; /** * Registers an action to handle jobs of a particular type * @param action */ -export function registerCreateAction( - action: JobActionClass -) { +export function registerCreateAction(action: JobActionClass) { createActions[action.actionType] = action; } @@ -202,7 +221,6 @@ export function getRegisteredStatusUpdateActions(): string[] { return Object.keys(statusUpdateActions); } - /** * Parsing */ @@ -220,7 +238,7 @@ export function loadJobConfig(filePath: string): JobConfig[] { } const json = fs.readFileSync(filePath, "utf8"); - let data = JSON.parse(json); + const data = JSON.parse(json); // Validate schema const ajv = new Ajv(); @@ -232,6 +250,8 @@ export function loadJobConfig(filePath: string): JobConfig[] { console.log("Invalid Schema", JSON.stringify(validate.errors, null, 2)); } - jobConfig = data.jobs.map((jobData: Record) => JobConfig.parse(jobData, data.configVersion)); + jobConfig = data.jobs.map((jobData: Record) => + JobConfig.parse(jobData, data.configVersion), + ); return jobConfig as JobConfig[]; } diff --git a/src/jobs/jobs.controller.spec.ts b/src/jobs/jobs.controller.spec.ts index cc293eecd..73d0358e3 100644 --- a/src/jobs/jobs.controller.spec.ts +++ b/src/jobs/jobs.controller.spec.ts @@ -1,14 +1,17 @@ import { EventEmitter2 } from "@nestjs/event-emitter"; import { Test, TestingModule } from "@nestjs/testing"; -import { CaslAbilityFactory } from "src/casl/casl-ability.factory"; +import { CaslModule } from "src/casl/casl.module"; +//import { CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { DatasetsService } from "src/datasets/datasets.service"; import { OrigDatablocksService } from "src/origdatablocks/origdatablocks.service"; import { JobsController } from "./jobs.controller"; import { JobsService } from "./jobs.service"; +import { UsersService } from "src/users/users.service"; class JobsServiceMock {} class DatasetsServiceMock {} class OrigDatablocksServiceMock {} +class UsersServiceMock {} describe("JobsController", () => { let controller: JobsController; @@ -16,11 +19,13 @@ describe("JobsController", () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [JobsController], + imports: [CaslModule], providers: [ - CaslAbilityFactory, + //CaslAbilityFactory, { provide: JobsService, useClass: JobsServiceMock }, { provide: DatasetsService, useClass: DatasetsServiceMock }, { provide: OrigDatablocksService, useClass: OrigDatablocksServiceMock }, + { provide: UsersService, useClass: UsersServiceMock }, { provide: EventEmitter2, useClass: EventEmitter2 }, ], }).compile(); diff --git a/src/jobs/jobs.controller.ts b/src/jobs/jobs.controller.ts index 3257d774a..062231c6f 100644 --- a/src/jobs/jobs.controller.ts +++ b/src/jobs/jobs.controller.ts @@ -23,6 +23,7 @@ import { PoliciesGuard } from "src/casl/guards/policies.guard"; import { CheckPolicies } from "src/casl/decorators/check-policies.decorator"; import { AppAbility, CaslAbilityFactory } from "src/casl/casl-ability.factory"; import { AuthOp } from "src/casl/authop.enum"; +import { CreateJobAuth } from "src/jobs/types/jobs-auth.enum"; import { JobClass, JobDocument } from "./schemas/job.schema"; import { ApiBearerAuth, @@ -62,7 +63,7 @@ export class JobsController { private readonly usersService: UsersService, private eventEmitter: EventEmitter2, ) { - this.jobDatasetAuthorization = Object.values(AuthOp).filter((v) => + this.jobDatasetAuthorization = Object.values(CreateJobAuth).filter((v) => v.includes("#dataset"), ); } @@ -275,7 +276,6 @@ export class JobsController { return true; }; - /** * Check that the user is authenticated */ @@ -293,17 +293,7 @@ export class JobsController { /** * Check that the dataset ids list is valid */ - checkDatasetIds = (jobParams: Record | undefined) => { - if (!jobParams) { - throw new HttpException( - { - status: HttpStatus.BAD_REQUEST, - message: "Dataset ids list was not provided in jobParams", - }, - HttpStatus.BAD_REQUEST, - ); - } - + async checkDatasetIds(jobParams: Record): Promise { const field = JobsConfigSchema.DatasetIds; const datasetIds = ( typeof jobParams[field] === "string" @@ -320,31 +310,78 @@ export class JobsController { HttpStatus.BAD_REQUEST, ); } + interface condition { + where: { + pid: { $in: string[] }; + }; + } + if (datasetIds.length == 0) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: "List of passed dataset IDs is empty.", + }, + HttpStatus.BAD_REQUEST, + ); + } + + const filter: condition = { + where: { + pid: { $in: datasetIds }, + }, + }; + const findDatasetsById = await this.datasetsService.findAll(filter); + const findIds = findDatasetsById.map(({ pid }) => pid); + const nonExistIds = datasetIds.filter((x) => !findIds.includes(x)); + if (nonExistIds.length != 0) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: ` Datasets with pid ${nonExistIds} don't exist.`, + }, + HttpStatus.BAD_REQUEST, + ); + } return datasetIds; - }; + } + + /** + * Create instance of JobClass to check permissions + */ + async generateJobInstanceForPermissions(job: JobClass): Promise { + const jobInstance = new JobClass(); + jobInstance._id = job._id; + jobInstance.id = job.id; + jobInstance.type = job.type; + //jobInstance.configuration = configuration().statusUpdateJobGroups; + jobInstance.ownerGroup = job.ownerGroup; + jobInstance.ownerUser = job.ownerUser; + + return jobInstance; + } /** * Check job type matching configuration */ - getJobMatchingConfiguration = (createJobDto: CreateJobDtoWithConfig) => { + getJobMatchingConfiguration = (createJobDtoType: string) => { const jobConfigs = configuration().jobConfiguration; const matchingConfig = jobConfigs.filter( - (j) => j.jobType == createJobDto.type, + (j) => j.jobType == createJobDtoType, ); if (matchingConfig.length != 1) { if (matchingConfig.length > 1) { Logger.error( - "More than one job configurations matching type " + createJobDto.type, + "More than one job configurations matching type " + createJobDtoType, ); } else { - Logger.error("No job configuration matching type " + createJobDto.type); + Logger.error("No job configuration matching type " + createJobDtoType); } // return error that job type does not exists throw new HttpException( { status: HttpStatus.BAD_REQUEST, - message: "Invalid job type: " + createJobDto.type, + message: "Invalid job type: " + createJobDtoType, }, HttpStatus.BAD_REQUEST, ); @@ -362,32 +399,27 @@ export class JobsController { // NOTE: We need JobClass instance because casl module works only on that. // If other fields are needed can be added later. const jobInstance = new JobClass(); - const jobConfiguration = this.getJobMatchingConfiguration(jobCreateDto); + const jobConfiguration = this.getJobMatchingConfiguration( + jobCreateDto.type, + ); jobInstance._id = ""; - jobInstance.ownerUser = ""; - jobInstance.ownerGroup = ""; jobInstance.accessGroups = []; jobInstance.type = jobCreateDto.type; jobInstance.contactEmail = jobCreateDto.contactEmail; + jobInstance.jobParams = jobCreateDto.jobParams; jobInstance.datasetsValidation = false; jobInstance.configuration = jobConfiguration; jobInstance.statusCode = "Initializing"; jobInstance.statusMessage = "Building and validating job, verifying authorization"; + // if datasetIds property in jobParams is passed, check if such IDs exist in data base + let datasetIds: string[] = []; + if (JobsConfigSchema.DatasetIds in jobCreateDto.jobParams) { + datasetIds = await this.checkDatasetIds(jobCreateDto.jobParams); + } if (user) { - // check if we have ownerGroup - if (!jobCreateDto.ownerGroup) { - throw new HttpException( - { - status: HttpStatus.BAD_REQUEST, - message: `Invalid new job. Owner group should be specified`, - }, - HttpStatus.BAD_REQUEST, - ); - } - // the request comes from a user who is logged in. if ( user.currentGroups.some((g) => configuration().adminGroups.includes(g)) @@ -399,11 +431,20 @@ export class JobsController { jobCreateDto.ownerUser, ); } - jobInstance.ownerUser = jobUser?.username as string; jobInstance.contactEmail = jobUser?.email as string; jobInstance.ownerGroup = jobCreateDto.ownerGroup; } else { + // check if we have ownerGroup + if (!jobCreateDto.ownerGroup) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: `Invalid new job. Owner group should be specified.`, + }, + HttpStatus.BAD_REQUEST, + ); + } // check that job user matches the user placing the request, if job user is specified if (jobCreateDto.ownerUser && jobCreateDto.ownerUser != user.username) { throw new HttpException( @@ -421,7 +462,7 @@ export class JobsController { throw new HttpException( { status: HttpStatus.BAD_REQUEST, - message: `Invalid new job. User needs to belong to job owner group`, + message: `Invalid new job. User needs to belong to job owner group.`, }, HttpStatus.BAD_REQUEST, ); @@ -432,26 +473,51 @@ export class JobsController { if ( jobConfiguration.create.auth && - jobConfiguration.create.auth in this.jobDatasetAuthorization + Object.values(this.jobDatasetAuthorization).includes( + jobConfiguration.create.auth, + ) ) { + // check that jobParams are passed for #dataset jobs + if (!jobCreateDto.jobParams) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: "Dataset ids list was not provided in jobParams", + }, + HttpStatus.BAD_REQUEST, + ); + } // verify that the user meet the requested permissions on the datasets listed - const datasetIds = this.checkDatasetIds(jobCreateDto.jobParams); + // const datasetIds = await this.checkDatasetIds(jobCreateDto.jobParams); // build the condition - const datasetsWhere: Record = { + interface datasetsWhere { + where: { + pid: { $in: string[] }; + isPublished?: boolean; + ownerGroup?: { $in: string[] }; + $or?: [ + { ownerGroup: { $in: string[] } }, + { accessGroups: { $in: string[] } }, + { isPublished: true }, + ]; + }; + } + + const datasetsWhere: datasetsWhere = { where: { pid: { $in: datasetIds }, }, }; if (jobConfiguration.create.auth === "#datasetPublic") { - datasetsWhere["isPublished"] = true; + datasetsWhere["where"]["isPublished"] = true; } else if (jobConfiguration.create.auth === "#datasetAccess") { - datasetsWhere["$or"] = [ + datasetsWhere["where"]["$or"] = [ { ownerGroup: { $in: user.currentGroups } }, { accessGroups: { $in: user.currentGroups } }, { isPublished: true }, ]; } else if (jobConfiguration.create.auth === "#datasetOwner") { - datasetsWhere["ownerGroup"] = { $in: user.currentGroups }; + datasetsWhere["where"]["ownerGroup"] = { $in: user.currentGroups }; } const numberOfDatasetsWithAccess = await this.datasetsService.count(datasetsWhere); @@ -459,6 +525,15 @@ export class JobsController { datasetIds.length - numberOfDatasetsWithAccess.count; jobInstance.datasetsValidation = datasetsNoAccess == 0; } + if (!user && jobCreateDto.ownerGroup) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: `Invalid new job. Unauthenticated user cannot initiate a job owned by another user.`, + }, + HttpStatus.BAD_REQUEST, + ); + } // instantiate the casl matrix for the user const ability = this.caslAbilityFactory.createForUser(user); @@ -469,7 +544,7 @@ export class JobsController { ability.can(AuthOp.JobCreateConfiguration, jobInstance); if (!canCreate) { - throw new ForbiddenException("Unauthorized to create this dataset"); + throw new ForbiddenException("Unauthorized to create this dataset."); } return jobInstance; @@ -478,7 +553,10 @@ export class JobsController { /** * Send off to external service */ - async performJobAction(jobInstance: JobClass, action: JobAction | JobAction): Promise { + async performJobAction( + jobInstance: JobClass, + action: JobAction | JobAction, + ): Promise { await action.performJob(jobInstance).catch((err: Error) => { if (err instanceof HttpException) { throw err; @@ -496,7 +574,7 @@ export class JobsController { } async performJobCreateAction(jobInstance: JobClass): Promise { - const jobConfig = this.getJobMatchingConfiguration(jobInstance); + const jobConfig = this.getJobMatchingConfiguration(jobInstance.type); for (const action of jobConfig.create.actions) { await this.performJobAction(jobInstance, action); } @@ -504,7 +582,7 @@ export class JobsController { } async performJobStatusUpdateAction(jobInstance: JobClass): Promise { - const jobConfig = this.getJobMatchingConfiguration(jobInstance); + const jobConfig = this.getJobMatchingConfiguration(jobInstance.type); await Promise.all( jobConfig.statusUpdate.actions.map((action) => { @@ -533,7 +611,6 @@ export class JobsController { return; } - /** * Create job */ @@ -562,6 +639,19 @@ export class JobsController { @Body() createJobDtoWithConfig: CreateJobDtoWithConfig, ): Promise { Logger.log("Creating job!"); + // throw an error if no jobParams are passed + if ( + !createJobDtoWithConfig.jobParams || + Object.keys(createJobDtoWithConfig.jobParams).length == 0 + ) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: "Job parameters need to be defined.", + }, + HttpStatus.BAD_REQUEST, + ); + } // Validate that request matches the current configuration // Check job authorization const jobInstance = await this.instanceAuthorizationJobCreate( @@ -569,37 +659,12 @@ export class JobsController { request.user as JWTUser, ); // Create actual job in database - const createdJobInstance = await this.jobsService.create( - jobInstance, - ); - + const createdJobInstance = await this.jobsService.create(jobInstance); // Perform the action that is specified in the create portion of the job configuration await this.performJobCreateAction(createdJobInstance); return createdJobInstance; } - /** - * Checking if user is allowed to create job according to auth field of job configuration - */ - async instanceAuthorizationJobStatusUpdate( - user: JWTUser, - jobInstance: JobClass, - ): Promise { - // instantiate the casl matrix for the user - const ability = this.caslAbilityFactory.createForUser(user); - // check if he/she can create this dataset - const canCreate = - ability.can(AuthOp.JobStatusUpdateAny, JobClass) || - ability.can(AuthOp.JobStatusUpdateOwner, jobInstance) || - ability.can(AuthOp.JobStatusUpdateConfiguration, jobInstance); - - if (!canCreate) { - throw new ForbiddenException("Unauthorized to update this dataset"); - } - - return jobInstance; - } - /** * Update job status */ @@ -639,13 +704,29 @@ export class JobsController { HttpStatus.BAD_REQUEST, ); } - // Check job authorization - await this.instanceAuthorizationJobStatusUpdate( + const currentJobInstance = + await this.generateJobInstanceForPermissions(currentJob); + currentJobInstance.configuration = this.getJobMatchingConfiguration( + currentJobInstance.type, + ); + + const ability = this.caslAbilityFactory.createForUser( request.user as JWTUser, - currentJob, ); + // check if he/she can create this dataset + const canUpdateStatus = + ability.can(AuthOp.JobStatusUpdateAny, JobClass) || + ability.can(AuthOp.JobStatusUpdateOwner, currentJobInstance) || + ability.can(AuthOp.JobStatusUpdateConfiguration, currentJobInstance); + if (!canUpdateStatus) { + throw new ForbiddenException("Unauthorized to update this dataset"); + } + // Update job in database - const updatedJob = await this.jobsService.statusUpdate(id, statusUpdateJobDto); + const updatedJob = await this.jobsService.statusUpdate( + id, + statusUpdateJobDto, + ); // Perform the action that is specified in the update portion of the job configuration if (updatedJob !== null) { await this.performJobStatusUpdateAction(updatedJob); @@ -681,7 +762,28 @@ export class JobsController { @Req() request: Request, @Param("id") id: string, ): Promise { - return this.jobsService.findOne({ _id: id }); + const currentJob = await this.jobsService.findOne({ _id: id }); + if (currentJob === null) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: "Invalid job id.", + }, + HttpStatus.BAD_REQUEST, + ); + } + const currentJobInstance = + await this.generateJobInstanceForPermissions(currentJob); + const ability = this.caslAbilityFactory.createForUser( + request.user as JWTUser, + ); + const canCreate = + ability.can(AuthOp.JobReadAny, JobClass) || + ability.can(AuthOp.JobReadAccess, currentJobInstance); + if (!canCreate) { + throw new ForbiddenException("Unauthorized to update this dataset"); + } + return currentJob; } /** @@ -711,7 +813,7 @@ export class JobsController { async findAll( @Req() request: Request, @Query("filter") filter?: string, - ): Promise { + ): Promise { try { filter = filter ?? "{}"; JSON.parse(filter as string); @@ -724,9 +826,27 @@ export class JobsController { if (!this.isFilterValid(Object.keys(parsedFilter))) { throw { message: "Invalid filter syntax." }; } - return this.jobsService.findAll(parsedFilter); - } - catch (e) { + // for each job run a casl JobReadOwner on a jobInstance + const datasetsFound = await this.jobsService.findAll(parsedFilter); + const datasetsAccessible: JobClass[] = []; + const ability = this.caslAbilityFactory.createForUser( + request.user as JWTUser, + ); + + for (const i in datasetsFound) { + // check if he/she can create this dataset + const jobInstance = await this.generateJobInstanceForPermissions( + datasetsFound[i], + ); + const canCreate = + ability.can(AuthOp.JobReadAny, JobClass) || + ability.can(AuthOp.JobReadAccess, jobInstance); + if (canCreate) { + datasetsAccessible.push(datasetsFound[i]); + } + } + return datasetsAccessible; + } catch (e) { throw new HttpException( { status: HttpStatus.BAD_REQUEST, @@ -742,7 +862,9 @@ export class JobsController { */ @UseGuards(PoliciesGuard) @CheckPolicies( - (ability: AppAbility) => ability.can(AuthOp.Delete, JobClass), // TBD + (ability: AppAbility) => + ability.can(AuthOp.JobDelete, JobClass) && + ability.can(AuthOp.JobDeleteAny, JobClass), ) @Delete(":id") @ApiOperation({ @@ -758,6 +880,18 @@ export class JobsController { @Req() request: Request, @Param("id") id: string, ): Promise { + const foundJob = await this.jobsService.findOne({ _id: id }); + if (foundJob === null) { + throw new HttpException( + { + status: HttpStatus.BAD_REQUEST, + message: `Job id ${id} doesn't exist.`, + }, + HttpStatus.BAD_REQUEST, + ); + } + + Logger.log(`Deleting job with id ${id}!`); return this.jobsService.remove({ _id: id }); } } diff --git a/src/jobs/jobs.service.ts b/src/jobs/jobs.service.ts index c9cfa5e2b..f380bf08e 100644 --- a/src/jobs/jobs.service.ts +++ b/src/jobs/jobs.service.ts @@ -30,10 +30,16 @@ export class JobsService { @Inject(REQUEST) private request: Request, ) {} - async create( - createJobDto: CreateJobDto, - ): Promise { - const username = (this.request.user as JWTUser).username; + getUsername(): string { + if (this.request.user as JWTUser) { + return (this.request.user as JWTUser).username; + } else { + return "anonymous"; + } + } + + async create(createJobDto: CreateJobDto): Promise { + const username = this.getUsername(); const createdJob = new this.jobModel( addStatusFields( addCreatedByFields(createJobDto, username), @@ -45,9 +51,9 @@ export class JobsService { } async findAll( - filter: IFilters> + filter: IFilters>, ): Promise { - var whereFilters: FilterQuery = filter.where ?? {}; + const whereFilters: FilterQuery = filter.where ?? {}; const { limit, skip, sort } = parseLimitFilters(filter.limits); return this.jobModel @@ -94,13 +100,16 @@ export class JobsService { if (!existingJob) { throw new NotFoundException(`Job #${id} not found`); } - const username = (this.request.user as JWTUser).username; + const username = this.getUsername(); const updatedJob = await this.jobModel .findOneAndUpdate( { id: id }, addStatusFields( - addUpdatedByField(statusUpdateJobDto as UpdateQuery, username), + addUpdatedByField( + statusUpdateJobDto as UpdateQuery, + username, + ), statusUpdateJobDto.statusCode, statusUpdateJobDto.statusMessage!, ), diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 2f96d25ae..6675324fc 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -238,7 +238,7 @@ export class UsersService implements OnModuleInit { async findByUsername2JWTUser(username: string): Promise { const userIdentity = await this.userIdentityModel - .findOne({ username: username }) + .findOne({ "profile.username": username }) .exec(); if (userIdentity) { const userProfile = userIdentity.profile; diff --git a/test/DatasetAuthorization.js b/test/DatasetAuthorization.js index b2ab8c39d..bcecc2b03 100644 --- a/test/DatasetAuthorization.js +++ b/test/DatasetAuthorization.js @@ -42,6 +42,9 @@ const dataset3 = { }; describe("0300: DatasetAuthorization: Test access to dataset", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/DatasetFilter.js b/test/DatasetFilter.js index 05d64550e..37b71bf79 100644 --- a/test/DatasetFilter.js +++ b/test/DatasetFilter.js @@ -89,6 +89,9 @@ const RawCorrect4 = { }; describe("0400: DatasetFilter: Test retrieving datasets using filtering capabilities", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/DatasetLifecycle.js b/test/DatasetLifecycle.js index 8c9b4749c..2f3fed3bc 100644 --- a/test/DatasetLifecycle.js +++ b/test/DatasetLifecycle.js @@ -13,6 +13,9 @@ var policyIds = null; const raw2 = { ...TestData.RawCorrect }; describe("0500: DatasetLifecycle: Test facet and filter queries", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/DerivedDataset.js b/test/DerivedDataset.js index efce61e31..61b960799 100644 --- a/test/DerivedDataset.js +++ b/test/DerivedDataset.js @@ -14,6 +14,9 @@ var minPid = null; var explicitPid = null; describe("0700: DerivedDataset: Derived Datasets", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/DerivedDatasetDatablock.js b/test/DerivedDatasetDatablock.js index 1621e03a9..ca62c7fc8 100644 --- a/test/DerivedDatasetDatablock.js +++ b/test/DerivedDatasetDatablock.js @@ -12,6 +12,9 @@ describe("0750: DerivedDatasetDatablock: Test Datablocks and their relation to d let datablockId2 = null; beforeEach((done) => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); utils.getToken( appUrl, { diff --git a/test/DerivedDatasetOrigDatablock.js b/test/DerivedDatasetOrigDatablock.js index c9f96ea2e..a8566b816 100644 --- a/test/DerivedDatasetOrigDatablock.js +++ b/test/DerivedDatasetOrigDatablock.js @@ -12,6 +12,10 @@ describe("0800: DerivedDatasetOrigDatablock: Test OrigDatablocks and their relat let origDatablockId2 = null; beforeEach((done) => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("OrigDatablock").deleteMany({}); + }); utils.getToken( appUrl, { diff --git a/test/ElasticSearch.js b/test/ElasticSearch.js index c65141758..a34551ab1 100644 --- a/test/ElasticSearch.js +++ b/test/ElasticSearch.js @@ -44,6 +44,9 @@ const scientificMetadata = ({ (isESenabled ? describe : describe.skip)( "ElastiSearch: CRUD, filtering and search test case", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/Instrument.js b/test/Instrument.js index bb630e10c..613f5f621 100644 --- a/test/Instrument.js +++ b/test/Instrument.js @@ -17,6 +17,9 @@ let accessTokenAdminIngestor = null, const newName = "ESS3-1"; describe("0900: Instrument: instrument management, creation, update, deletion and search", () => { + before(() => { + db.collection("Instrument").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/InstrumentsFilter.js b/test/InstrumentsFilter.js index 973e6e879..a3958f90d 100644 --- a/test/InstrumentsFilter.js +++ b/test/InstrumentsFilter.js @@ -42,6 +42,9 @@ const InstrumentCorrect4 = { }; describe("1000: InstrumentFilter: Test retrieving instruments using filtering capabilities", () => { + before(() => { + db.collection("Instrument").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, @@ -79,7 +82,8 @@ describe("1000: InstrumentFilter: Test retrieving instruments using filtering ca appUrl, { username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], + password: + TestData.Accounts["archiveManager"]["password"], }, (tokenVal) => { accessTokenArchiveManager = tokenVal; diff --git a/test/Jobs.js b/test/Jobs.js index 9d7ec1f60..e9d48638a 100644 --- a/test/Jobs.js +++ b/test/Jobs.js @@ -1,33 +1,151 @@ /* eslint-disable @typescript-eslint/no-var-requires */ "use strict"; +const { and } = require("ajv/dist/compile/codegen"); var utils = require("./LoginUtils"); const { TestData } = require("./TestData"); -var accessTokenAdminIngestor = null; -var accessTokenArchiveManager = null; +let accessTokenAdminIngestor = null, + accessTokenUser1 = null, + accessTokenUser3 = null, + accessTokenUser51 = null, + accessTokenUser52 = null, + accessTokenAdmin = null, + accessTokenArchiveManager = null; -var pid1 = null; -var pid2 = null; -var datasetLiveCycle1 = {}; -var datasetLiveCycle2 = {}; -var archiveJob = null; -var retrieveJob = null; -var publicJob = null; -var archiveJobId = null; -var retrieveJobId = null; -var publicJobIds = []; -var origDatablockId = null; -describe.skip("1100: Jobs: Test New Job Model", () => { - before((done) => { - archiveJob = { ...TestData.ArchiveJob }; - retrieveJob = { ...TestData.RetrieveJob }; - publicJob = { ...TestData.PublicJob }; - done(); +let datasetPid1 = null, + datasetPid2 = null, + datasetPid3 = null, + jobId1 = null, + encodedJobId1 = null, + jobId2 = null, + encodedJobId2 = null, + jobId3 = null, + encodedJobId3 = null, + jobId4 = null, + encodedJobId4 = null, + jobId5 = null, + encodedJobId5 = null, + jobId6 = null, + encodedJobId6 = null, + + jobIdGroup1 = null, + encodedJobIdGroup1 = null, + jobIdGroup2 = null, + encodedJobIdGroup2 = null, + jobIdGroup3 = null, + encodedJobIdGroup3 = null, + jobIdGroup4 = null, + encodedJobIdGroup4 = null, + jobIdGroup5 = null, + encodedJobIdGroup5 = null, + jobIdGroup6 = null, + encodedJobIdGroup6 = null, + + jobIdUser1 = null, + encodedJobIdUser1 = null, + jobIdUser2 = null, + encodedJobIdUser2 = null, + jobIdUser3 = null, + encodedJobIdUser3 = null, + jobIdUser4 = null, + encodedJobIdUser4 = null, + jobIdUser5 = null, + encodedJobIdUser5 = null, + jobIdUser6 = null, + encodedJobIdUser6 = null, + + jobIdUserSpec1 = null, + encodedJobIdUserSpec1 = null, + jobIdUserSpec2 = null, + encodedJobIdUserSpec2 = null, + jobIdUserSpec3 = null, + encodedJobIdUserSpec3 = null, + jobIdUserSpec4 = null, + encodedJobIdUserSpec4 = null, + jobIdUserSpec5 = null, + encodedJobIdUserSpec5 = null, + jobIdUserSpec6 = null, + encodedJobIdUserSpec6 = null, + jobIdUserSpec7 = null, + encodedJobIdUserSpec7 = null, + + jobIdGroupSpec1 = null, + encodedJobIdGroupSpec1 = null, + jobIdGroupSpec2 = null, + encodedJobIdGroupSpec2 = null, + jobIdGroupSpec3 = null, + encodedJobIdGroupSpec3 = null, + jobIdGroupSpec4 = null, + encodedJobIdGroupSpec4 = null, + jobIdGroupSpec5 = null, + encodedJobIdGroupSpec5 = null, + jobIdGroupSpec6 = null, + encodedJobIdGroupSpec6 = null, + jobIdGroupSpec7 = null, + encodedJobIdGroupSpec7 = null, + jobIdGroupSpec8 = null, + encodedJobIdGroupSpec8 = null; + + +const dataset1 = { + ...TestData.RawCorrect, + isPublished: true, + ownerGroup: "group1", + accessGroups: ["group5"], +}; + +const dataset2 = { + ...TestData.RawCorrect, + isPublished: false, + ownerGroup: "group2", + accessGroups: [], +}; + +const dataset3 = { + ...TestData.RawCorrect, + isPublished: false, + ownerGroup: "group5", + accessGroups: ["group1"], +}; +const jobAll = { + ...TestData.Job, + type: "all_access", +}; +const jobDatasetPublic = { + ...TestData.Job, + type: "public_access", +} +const jobAuthenticated = { + ...TestData.Job, + type: "authenticated_access" +}; +const jobDatasetAccess = { + ...TestData.Job, + type: "dataset_access" +}; +const jobDatasetOwner = { + ...TestData.Job, + type: "owner_access" +}; +const jobUser51 = { + ...TestData.Job, + type: "user_access" +}; +const jobGroup5 = { + ...TestData.Job, + type: "group_access" +}; + +describe("1100: Jobs: Test New Job Model", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("Job").deleteMany({}); }); + beforeEach((done) => { utils.getToken( appUrl, @@ -40,755 +158,3715 @@ describe.skip("1100: Jobs: Test New Job Model", () => { utils.getToken( appUrl, { - username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], + username: "user1", + password: TestData.Accounts["user1"]["password"], }, (tokenVal) => { - accessTokenArchiveManager = tokenVal; - done(); + accessTokenUser1 = tokenVal; + utils.getToken( + appUrl, + { + username: "user3", + password: TestData.Accounts["user3"]["password"], + }, + (tokenVal) => { + accessTokenUser3 = tokenVal; + utils.getToken( + appUrl, + { + username: "user5.1", + password: TestData.Accounts["user5.1"]["password"], + }, + (tokenVal) => { + accessTokenUser51 = tokenVal; + utils.getToken( + appUrl, + { + username: "user5.2", + password: + TestData.Accounts["user5.2"]["password"], + }, + (tokenVal) => { + accessTokenUser52 = tokenVal; + utils.getToken( + appUrl, + { + username: "admin", + password: TestData.Accounts["admin"]["password"], + }, + (tokenVal) => { + accessTokenAdmin = tokenVal; + utils.getToken( + appUrl, + { + username:"archiveManager", + password: TestData.Accounts["archiveManager"]["password"], + }, + (tokenVal) => { + accessTokenArchiveManager = tokenVal; + done(); + } + ) + }, + ); + }, + ); + }, + ); + }, + ); }, ); }, ); }); - it("0010: adds a new raw dataset", async () => { + after(() => { //because we're not deleting all the jobs and don't delete datasets + db.collection("Dataset").deleteMany({}); + db.collection("Job").deleteMany({}); + }); + + it("0010: adds dataset 1 as Admin Ingestor", async () => { return request(appUrl) .post("/api/v3/Datasets") - .send(TestData.RawCorrect) + .send(dataset1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(true); res.body.should.have.property("pid").and.be.string; - // store link to this dataset in datablocks - var pidtest = res.body["pid"]; - archiveJob.datasetList[0].pid = pidtest; - retrieveJob.datasetList[0].pid = pidtest; - publicJob.datasetList[0].pid = pidtest; - pid1 = encodeURIComponent(res.body["pid"]); + datasetPid1 = res.body["pid"]; }); }); - it("0020: adds another new raw dataset", async () => { + it("0020: adds dataset 2 as Admin Ingestor", async () => { return request(appUrl) .post("/api/v3/Datasets") - .send(TestData.RawCorrect) + .send(dataset2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("owner").and.be.string; + res.body.should.have.property("ownerGroup").and.equal("group2"); res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); res.body.should.have.property("pid").and.be.string; - // store link to this dataset in datablocks - var pidtest = res.body["pid"]; - archiveJob.datasetList[1].pid = pidtest; - retrieveJob.datasetList[1].pid = pidtest; - publicJob.datasetList[1].pid = pidtest; - pid2 = encodeURIComponent(res.body["pid"]); + datasetPid2 = res.body["pid"]; }); }); - it("0030: Adds a new archive job request without authentication, which should fail", async () => { + it("0030: adds dataset 3 as Admin Ingestor", async () => { return request(appUrl) - .post("/api/v3/Jobs") - .send(archiveJob) + .post("/api/v3/Datasets") + .send(dataset3) .set("Accept", "application/json") - .expect(TestData.UnauthorizedStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.should.have.property("error"); + res.body.should.have.property("ownerGroup").and.equal("group5"); + res.body.should.have.property("type").and.equal("raw"); + res.body.should.have.property("isPublished").and.equal(false); + res.body.should.have.property("pid").and.be.string; + datasetPid3 = res.body["pid"]; }); }); + + it("0040: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#all' configuration with no datasets in job parameters, which should fail", async () => { + const newDataset = { + ...jobAll, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobAll.jobParams, + datasetIds: [], + }, + }; - it("0040: Adds a new archive job request", async () => { return request(appUrl) .post("/api/v3/Jobs") - .send(archiveJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("type").and.be.string; - archiveJobId = res.body["id"]; + res.body.should.not.have.property("id") + res.body.should.have.property("message").and.be.equal("List of passed dataset IDs is empty."); }); }); - it("0050: Adds a new archive job request contains empty datasetList, which should fail", async () => { - const empty = { ...TestData.ArchiveJob }; - empty.datasetList = []; + it("0050: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#all' configuration with not existing dataset IDs, which should fail", async () => { + const newDataset = { + ...jobAll, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobAll.jobParams, + datasetIds: ["fakeID", "fakeID2"], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(empty) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.should.have.property("error"); + res.body.should.not.have.property("id") }); }); - it("0060: Adds a new archive job request on non exist dataset which should fail", async () => { - let nonExistDataset = { - ...TestData.ArchiveJob, - datasetList: [ - { - pid: "dummy", - files: [], - }, - ], + it("0060: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetPublic' configuration with no jobParams parameter, which should fail", async () => { + const newDataset = { + type: "all_access", + ownerUser: "admin", + ownerGroup: "admin", }; return request(appUrl) .post("/api/v3/Jobs") - .send(nonExistDataset) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) - .then((res, err) => { - if (err) { - return done(err); - } - res.body.should.have.property("message"); + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Job parameters need to be defined."); }); }); - it("0070: Check if dataset 1 was updated by job request", async () => { + it("0065: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetPublic' configuration with empty jobParams parameter, which should fail", async () => { + const newDataset = { + type: "all_access", + ownerUser: "admin", + ownerGroup: "admin", + }; + return request(appUrl) - .get("/api/v3/Datasets/" + pid1) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.archivable") - .and.equal(false); - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(false); - res.body.should.have.nested - .property("datasetlifecycle.archiveStatusMessage") - .and.equal("scheduledForArchiving"); - res.body.should.have.nested - .property("datasetlifecycle.publishable") - .and.equal(false); - - datasetLiveCycle1 = res.body.datasetlifecycle; + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Job parameters need to be defined."); }); }); - it("0080: Check if dataset 2 was updated by job request", async () => { + + it("0070: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .get("/api/v3/Datasets/" + pid2) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.archivable") - .and.equal(false); - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(false); - res.body.should.have.nested - .property("datasetlifecycle.archiveStatusMessage") - .and.equal("scheduledForArchiving"); - res.body.should.have.nested - .property("datasetlifecycle.publishable") - .and.equal(false); - datasetLiveCycle2 = res.body.datasetlifecycle; + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId1 = res.body["id"]; + encodedJobId1 = encodeURIComponent(jobId1); }); }); - it("0090: Create retrieve job request on same dataset, which should fail as well because not yet retrievable", async () => { + it("0080: Add a new job as a user from ADMIN_GROUPS for another user in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(TestData.RetrieveJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.ConflictStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) - .then((res, err) => { - if (err) { - return done(err); - } - res.body.should.have.property("error"); + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId2 = res.body["id"]; + encodedJobId2 = encodeURIComponent(jobId2); }); }); - it("0100: Send an update status to dataset 1, simulating the archive system response", async () => { + it("0090: Add a new job as a user from ADMIN_GROUPS for undefined user from another group user in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .patch("/api/v3/Datasets/" + pid1) - .send({ - datasetlifecycle: { - ...datasetLiveCycle1, - retrievable: true, - archiveStatusMessage: "datasetOnArchiveDisk", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); - res.body.should.have.nested - .property("datasetlifecycle.publishable") - .and.equal(false); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId3 = res.body["id"]; + encodedJobId3 = encodeURIComponent(jobId3); }); }); - it("0110: Send an update status to dataset 2, simulating the archive system response", async () => { + + it("0100: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .patch("/api/v3/Datasets/" + pid2) - .send({ - datasetlifecycle: { - ...datasetLiveCycle2, - retrievable: true, - archiveStatusMessage: "datasetOnArchiveDisk", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); - res.body.should.have.nested - .property("datasetlifecycle.publishable") - .and.equal(false); + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId6 = res.body["id"]; + encodedJobId6 = encodeURIComponent(jobId6); }); }); - // change policy to suppress emails - it("0120: Disable notification by email", async () => { + it("0110: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .post("/api/v3/Policies/updateWhere") - .send({ - ownerGroupList: TestData.RawCorrect.ownerGroup, - data: { - archiveEmailNotification: false, - retrieveEmailNotification: false, - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .set("Content-Type", "application/x-www-form-urlencoded") - .expect(TestData.SuccessfulPostStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) .then((res) => { - console.log("Result policy update:", res.body); - //res.body.not.equal({}); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0130: Adds a new archive job request for same data which should fail", async () => { + it("0120: Add a new job as a user from CREATE_JOB_GROUPS for his/her group in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(TestData.ArchiveJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.ConflictStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) - .then((res, err) => { - if (err) { - return done(err); - } - res.body.should.have.property("error"); + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0140: Send an update status to the archive job request, signal successful archiving", async () => { - return request(appUrl) - .patch("/api/v3/Jobs/" + archiveJobId) - .send({ - jobStatusMessage: "finishedSuccessful", - jobResultObject: { - status: "okay", - message: "Archive job was finished successfully", - }, - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulPatchStatusCode) - .expect("Content-Type", /json/); - }); + it("0130: Add a new job as a user from CREATE_JOB_GROUPS for another user in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; - it("0150: Adds a new retrieve job request on same dataset, which should succeed now", async () => { return request(appUrl) .post("/api/v3/Jobs") - .send(TestData.RetrieveJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.EntryCreatedStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) - .then((res, err) => { - if (err) { - return done(err); - } - res.body.should.have.property("id"); - retrieveJobId = res.body["id"]; + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User owning the job should match user logged in."); }); }); - it("0160: Read contents of dataset 1 after retrieve job and make sure that still retrievable", async () => { + it("0140: Add a new job as a user from CREATE_JOB_GROUPS for another group in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group5", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .get("/api/v3/Datasets/" + pid1) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulGetStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User needs to belong to job owner group."); }); }); - it("0170: Send an update status to the dataset", async () => { + it("0150: Add a new job as a user from CREATE_JOB_GROUPS for anonymous user in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .patch("/api/v3/Datasets/" + pid1) - .send({ - datasetlifecycle: { - ...datasetLiveCycle1, - retrieveReturnMessage: { - text: "Some dummy retrieve message", - }, - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested.property( - "datasetlifecycle.retrieveReturnMessage", - ); + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. Owner group should be specified."); }); }); - it("0180: Send an update status to the dataset, simulating the archive system response of finished job with partial failure", async () => { + it("0160: Add a new job as a normal user for himself/herself in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid2], + }, + }; + return request(appUrl) - .patch("/api/v3/Datasets/" + pid1) - .send({ - datasetlifecycle: { - ...datasetLiveCycle1, - retrievable: true, - archiveStatusMessage: "datasetOnArchiveDisk", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); - res.body.should.have.nested - .property("datasetlifecycle.publishable") - .and.equal(false); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId4 = res.body["id"]; + encodedJobId4 = encodeURIComponent(jobId4); }); }); - it("0190: Send an update status message to the Job", async () => { + it("0170:Add a new job as a normal user for his/her group in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group5", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .patch("/api/v3/Jobs/" + retrieveJobId) - .send({ - jobStatusMessage: "finishedUnsuccessful", - jobResultObject: { - status: "bad", - message: "System A failed", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("jobResultObject"); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobId5 = res.body["id"]; + encodedJobId5 = encodeURIComponent(jobId5); }); }); - it("0200: Send an update status to the datasets, simulating the archive system response of successful job", async () => { - await request(appUrl) - .patch("/api/v3/Datasets/" + pid1) - .send({ - datasetlifecycle: { - ...datasetLiveCycle1, - retrievable: true, - archiveStatusMessage: "datasetOnArchiveDisk", - }, - }) + it("0180: Add a new job as a normal user for another user in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User owning the job should match user logged in."); }); + }); + + it("0190: Add a new job as a normal user for another group in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; return request(appUrl) - .patch("/api/v3/Datasets/" + pid2) - .send({ - datasetlifecycle: { - ...datasetLiveCycle2, - retrievable: true, - archiveStatusMessage: "datasetOnArchiveDisk", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested - .property("datasetlifecycle.retrievable") - .and.equal(true); + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User needs to belong to job owner group."); }); }); - it("0210: Send an update status message to the Job", async () => { + it("0200: Add a new job as a normal user for anonymous user in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) - .patch("/api/v3/Jobs/" + retrieveJobId) - .send({ - jobStatusMessage: "finishedSuccessful", - jobResultObject: { - status: "okay", - message: "Job archiving worked", - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("jobStatusMessage").and.be.string; - }); - }); - - // NOTE: Missing endpoint!!! /api/v3/Jobs/update?where. Do we need one??? - // it("Bulk update Job status prepare to trigger sending email mechanism", async () => { - // const filter = { - // id: { - // inq: [archiveJobId, retrieveJobId], - // }, - // }; - // return request(appUrl) - // .post("/api/v3/Jobs/update?where=" + JSON.stringify(filter)) - // .send({ - // jobStatusMessage: "test", - // }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(200) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("count").and.equal(2); - // return; - // }); - // }); - - // NOTE: Missing endpoint!!! /api/v3/Jobs/update?where. Do we need one??? - // it("Bulk update Job status, should send out email", async () => { - // var filter = { - // id: { - // inq: [archiveJobId, retrieveJobId], - // }, - // }; - // return request(appUrl) - // .post("/api/v3/Jobs/update?where=" + JSON.stringify(filter)) - // .send({ - // jobStatusMessage: "finishedSuccessful", - // }) - // .set("Accept", "application/json") - // .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - // .expect(200) - // .expect("Content-Type", /json/) - // .then((res) => { - // res.body.should.have.property("count").and.equal(2); - // //setTimeout(done, 3000); - // return; - // }); - // }); - - it("0220: adds a new origDatablock", async () => { - return request(appUrl) - .post(`/api/v3/datasets/${pid1}/OrigDatablocks`) - .send(TestData.OrigDataBlockCorrect1) + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. Owner group should be specified."); + }); + }); + + it("0210: Adds a new job as unauthenticated user in '#all' configuration", async () => { + const newDataset = { + ...jobAll, + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have - .property("size") - .and.equal(TestData.OrigDataBlockCorrect1.size); - res.body.should.have.property("id").and.be.string; - origDatablockId = res.body["id"]; + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerUser"); + res.body.should.not.have.property("ownerGroup"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0230: Adds a new public job request on private datasets, which should fails", async () => { + it("0220: Adds a new job as unauthenticated user for another user in '#all' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobAll, + ownerGroup: "group1", + jobParams: { + ...jobAll.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.ConflictStatusCode) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("error"); + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. Unauthenticated user cannot initiate a job owned by another user."); }); }); + + it("0230: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetPublic' configuration with all published datasets", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1], + }, + }; - it("0240: Set to true for one of the dataset", async () => { return request(appUrl) - .patch("/api/v3/Datasets/" + pid1) - .send({ - isPublished: true, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested.property("isPublished").and.equal(true); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0250: Adds a new public job request on one public and one private dataset, which should fails", async () => { + it("0240: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetPublic' configuration with one unpublished dataset", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.ConflictStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.property("error"); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0260: Update isPublished to true on second dataset", async () => { + it("0250: Add a new job as a user from ADMIN_GROUPS for another user in '#datasetPublic' configuration with one unpublished dataset", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + return request(appUrl) - .patch("/api/v3/Datasets/" + pid2) - .send({ - isPublished: true, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.SuccessfulPatchStatusCode) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - res.body.should.have.nested.property("isPublished").and.equal(true); + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0270: Adds a new public job request without authentication", async () => { + it("0260: Add a new job as a user from ADMIN_GROUPS for another group in '#datasetPublic' configuration with one unpublished dataset", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerGroup: "group1", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("type").and.be.string; - publicJobIds.push(res.body["id"]); + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); - it("0280: Adds a new public job request with authentication", async () => { + it("0270: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#datasetPublic' configuration with one unpublished dataset", async () => { + const newDataset = { + ...jobDatasetPublic, + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("type").and.be.string; - publicJobIds.push(res.body["id"]); - }); - }); - - it("0290: Send an update status to the public job request, signal finished job with partial failure", async () => { - return request(appUrl) - .patch("/api/v3/Jobs/" + publicJobIds[0]) - .send({ - jobStatusMessage: "finishedUnsuccessful", - jobResultObject: { - good: [ - { - pid: decodeURIComponent(pid1), - downloadLink: "Globus link", - }, - ], - bad: [ - { - pid: decodeURIComponent(pid2), - downloadLink: "Globus link", - availableFiles: [ - { - file: "N1039-1.tif", - reason: "ok", - }, - { - file: "N1039-2.tif", - reason: "ok", - }, - ], - unavailableFiles: [ - { - file: "N1039-3.tif", - reason: "no space in destination", - }, - ], - }, - ], - }, - }) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulPatchStatusCode) - .expect("Content-Type", /json/); + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); }); - it("0300: Adds a new public job request to download some selected files", async () => { - publicJob.datasetList[0].files = ["N1039-1.tif", "N1039-2.tif"]; + it("0280: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetPublic' configuration with all published datasets", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1], + }, + }; + return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - //reset - publicJob.datasetList[0].files = []; - res.body.should.have.property("type").and.be.string; - publicJobIds.push(res.body["id"]); + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); + + it("0290: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetPublic' configuration with one unpublished dataset", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; - it("0310: Send an update status to the public job request, signal successful job", async () => { return request(appUrl) - .patch("/api/v3/Jobs/" + publicJobIds[1]) - .send({ - jobStatusMessage: "finishedSuccessful", - jobResultObject: { - good: [ - { - pid: pid1, - downloadLink: "Globus link 1", - }, - { - pid: pid2, - downloadLink: "Globus link 2", - }, - ], - bad: [], - }, - }) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulPatchStatusCode) - .expect("Content-Type", /json/); + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); }); - // NOTE: We don't have put endpoint on the jobs here, only patch. - // Patch without id is returning 404 nor found. Maybe this will be valid one if we need and add put endpoint later? - // it("Add new job using put, which should fails. Ensure that adding new job without authentication using put is not possible ", async () => { - // return request(appUrl) - // .put("/api/v3/Jobs/") - // .send(testPublicJob) - // .set("Accept", "application/json") - // .expect(401) - // .expect("Content-Type", /json/); - // }); + it("0300: Add a new job as a normal user himself/herself in '#datasetPublic' configuration with all published datasets", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1,], + }, + }; - it("0320: Adds a new public job request with to download some selected files that dont exist, which should fail", async () => { - publicJob.datasetList[0].files = ["N1039-1.tif", "N1039-101.tif"]; return request(appUrl) .post("/api/v3/Jobs") - .send(publicJob) + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) - .expect(TestData.BadRequestStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) .expect("Content-Type", /json/) .then((res) => { - //reset - publicJob.datasetList[0].files = []; - - res.should.have.property("error").and.be.string; + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); }); }); + + it("0310: Add a new job as a normal user himself/herself in '#datasetPublic' configuration with one unpublished dataset, which should fail ad forbidden", async () => { + const newDataset = { + ...jobDatasetPublic, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; - it("0330: should delete the archive Job", async () => { return request(appUrl) - .delete("/api/v3/Jobs/" + archiveJobId) + .post("/api/v3/Jobs") + .send(newDataset) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) - .expect("Content-Type", /json/); + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); }); - it("0340: should delete the retrieve Job", async () => { + it("0320: Add a new job as anonymous user in '#datasetPublic' configuration with all published datasets", async () => { + const newDataset = { + ...jobDatasetPublic, + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerUser"); + res.body.should.not.have.property("ownerGroup"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0330: Add a new job as anonymous user in '#datasetPublic' configuration with one unpublished dataset, which should fail as forbidden", async () => { + const newDataset = { + ...jobDatasetPublic, + jobParams: { + ...jobDatasetPublic.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0340: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0350: Add a new job as a user from ADMIN_GROUPS for another user in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + it("0360: Add a new job as a user from ADMIN_GROUPS for another group in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + ownerGroup: "group1", + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0370: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0380: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0390: Add a new job as a normal user for himself/herself in '#authenticated' configuration", async () => { + const newDataset = { + ...jobAuthenticated, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0400: Add a new job as unauthenticated user in '#authenticated' configuration, which should fail as forbidden", async () => { + const newDataset = { + ...jobAuthenticated, + jobParams: { + ...jobAuthenticated.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0410: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetAccess' configuration", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup1 = res.body["id"]; + encodedJobIdGroup1 = encodeURIComponent(jobIdGroup1); + }); + }); + + it("0420: Add a new job as a user from ADMIN_GROUPS for another user in '#datasetAccess' configuration", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup2 = res.body["id"]; + encodedJobIdGroup2 = encodeURIComponent(jobIdGroup2); + }); + }); + + it("0430: Add a new job as a user from ADMIN_GROUPS for another group in '#datasetAccess' configuration", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerGroup: "group1", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup3 = res.body["id"]; + encodedJobIdGroup3 = encodeURIComponent(jobIdGroup3); + }); + }); + + it("0435: Add a new job as a user from ADMIN_GROUPS for another group in '#datasetAccess' configuration", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerGroup: "group5", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup5 = res.body["id"]; + encodedJobIdGroup5 = encodeURIComponent(jobIdGroup5); + }); + }); + + it("0440: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#datasetAccess' configuration", async () => { + const newDataset = { + ...jobDatasetAccess, + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup6 = res.body["id"]; + encodedJobIdGroup6 = encodeURIComponent(jobIdGroup6); + }); + }); + + it("0450: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetAccess' configuration with access to datasets", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0460: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetAccess' configuration with no access to datasets", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0470: Adds a new job as user1 for user5.1 ownerUser and group5 ownerGroup for #datasetAccess, which should fail", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User owning the job should match user logged in."); + }); + }); + + it("0480: Add a new job as a normal user for himself/herself in '#datasetAccess' configuration with access to datasets", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroup4 = res.body["id"]; + encodedJobIdGroup4 = encodeURIComponent(jobIdGroup4); + }); + }); + + it("0490: Add a new job as a normal user for himself/herself in '#datasetAccess' configuration with no access to datasets, which should fail as forbidden", async () => { + const newDataset = { + ...jobDatasetAccess, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetAccess.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0500: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser1 = res.body["id"]; + encodedJobIdUser1 = encodeURIComponent(jobIdUser1); + }); + }); + + it("0510: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0520: Add a new job as a user from ADMIN_GROUPS for another user in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser2 = res.body["id"]; + encodedJobIdUser2 = encodeURIComponent(jobIdUser2); + }); + }); + + it("0530: Add a new job as a user from ADMIN_GROUPS for another group in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerGroup: "group1", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser3 = res.body["id"]; + encodedJobIdUser3 = encodeURIComponent(jobIdUser3); + }); + }); + + it("0535: Add a new job as a user from ADMIN_GROUPS for another group in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerGroup: "group5", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser5 = res.body["id"]; + encodedJobIdUser5 = encodeURIComponent(jobIdUser5); + }); + }); + + it("0540: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#datasetOwner' configuration", async () => { + const newDataset = { + ...jobDatasetOwner, + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid2, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser6 = res.body["id"]; + encodedJobIdUser6 = encodeURIComponent(jobIdUser6); + }); + }); + + it("0550: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetOwner' configuration with datasets owned by his/her group", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0560: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself in '#datasetOwner' configuration with datasets owned by his/her group", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1, datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0570: Add a new job as a normal user for himself/herself in '#datasetOwner' configuration with datasets owned by his/her group", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid3], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUser4 = res.body["id"]; + encodedJobIdUser4 = encodeURIComponent(jobIdUser4); + }); + }); + + it("0580: Add a new job as a normal user for himself/herself in '#datasetOwner' configuration with datasets not owned by his/her group, which should fail as forbidden", async () => { + const newDataset = { + ...jobDatasetOwner, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobDatasetOwner.jobParams, + datasetIds: [datasetPid1], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0590: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec1 = res.body["id"]; + encodedJobIdUserSpec1 = encodeURIComponent(jobIdUserSpec1); + }); + }); + + it("0600: Add a new job as a user from ADMIN_GROUPS for another user in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec2 = res.body["id"]; + encodedJobIdUserSpec2 = encodeURIComponent(jobIdUserSpec2); + }); + }); + + it("0610: Add a new job as a user from ADMIN_GROUPS for another group in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerGroup: "group1", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec3 = res.body["id"]; + encodedJobIdUserSpec3 = encodeURIComponent(jobIdUserSpec3); + }); + }); + + it("0615: Add a new job as a user from ADMIN_GROUPS for another group in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec5 = res.body["id"]; + encodedJobIdUserSpec5 = encodeURIComponent(jobIdUserSpec5); + }); + }); + + it("0616: Add a new job as a user from ADMIN_GROUPS for another user in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user5.2", + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.2"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec7 = res.body["id"]; + encodedJobIdUserSpec7 = encodeURIComponent(jobIdUserSpec7); + }); + }); + + + it("0620: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec6 = res.body["id"]; + encodedJobIdUserSpec6 = encodeURIComponent(jobIdUserSpec6); + }); + }); + + it("0630: Add a new job as a user from CREATE_JOB_GROUPS for himself/herself user in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0640: Add a new job as a user from CREATE_JOB_GROUPS for user5.1 in '#USER5.1' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User owning the job should match user logged in."); + }); + }); + + it("0650: Adds a new job as user5.1 himself/herself in '#USER5.1' configuration", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdUserSpec4 = res.body["id"]; + encodedJobIdUserSpec4 = encodeURIComponent(jobIdUserSpec4); + }); + }); + + it("0660: Adds a new job as user5.1 for no ownerUser and group5 ownerGroup in #USER5.1 configuration", async () => { + const newDataset = { + ...jobUser51, + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0670: Adds a new job as user5.2 for himself/herself in #USER5.1, which should fail as forbidden", async () => { + const newDataset = { + ...jobUser51, + ownerUser: "user5.2", + ownerGroup: "group5", + jobParams: { + ...jobUser51.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0680: Add a new job as a user from ADMIN_GROUPS for himself/herself in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "admin", + ownerGroup: "admin", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("admin"); + res.body.should.have.property("ownerUser").and.be.equal("admin"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec1 = res.body["id"]; + encodedJobIdGroupSpec1 = encodeURIComponent(jobIdGroupSpec1); + }); + }); + + it("0690: Add a new job as a user from ADMIN_GROUPS for another user in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec2 = res.body["id"]; + encodedJobIdGroupSpec2 = encodeURIComponent(jobIdGroupSpec2); + }); + }); + + it("0700: Add a new job as a user from ADMIN_GROUPS for another group in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerGroup: "group1", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec3 = res.body["id"]; + encodedJobIdGroupSpec3 = encodeURIComponent(jobIdGroupSpec3); + }); + }); + + it("0705: Add a new job as a user from ADMIN_GROUPS for another group in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerGroup: "group5", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec5 = res.body["id"]; + encodedJobIdGroupSpec5 = encodeURIComponent(jobIdGroupSpec5); + }); + }); + + it("0706: Add a new job as a user from ADMIN_GROUPS for another user in '@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user3", + ownerGroup: "group3", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group3"); + res.body.should.have.property("ownerUser").and.be.equal("user3"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec8 = res.body["id"]; + encodedJobIdGroupSpec8 = encodeURIComponent(jobIdGroupSpec8); + }); + }); + + it("0710: Add a new job as a user from ADMIN_GROUPS for anonymous user in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.not.have.property("ownerGroup"); + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec6 = res.body["id"]; + encodedJobIdGroupSpec6 = encodeURIComponent(jobIdGroupSpec6); + }); + }); + + it("0720: Add a new job as a user from CREATE_JOB_GROUPS for another group in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user1", + ownerGroup: "group1", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0730: Add a new job as a user from CREATE_JOB_GROUPS for user 5.1 in '#@group5' configuration, which should fail as bad request", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Invalid new job. User owning the job should match user logged in."); + }); + }); + + it("0740: Add a new job as a user 5.1 for himself/herself in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user5.1", + ownerGroup: "group5", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec4 = res.body["id"]; + encodedJobIdGroupSpec4 = encodeURIComponent(jobIdGroupSpec4); + }); + }); + + it("0750: Add a new job as a user 5.1 for another user in his/her group in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerGroup: "group5", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.1"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + }); + }); + + it("0760: Add a new job as a user 5.2 for himself/herself in '#@group5' configuration", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user5.2", + ownerGroup: "group5", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.EntryCreatedStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("type").and.be.string; + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + res.body.should.have.property("ownerUser").and.be.equal("user5.2"); + res.body.should.have.property("statusMessage").to.be.equal("jobCreated"); + jobIdGroupSpec7 = res.body["id"]; + encodedJobIdGroupSpec7 = encodeURIComponent(jobIdGroupSpec7); + }); + }); + + it("0770: Adds a new job as user3 for himself/herself in #@group5 configuration, which should fail as forbidden", async () => { + const newDataset = { + ...jobGroup5, + ownerUser: "user3", + ownerGroup: "group3", + jobParams: { + ...jobGroup5.jobParams, + datasetIds: [datasetPid1, datasetPid2], + }, + }; + + return request(appUrl) + .post("/api/v3/Jobs") + .send(newDataset) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("id"); + res.body.should.have.property("message").and.be.equal("Unauthorized to create this dataset."); + }); + }); + + it("0780: Adds a status update to a job as a user from ADMIN_GROUPS for his/her job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId1}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0790: Adds a Status update to a job as a user from ADMIN_GROUPS for another user's job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0800: Adds a Status update to a job as a user from ADMIN_GROUPS for another group's job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0810: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0820: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her job in '#all' configuration", async () => { + + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0830: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0840: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0850: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0860: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for anonymous user's group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0870: Adds a Status update to a job as a normal user for his/her job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0880: Adds a Status update to a job as a normal user for another user's job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0890: Adds a Status update to a job as a normal user for his/her group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0900: Adds a Status update to a job as a normal user for another user's group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0910: Adds a Status update to a job as a normal user for anonymous user's group in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0920: Adds a Status update to a job as unauthhenticated user for anonymous job in '#all' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0930: Adds a Status update to a job as unauthhenticated user for anouther group's job in '#all' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("0940: Adds a Status update to a job as unauthhenticated user for another user's job in '#all' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobId2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("0950: Adds a status update to a job as a user from ADMIN_GROUPS for his/her job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser1}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0960: Adds a Status update to a job as a user from ADMIN_GROUPS for another group's job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0970: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0980: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("0990: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1000: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's job in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1010: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her group in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1020: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1030: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for anonymous user's group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1040: Adds a Status update to a job as a normal user for his/her job in '#jobOwnerUser' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1050: Adds a Status update to a job as a normal user for another user's job in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1060: Adds a Status update to a job as a normal user for his/her group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1070: Adds a Status update to a job as a normal user for another user's group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1080: Adds a Status update to a job as a normal user for anonymous user's group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1090: Adds a Status update to a job as unauthhenticated user for anonymous user's group in '#jobOwnerUser' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUser6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1100: Adds a status update to a job as a user from ADMIN_GROUPS for his/her job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup1}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1110: Adds a Status update to a job as a user from ADMIN_GROUPS for another group's job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1120: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1130: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + + it("1140: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + it("1150: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's job in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + it("1160: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her group in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + it("1170: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's group in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1180: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for anonymous user's group in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1190: Adds a Status update to a job as a normal user for his/her job in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1200: Adds a Status update to a job as a normal user for another user's job in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1210: Adds a Status update to a job as a normal user for his/her group in '#jobOwnerGroup' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1220: Adds a Status update to a job as a normal user for another user's group in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1230: Adds a Status update to a job as a normal user for anonymous user's group in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1240: Adds a Status update to a job as unauthhenticated user for anonymous user's group in '#jobOwnerGroup' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroup6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1250: Adds a Status update to a job as a user from ADMIN_GROUPS for his/her job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec1}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1260: Adds a Status update to a job as a user from ADMIN_GROUPS for another group's job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1270: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1280: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1290: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1300: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's job in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1310: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her group in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1320: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's group in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1330: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for anonymous user's group in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1340: Adds a Status update to a job as user5.1 for his/her job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1350: Adds a Status update to a job as user5.1 for another user's job in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1360: Adds a Status update to a job as user5.1 for his/her group in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1370: Adds a Status update to a job as user5.1 for another user's group in 'USER5.1' configuration", async () => { return request(appUrl) - .delete("/api/v3/Jobs/" + retrieveJobId) - .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode); + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); }); - publicJobIds.forEach((jobId) => { - it("0350: should delete the public Job" + jobId, async () => { - return request(appUrl) - .delete("/api/v3/Jobs/" + jobId) + it("1380: Adds a Status update to a job as user5.1 for anonymous user's group in 'USER5.1' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1390: Adds a Status update to a job as user5.2 for his/her job in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec7}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1400: Adds a Status update to a job as user5.2 for user's 5.1 in same group job in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1410: Adds a Status update to a job as user5.2 for another user in his/her group job in 'USER5.1' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdUserSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.AccessForbiddenStatusCode) .expect("Content-Type", /json/); - }); }); - it("0360: should delete the originDataBlock", async () => { + it("1420: Adds a status update to a job as a user from ADMIN_GROUPS for his/her job in '@group5' configuration", async () => { return request(appUrl) - .delete(`/api/v3/datasets/${pid1}/OrigDatablocks/` + origDatablockId) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec1}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1430: Adds a Status update to a job as a user from ADMIN_GROUPS for another group's job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode); + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1440: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1450: Adds a Status update to a job as a user from ADMIN_GROUPS for anonymous user's job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1460: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1470: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's job in '@group5' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1480: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for his/her group in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec3}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1490: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for another user's group in '@group5' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1500: Adds a Status update to a job as a user from UPDATE_JOB_GROUPS for anonymous user's group in '@group5' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1510: Adds a Status update to a job as user5.1 for his/her job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1520: Adds a Status update to a job as user5.1 for another user's job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec2}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1530: Adds a Status update to a job as user5.1 for his/her group in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1540: Adds a Status update to a job as user5.1 for another user's group in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1550: Adds a Status update to a job as user5.1 for anonymous user's group in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec6}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1560: Adds a Status update to a job as user5.2 for his/her job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec7}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + + it("1570: Adds a Status update to a job as user5.2 for user's 5.1 in same group job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1580: Adds a Status update to a job as user5.2 for another user in his/her group job in '@group5' configuration", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec5}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/); + }); + + it("1590: Adds a Status update to a job as user3 for his/her job in '@group5' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec8}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1600: Adds a Status update to a job as user3 for user's 5.1 job in '@group5' configuration, which should fail as forbidden", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/${encodedJobIdGroupSpec4}`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1610: Adds a status update to a job as a user from ADMIN_GROUPS for his/her job in '#all' configuration with non-existing jobId, which should fail as bad request", async () => { + return request(appUrl) + .patch(`/api/v3/Jobs/badJobId`) + .send({ + statusCode: "update status of a job", + statusMessage: "job finished/blocked/etc", + }) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.BadRequestStatusCode) + .expect("Content-Type", /json/); + }); + + it("1620: Access jobs as a user from ADMIN_GROUPS ", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(60); + }); + }); + + it("1630: Access jobs as a user from ADMIN_GROUPS that were created by admin", async () => { + const query = { where:{ createdBy: "admin" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(36); + }); + }); + + it("1640: Access jobs as a user from ADMIN_GROUPS that were created by User1", async () => { + const query = { where:{ createdBy: "user1" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(11); + }); + }); + + it("1650: Access jobs as a user from ADMIN_GROUPS that were created by User5.1", async () => { + const query = { where:{ createdBy: "user5.1" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(10); + }); + }); + + it("1660: Access jobs as a user from ADMIN_GROUPS that were created by User5.2", async () => { + const query = { where:{ createdBy: "user5.2" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(1); + }); + }); + + it("1670: Access jobs as a user from ADMIN_GROUPS that were created by anonymous user", async () => { + const query = { where:{ createdBy: "anonymous" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("1680: Access jobs as a user from CREATE_JOB_GROUPS ", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(25); + }); + }); + + it("1690: Access jobs as a user from CREATE_JOB_GROUPS that were created by admin", async () => { + const query = { where:{ createdBy: "admin" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(14); + }); + }); + + it("1700: Access jobs as a user from CREATE_JOB_GROUPS that were created by User1", async () => { + const query = { where:{ createdBy: "user1" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(11); + }); + }); + + it("1710: Access jobs as a normal user", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(10); + }); + }); + + it("1720: Access jobs as a normal user (user5.1) that were created by admin", async () => { + const query = { where:{ createdBy: "admin" }}; + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .query("filter=" + encodeURIComponent(JSON.stringify(query))) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(0); + }); + }); + + it("1730: Access jobs as another normal user (user5.2)", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser52}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(2); + }); + }); + + it("1740: Access jobs as unauthenticated user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1750: Get admin's job as user from ADMIN_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser1}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerUser").and.be.equal("admin"); + }); + }); + + it("1760: Get user1's job as user from ADMIN_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser2}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerUser").and.be.equal("user1"); + }); + }); + + it("1770: Get group1's job as user from ADMIN_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser3}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + }); + }); + + it("1780: Get admin's job as user from ADMIN_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser6}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1790: Get admin's job as user from CREATE_JOB_GROUP, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser1}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1800: Get his/her own job as user from CREATE_JOB_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser2}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerUser").and.be.equal("user1"); + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + }); + }); + + it("1810: Get a job from his/her own group as user from CREATE_JOB_GROUP", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser3}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + res.body.should.have.property("ownerGroup").and.be.equal("group1"); + }); + }); + + it("1820: Get other user's job as user from CREATE_JOB_GROUP, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser4}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1830: Get anonymous user's job as user from CREATE_JOB_GROUP, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser6}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1840: Get admin's job as normal, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser1}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1850: Get other user's job as normal user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser2}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1860: Get his/her own job as normal user", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser4}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.SuccessfulPatchStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.have.property("ownerUser").and.be.equal('user5.1'); + res.body.should.have.property("ownerGroup").and.be.equal("group5"); + }); + }); + + it("1870: Get job od another user in his/her group as normal user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUserSpec7}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1880: Get job from his/her own group as normal user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser5}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1890: Get anonymous user's job as normal user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser6}`) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); + }); + + it("1900: Get anonymous user's job as anonymous user, which should be forbidden", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/${encodedJobIdUser6}`) + .set("Accept", "application/json") + .expect(TestData.AccessForbiddenStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.not.have.property("ownerUser"); + }); }); - it("0370: should delete the dataset #1", async () => { + it("1910: Delete job 1 as Archive Manager", async () => { return request(appUrl) - .delete("/api/v3/Datasets/" + pid1) + .delete("/api/v3/jobs/" + encodedJobIdUser1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.SuccessfulDeleteStatusCode) .expect("Content-Type", /json/); }); - it("0390: should delete the dataset #2", async () => { + it("1920: Delete job 1 as Admin, which should fail", async () => { + return request(appUrl) + .delete("/api/v3/jobs/" + encodedJobIdUser1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.DeleteForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1930: Delete job 1 as CREATE_JOB_GROUPS user, which should fail", async () => { return request(appUrl) - .delete("/api/v3/Datasets/" + pid2) + .delete("/api/v3/jobs/" + encodedJobIdUser1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .expect(TestData.DeleteForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1940: Delete job 1 as normal user, which should fail", async () => { + return request(appUrl) + .delete("/api/v3/jobs/" + encodedJobIdUser1) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenUser51}` }) + .expect(TestData.DeleteForbiddenStatusCode) + .expect("Content-Type", /json/); + }); + + it("1950: Delete job not existing in database as Archive Manager, which should fail", async () => { + return request(appUrl) + .delete("/api/v3/jobs/" + 'fakeJobId') .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) - .expect(TestData.SuccessfulDeleteStatusCode) + .expect(TestData.BadRequestStatusCode) .expect("Content-Type", /json/); }); + + it("1960: Access jobs as a user from ADMIN_GROUPS, which should be one less that before prooving that delete works.", async () => { + return request(appUrl) + .get(`/api/v3/Jobs/`) + .send({}) + .set("Accept", "application/json") + .set({ Authorization: `Bearer ${accessTokenAdmin}` }) + .expect(TestData.SuccessfulGetStatusCode) + .expect("Content-Type", /json/) + .then((res) => { + res.body.should.be.an("array").to.have.lengthOf(59); + }); + }); + }); diff --git a/test/OrigDatablockForRawDataset.js b/test/OrigDatablockForRawDataset.js index e835631fc..e7d226d62 100644 --- a/test/OrigDatablockForRawDataset.js +++ b/test/OrigDatablockForRawDataset.js @@ -19,6 +19,10 @@ var accessTokenAdminIngestor = null, origDatablockWithValidChkAlg = null; describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relation to raw Datasets using origdatablocks endpoint", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("OrigDatablock").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, @@ -147,7 +151,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati it("0050: adds a new origDatablock with wrong account which should fail", async () => { origDatablockData1.datasetId = datasetPid1; return request(appUrl) - .post(`/api/v3/OrigDatablocks`) + .post(`/api/v3/origDatablocks`) .send(origDatablockData1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) @@ -158,7 +162,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati it("0060: adds a new origDatablock with correct account (origdatablock 1)", async () => { origDatablockData1.datasetId = datasetPid1; return request(appUrl) - .post(`/api/v3/OrigDatablocks`) + .post(`/api/v3/origDatablocks`) .send(origDatablockData1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) @@ -176,7 +180,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati it("0070: adds a second origDatablock (origdatablock 2)", async () => { origDatablockData2.datasetId = datasetPid1; return request(appUrl) - .post(`/api/v3/OrigDatablocks`) + .post(`/api/v3/origDatablocks`) .send(origDatablockData2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) @@ -193,7 +197,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati it("0080: add a new origDatablock with empty chkAlg should fail", async () => { return request(appUrl) - .post(`/api/v3/OrigDatablocks`) + .post(`/api/v3/origDatablocks`) .send(origDatablockWithEmptyChkAlg) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) @@ -207,7 +211,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati it("0090: add a new origDatablock with valid chkAlg should success (origdatablock 3)", async () => { origDatablockData3.datasetId = datasetPid2; return request(appUrl) - .post(`/api/v3/OrigDatablocks`) + .post(`/api/v3/origDatablocks`) .send(origDatablockData3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) @@ -229,7 +233,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati const filter = { where: { datasetId: datasetPid1 } }; return request(appUrl) - .get(`/api/v3/OrigDatablocks`) + .get(`/api/v3/origDatablocks`) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .query({ filter: JSON.stringify(filter) }) @@ -246,7 +250,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati const filter = { where: { datasetId: datasetPid2 } }; return request(appUrl) - .get(`/api/v3/OrigDatablocks`) + .get(`/api/v3/origDatablocks`) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .query({ filter: JSON.stringify(filter) }) @@ -727,7 +731,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati const filter = { where: { datasetId: datasetPid1 } }; return request(appUrl) - .get(`/api/v3/OrigDatablocks`) + .get(`/api/v3/origDatablocks`) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .query({ filter: JSON.stringify(filter) }) @@ -742,7 +746,7 @@ describe("1200: OrigDatablockForRawDataset: Test OrigDatablocks and their relati const filter = { where: { datasetId: datasetPid2 } }; return request(appUrl) - .get(`/api/v3/OrigDatablocks`) + .get(`/api/v3/origDatablocks`) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .query({ filter: JSON.stringify(filter) }) diff --git a/test/Policy.js b/test/Policy.js index 5aebadc68..e6b3b9fa4 100644 --- a/test/Policy.js +++ b/test/Policy.js @@ -22,6 +22,9 @@ var testdataset = { }; describe("1300: Policy: Simple Policy tests", () => { + before(() => { + db.collection("Policy").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/Proposal.js b/test/Proposal.js index 65d27a832..411aa220f 100644 --- a/test/Proposal.js +++ b/test/Proposal.js @@ -12,6 +12,9 @@ let accessTokenProposalIngestor = null, attachmentId = null; describe("1500: Proposal: Simple Proposal", () => { + before(() => { + db.collection("Proposal").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/ProposalAuthorization.js b/test/ProposalAuthorization.js index 16637b70f..4e4a9a200 100644 --- a/test/ProposalAuthorization.js +++ b/test/ProposalAuthorization.js @@ -5,7 +5,7 @@ const utils = require("./LoginUtils"); const { TestData } = require("./TestData"); const sandbox = require("sinon").createSandbox(); -let accessTokenProposalIngestor= null, +let accessTokenProposalIngestor = null, accessTokenArchiveManager = null, accessTokenAdminIngestor = null, accessTokenUser1 = null, @@ -40,6 +40,9 @@ const proposal3 = { }; describe("1400: ProposalAuthorization: Test access to proposal", () => { + before(() => { + db.collection("Proposal").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, @@ -48,7 +51,7 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { password: TestData.Accounts["adminIngestor"]["password"], }, (tokenVal) => { - accessTokenAdminIngestor= tokenVal; + accessTokenAdminIngestor = tokenVal; utils.getToken( appUrl, @@ -78,7 +81,8 @@ describe("1400: ProposalAuthorization: Test access to proposal", () => { appUrl, { username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], + password: + TestData.Accounts["archiveManager"]["password"], }, (tokenVal) => { accessTokenArchiveManager = tokenVal; diff --git a/test/PublishedData.js b/test/PublishedData.js index c6a110356..69531a188 100644 --- a/test/PublishedData.js +++ b/test/PublishedData.js @@ -34,6 +34,10 @@ const nonpublictestdataset = { }; describe("1600: PublishedData: Test of access to published data", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("PublishedData").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/RandomizedDatasetPermissions.js b/test/RandomizedDatasetPermissions.js index 6d22c26ad..9a31f8eb2 100644 --- a/test/RandomizedDatasetPermissions.js +++ b/test/RandomizedDatasetPermissions.js @@ -185,6 +185,9 @@ async function removeAllDatasets() { } describe("1700: Randomized Datasets: permission test with bigger amount of data", async () => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, @@ -222,7 +225,8 @@ describe("1700: Randomized Datasets: permission test with bigger amount of data" appUrl, { username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], + password: + TestData.Accounts["archiveManager"]["password"], }, (tokenVal) => { accessTokenArchiveManager = tokenVal; diff --git a/test/RawDataset.js b/test/RawDataset.js index a4f4cff35..89a04f3dd 100644 --- a/test/RawDataset.js +++ b/test/RawDataset.js @@ -14,6 +14,10 @@ var accessTokenArchiveManager = null; var proposalId = null; describe("1900: RawDataset: Raw Datasets", () => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("Proposals").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, diff --git a/test/RawDatasetDatablock.js b/test/RawDatasetDatablock.js index b6081a568..fae50686b 100644 --- a/test/RawDatasetDatablock.js +++ b/test/RawDatasetDatablock.js @@ -11,6 +11,9 @@ describe("1800: RawDatasetDatablock: Test Datablocks and their relation to raw D var datablockId2 = null; beforeEach((done) => { + before(() => { + db.collection("Dataset").deleteMany({}); + }); utils.getToken( appUrl, { diff --git a/test/RawDatasetOrigDatablock.js b/test/RawDatasetOrigDatablock.js index 1f7587f1c..fc46197a1 100644 --- a/test/RawDatasetOrigDatablock.js +++ b/test/RawDatasetOrigDatablock.js @@ -15,6 +15,10 @@ describe("2000: RawDatasetOrigDatablock: Test OrigDatablocks and their relation origDatablockWithValidChkAlg = null; beforeEach((done) => { + before(() => { + db.collection("Dataset").deleteMany({}); + db.collection("OrigDatablock").deleteMany({}); + }); utils.getToken( appUrl, { diff --git a/test/Sample.js b/test/Sample.js index 915871cd5..3baccdb69 100644 --- a/test/Sample.js +++ b/test/Sample.js @@ -13,6 +13,7 @@ let accessTokenAdminIngestor = null, describe("2200: Sample: Simple Sample", () => { before(() => { db.collection("Sample").deleteMany({}); + db.collection("Dataset").deleteMany({}); }); beforeEach((done) => { utils.getToken( diff --git a/test/SampleAuthorization.js b/test/SampleAuthorization.js index 3f02fa75b..a8fcfcb25 100644 --- a/test/SampleAuthorization.js +++ b/test/SampleAuthorization.js @@ -36,6 +36,9 @@ let accessTokenAdminIngestor = null, attachmentId10 = null; describe("2250: Sample Authorization", () => { + before(() => { + db.collection("Sample").deleteMany({}); + }); beforeEach((done) => { utils.getToken( appUrl, @@ -73,7 +76,8 @@ describe("2250: Sample Authorization", () => { appUrl, { username: "archiveManager", - password: TestData.Accounts["archiveManager"]["password"], + password: + TestData.Accounts["archiveManager"]["password"], }, (tokenVal) => { accessTokenArchiveManager = tokenVal; @@ -89,7 +93,8 @@ describe("2250: Sample Authorization", () => { appUrl, { username: "user4", - password: TestData.Accounts["user4"]["password"], + password: + TestData.Accounts["user4"]["password"], }, (tokenVal) => { accessTokenUser4 = tokenVal; @@ -97,7 +102,8 @@ describe("2250: Sample Authorization", () => { appUrl, { username: "user5.1", - password: TestData.Accounts["user5.1"]["password"], + password: + TestData.Accounts["user5.1"]["password"], }, (tokenVal) => { accessTokenUser5 = tokenVal; @@ -126,7 +132,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 1"; sample.ownerGroup = "adminingestor"; - sample.accessGroups=["group5"]; + sample.accessGroups = ["group5"]; return request(appUrl) .post("/api/v3/Samples") @@ -151,7 +157,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 2"; sample.ownerGroup = "sampleingestor"; - sample.accessGroups=["group3"]; + sample.accessGroups = ["group3"]; return request(appUrl) .post("/api/v3/Samples") @@ -176,7 +182,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 3"; sample.ownerGroup = "group1"; - sample.accessGroups=["group3"]; + sample.accessGroups = ["group3"]; return request(appUrl) .post("/api/v3/Samples") @@ -199,9 +205,9 @@ describe("2250: Sample Authorization", () => { let sample = { ...TestData.SampleCorrect, }; - sample.description = "Sample 4" + sample.description = "Sample 4"; sample.ownerGroup = "group2"; - sample.accessGroups=["group4"]; + sample.accessGroups = ["group4"]; return request(appUrl) .post("/api/v3/Samples") @@ -226,8 +232,8 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 10 Public"; sample.ownerGroup = "nogroup"; - sample.accessGroups=[]; - sample.isPublished=true; + sample.accessGroups = []; + sample.isPublished = true; return request(appUrl) .post("/api/v3/Samples") @@ -252,7 +258,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 5"; sample.ownerGroup = "adminingestor"; - sample.accessGroups=["group5","group2"]; + sample.accessGroups = ["group5", "group2"]; return request(appUrl) .post("/api/v3/Samples") @@ -277,7 +283,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 6"; sample.ownerGroup = "sampleingestor"; - sample.accessGroups=["group1","group4"]; + sample.accessGroups = ["group1", "group4"]; return request(appUrl) .post("/api/v3/Samples") @@ -302,7 +308,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 7"; sample.ownerGroup = "group1"; - sample.accessGroups=["group2","group3"]; + sample.accessGroups = ["group2", "group3"]; return request(appUrl) .post("/api/v3/Samples") @@ -327,7 +333,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 8"; sample.ownerGroup = "group2"; - sample.accessGroups=[]; + sample.accessGroups = []; return request(appUrl) .post("/api/v3/Samples") @@ -380,7 +386,7 @@ describe("2250: Sample Authorization", () => { }; sample.description = "Sample 9"; sample.ownerGroup = "group1"; - sample.accessGroups=["group5"]; + sample.accessGroups = ["group5"]; return request(appUrl) .post("/api/v3/Samples") @@ -576,12 +582,12 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); }); - + function defineAttachment(caption) { return { thumbnail: TestData.AttachmentCorrect.thumbnail, - caption: caption || TestData.AttachmentCorrect.caption - } + caption: caption || TestData.AttachmentCorrect.caption, + }; } // sample attachment @@ -600,12 +606,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("adminingestor"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("adminingestor"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -630,12 +632,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("sampleingestor"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("sampleingestor"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -660,12 +658,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group1"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -690,12 +684,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group2"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group2"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -720,12 +710,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("nogroup"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("nogroup"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -750,12 +736,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("adminingestor"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("adminingestor"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -780,12 +762,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("sampleingestor"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("sampleingestor"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -810,12 +788,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group1"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -840,12 +814,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group2"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group2"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -892,12 +862,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group1"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -933,12 +899,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group1"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -963,12 +925,8 @@ describe("2250: Sample Authorization", () => { res.body.should.have .property("thumbnail") .and.equal(attachment.thumbnail); - res.body.should.have - .property("caption") - .and.equal(attachment.caption); - res.body.should.have - .property("ownerGroup") - .and.equal("group1"); + res.body.should.have.property("caption").and.equal(attachment.caption); + res.body.should.have.property("ownerGroup").and.equal("group1"); res.body.should.have.property("accessGroups"); res.body.should.have.property("createdBy"); res.body.should.have.property("updatedBy").and.be.string; @@ -977,7 +935,7 @@ describe("2250: Sample Authorization", () => { attachmentId9 = res.body["id"]; }); }); - + it("0370: adds an attachment as User 2 to sample 1, which should fail", async () => { return request(appUrl) .post("/api/v3/Samples/" + sampleId1 + "/attachments") @@ -1109,7 +1067,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "adminingestor", - } + }, }; return request(appUrl) @@ -1122,7 +1080,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(2); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId1, sampleId5]); }); @@ -1133,7 +1091,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "group1", - } + }, }; return request(appUrl) @@ -1146,7 +1104,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(3); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId3, sampleId7, sampleId9]); }); @@ -1169,7 +1127,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "sampleingestor", - } + }, }; return request(appUrl) @@ -1182,7 +1140,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(2); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId2, sampleId6]); }); @@ -1193,7 +1151,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "group1", - } + }, }; return request(appUrl) @@ -1225,7 +1183,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "group1", - } + }, }; return request(appUrl) @@ -1238,7 +1196,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.a("array").and.to.have.length(3); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId3, sampleId7, sampleId9]); }); @@ -1249,7 +1207,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "group2", - } + }, }; return request(appUrl) @@ -1281,7 +1239,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "group2", - } + }, }; return request(appUrl) @@ -1294,7 +1252,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(2); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId4, sampleId8]); }); @@ -1305,7 +1263,7 @@ describe("2250: Sample Authorization", () => { const filter = { where: { ownerGroup: "nogroup", - } + }, }; return request(appUrl) @@ -1318,7 +1276,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(1); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("sampleId"); e.sampleId.should.be.oneOf([sampleId10]); }); @@ -1369,7 +1327,7 @@ describe("2250: Sample Authorization", () => { .expect("Content-Type", /json/) .then((res) => { res.body.should.be.an("array").and.to.have.length(1); - res.body.forEach( (e) => { + res.body.forEach((e) => { e.should.have.deep.property("isPublished"); e.isPublished.should.be.equal(true); }); @@ -1381,7 +1339,7 @@ describe("2250: Sample Authorization", () => { // it("0640: access sample 1 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1405,7 +1363,7 @@ describe("2250: Sample Authorization", () => { it("0650: access sample 2 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1429,7 +1387,7 @@ describe("2250: Sample Authorization", () => { it("0660: access sample 3 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1453,7 +1411,7 @@ describe("2250: Sample Authorization", () => { it("0660: access sample 4 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1477,7 +1435,7 @@ describe("2250: Sample Authorization", () => { it("0670: access sample 5 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1501,7 +1459,7 @@ describe("2250: Sample Authorization", () => { it("0680: access sample 6 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1525,7 +1483,7 @@ describe("2250: Sample Authorization", () => { it("0690: access sample 7 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1549,7 +1507,7 @@ describe("2250: Sample Authorization", () => { it("0700: access sample 8 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1573,7 +1531,7 @@ describe("2250: Sample Authorization", () => { it("0710: access sample 9 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1597,7 +1555,7 @@ describe("2250: Sample Authorization", () => { it("0720: access public sample 10 as Admin Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1621,7 +1579,7 @@ describe("2250: Sample Authorization", () => { it("0730: access sample 1 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1637,7 +1595,7 @@ describe("2250: Sample Authorization", () => { it("0740: access sample 2 as Sample Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1661,7 +1619,7 @@ describe("2250: Sample Authorization", () => { it("0750: access sample 3 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1677,7 +1635,7 @@ describe("2250: Sample Authorization", () => { it("0760: access sample 4 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1693,7 +1651,7 @@ describe("2250: Sample Authorization", () => { it("0770: access sample 5 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1709,7 +1667,7 @@ describe("2250: Sample Authorization", () => { it("0780: access sample 6 as Sample Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1733,7 +1691,7 @@ describe("2250: Sample Authorization", () => { it("0790: access sample 7 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1749,7 +1707,7 @@ describe("2250: Sample Authorization", () => { it("0800: access sample 8 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1765,7 +1723,7 @@ describe("2250: Sample Authorization", () => { it("0810: access sample 9 as Sample Ingestor, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1781,7 +1739,7 @@ describe("2250: Sample Authorization", () => { it("0820: access public sample 10 as Sample Ingestor", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1805,7 +1763,7 @@ describe("2250: Sample Authorization", () => { it("0830: access sample 1 as User 1, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1821,7 +1779,7 @@ describe("2250: Sample Authorization", () => { it("0840: access sample 2 as User 1, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1837,7 +1795,7 @@ describe("2250: Sample Authorization", () => { it("0850: access sample 3 as User 1", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1861,7 +1819,7 @@ describe("2250: Sample Authorization", () => { it("0860: access sample 4 as User 1, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1877,7 +1835,7 @@ describe("2250: Sample Authorization", () => { it("0870: access sample 5 as User 1, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1893,7 +1851,7 @@ describe("2250: Sample Authorization", () => { it("0880: access sample 6 as User 1", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1917,7 +1875,7 @@ describe("2250: Sample Authorization", () => { it("0890: access sample 7 as User 1", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1941,7 +1899,7 @@ describe("2250: Sample Authorization", () => { it("0900: access sample 8 as User 1, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -1957,7 +1915,7 @@ describe("2250: Sample Authorization", () => { it("0910: access sample 9 as User 1", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -1981,7 +1939,7 @@ describe("2250: Sample Authorization", () => { it("0920: access public sample 10 as User 1", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2005,7 +1963,7 @@ describe("2250: Sample Authorization", () => { it("0930: access sample 1 as User 2, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2021,7 +1979,7 @@ describe("2250: Sample Authorization", () => { it("0940: access sample 2 as User 2, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2037,7 +1995,7 @@ describe("2250: Sample Authorization", () => { it("0950: access sample 3 as User 2, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2053,7 +2011,7 @@ describe("2250: Sample Authorization", () => { it("0960: access sample 4 as User 2", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2077,7 +2035,7 @@ describe("2250: Sample Authorization", () => { it("0970: access sample 5 as User 2", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2101,7 +2059,7 @@ describe("2250: Sample Authorization", () => { it("0980: access sample 6 as User 2, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2117,7 +2075,7 @@ describe("2250: Sample Authorization", () => { it("0990: access sample 7 as User 2", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2141,7 +2099,7 @@ describe("2250: Sample Authorization", () => { it("1000: access sample 8 as User 2", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2165,7 +2123,7 @@ describe("2250: Sample Authorization", () => { it("1010: access sample 9 as User 2, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2181,7 +2139,7 @@ describe("2250: Sample Authorization", () => { it("1020: access public sample 10 as User 2", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2205,7 +2163,7 @@ describe("2250: Sample Authorization", () => { it("1030: access sample 1 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2221,7 +2179,7 @@ describe("2250: Sample Authorization", () => { it("1040: access sample 2 as User 3", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2245,7 +2203,7 @@ describe("2250: Sample Authorization", () => { it("1050: access sample 3 as User 3", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2269,7 +2227,7 @@ describe("2250: Sample Authorization", () => { it("1060: access sample 4 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2285,7 +2243,7 @@ describe("2250: Sample Authorization", () => { it("1070: access sample 5 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2301,7 +2259,7 @@ describe("2250: Sample Authorization", () => { it("1080: access sample 6 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2317,7 +2275,7 @@ describe("2250: Sample Authorization", () => { it("1090: access sample 7 as User 3", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2341,7 +2299,7 @@ describe("2250: Sample Authorization", () => { it("1100: access sample 8 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2357,7 +2315,7 @@ describe("2250: Sample Authorization", () => { it("1110: access sample 9 as User 3, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2373,7 +2331,7 @@ describe("2250: Sample Authorization", () => { it("1120: access public sample 10 as User 3", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2397,7 +2355,7 @@ describe("2250: Sample Authorization", () => { it("1130: access sample 1 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2413,7 +2371,7 @@ describe("2250: Sample Authorization", () => { it("1140: access sample 2 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2429,7 +2387,7 @@ describe("2250: Sample Authorization", () => { it("1150: access sample 3 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2445,7 +2403,7 @@ describe("2250: Sample Authorization", () => { it("1160: access sample 4 as User 4", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2469,7 +2427,7 @@ describe("2250: Sample Authorization", () => { it("1170: access sample 5 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2485,7 +2443,7 @@ describe("2250: Sample Authorization", () => { it("1180: access sample 6 as User 4", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2509,7 +2467,7 @@ describe("2250: Sample Authorization", () => { it("1190: access sample 7 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2525,7 +2483,7 @@ describe("2250: Sample Authorization", () => { it("1200: access sample 8 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2541,7 +2499,7 @@ describe("2250: Sample Authorization", () => { it("1210: access sample 9 as User 4, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2557,7 +2515,7 @@ describe("2250: Sample Authorization", () => { it("1220: access public sample 10 as User 4", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2581,7 +2539,7 @@ describe("2250: Sample Authorization", () => { it("1230: access sample 1 as User 5", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2605,7 +2563,7 @@ describe("2250: Sample Authorization", () => { it("1240: access sample 2 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2621,7 +2579,7 @@ describe("2250: Sample Authorization", () => { it("1250: access sample 3 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2637,7 +2595,7 @@ describe("2250: Sample Authorization", () => { it("1260: access sample 4 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2653,7 +2611,7 @@ describe("2250: Sample Authorization", () => { it("1270: access sample 5 as User 5", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2677,7 +2635,7 @@ describe("2250: Sample Authorization", () => { it("1280: access sample 6 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2693,7 +2651,7 @@ describe("2250: Sample Authorization", () => { it("1290: access sample 7 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2709,7 +2667,7 @@ describe("2250: Sample Authorization", () => { it("1300: access sample 8 as User 5, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2725,7 +2683,7 @@ describe("2250: Sample Authorization", () => { it("1310: access sample 9 as User 5", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2749,7 +2707,7 @@ describe("2250: Sample Authorization", () => { it("1320: access public sample 10 as User 5", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -2773,7 +2731,7 @@ describe("2250: Sample Authorization", () => { it("1330: access sample 1 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2787,7 +2745,7 @@ describe("2250: Sample Authorization", () => { it("1340: access sample 2 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2801,7 +2759,7 @@ describe("2250: Sample Authorization", () => { it("1350: access sample 3 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2815,7 +2773,7 @@ describe("2250: Sample Authorization", () => { it("1360: access sample 4 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2829,7 +2787,7 @@ describe("2250: Sample Authorization", () => { it("1370: access sample 5 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2843,7 +2801,7 @@ describe("2250: Sample Authorization", () => { it("1380: access sample 6 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2857,7 +2815,7 @@ describe("2250: Sample Authorization", () => { it("1390: access sample 7 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2871,7 +2829,7 @@ describe("2250: Sample Authorization", () => { it("1400: access sample 8 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2885,7 +2843,7 @@ describe("2250: Sample Authorization", () => { it("1410: access sample 9 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -2899,7 +2857,7 @@ describe("2250: Sample Authorization", () => { it("1420: access public sample 10 as Unauthenticated User", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .expect(TestData.SuccessfulGetStatusCode) .expect("Content-Type", /json/) @@ -2921,7 +2879,7 @@ describe("2250: Sample Authorization", () => { it("1430: access sample 1 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId1 ) + .get("/api/v3/Samples/" + sampleId1) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2937,7 +2895,7 @@ describe("2250: Sample Authorization", () => { it("1440: access sample 2 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId2 ) + .get("/api/v3/Samples/" + sampleId2) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2953,7 +2911,7 @@ describe("2250: Sample Authorization", () => { it("1450: access sample 3 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId3 ) + .get("/api/v3/Samples/" + sampleId3) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2969,7 +2927,7 @@ describe("2250: Sample Authorization", () => { it("1460: access sample 4 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId4 ) + .get("/api/v3/Samples/" + sampleId4) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -2985,7 +2943,7 @@ describe("2250: Sample Authorization", () => { it("1470: access sample 5 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId5 ) + .get("/api/v3/Samples/" + sampleId5) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3001,7 +2959,7 @@ describe("2250: Sample Authorization", () => { it("1480: access sample 6 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId6 ) + .get("/api/v3/Samples/" + sampleId6) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3016,7 +2974,7 @@ describe("2250: Sample Authorization", () => { it("1490: access sample 7 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId7 ) + .get("/api/v3/Samples/" + sampleId7) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3032,7 +2990,7 @@ describe("2250: Sample Authorization", () => { it("1500: access sample 8 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId8 ) + .get("/api/v3/Samples/" + sampleId8) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3048,7 +3006,7 @@ describe("2250: Sample Authorization", () => { it("1510: access sample 9 as Archive Manager, which should fail", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId9 ) + .get("/api/v3/Samples/" + sampleId9) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3064,7 +3022,7 @@ describe("2250: Sample Authorization", () => { it("1520: access public sample 10 as Archive Manager", async () => { return request(appUrl) - .get("/api/v3/Samples/" + sampleId10 ) + .get("/api/v3/Samples/" + sampleId10) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.SuccessfulGetStatusCode) @@ -3087,21 +3045,23 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2000", - "user" : "Admin Ingestor" - } - } + test: "2000", + user: "Admin Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId1) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3109,43 +3069,47 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2010", - "user" : "Admin Ingestor" - } - } + test: "2010", + user: "Admin Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId2) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); - + it("2020: update sample characteristic for sample 5 as Admin Ingestor", async () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2020", - "user" : "Admin Ingestor" - } - } + test: "2020", + user: "Admin Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId5) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3153,21 +3117,23 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2030", - "user" : "Admin Ingestor" - } - } + test: "2030", + user: "Admin Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId6) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3175,14 +3141,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2040", - "user" : "Sample Ingestor" - } - } + test: "2040", + user: "Sample Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId1) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3192,36 +3158,38 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2050", - "user" : "Sample Ingestor" - } - } + test: "2050", + user: "Sample Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId2) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); - + it("2060: update sample characteristic for sample 5 as Sample Ingestor, which should fail", async () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2060", - "user" : "Sample Ingestor" - } - } + test: "2060", + user: "Sample Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId5) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3231,21 +3199,23 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2070", - "user" : "Sample Ingestor" - } - } + test: "2070", + user: "Sample Ingestor", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId6) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3253,14 +3223,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2080", - "user" : "User 1" - } - } + test: "2080", + user: "User 1", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId2) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3270,36 +3240,38 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2090", - "user" : "User 1" - } - } + test: "2090", + user: "User 1", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId3) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); - + it("2100: update sample characteristic for sample 6 as User 1, which should fail", async () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2100", - "user" : "User 1" - } - } + test: "2100", + user: "User 1", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId6) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3309,21 +3281,23 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2110", - "user" : "User 1" - } - } + test: "2110", + user: "User 1", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId7) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3331,21 +3305,23 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2120", - "user" : "User 1" - } - } + test: "2120", + user: "User 1", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId9) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulPatchStatusCode) .expect("Content-Type", /json/) .then((res) => { res.body.should.have.property("sampleCharacteristics"); - res.body.sampleCharacteristics.should.have.property("test").and.be.equal(characteristics["test"]); + res.body.sampleCharacteristics.should.have + .property("test") + .and.be.equal(characteristics["test"]); }); }); @@ -3353,14 +3329,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2130", - "user" : "User 2" - } - } + test: "2130", + user: "User 2", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId2) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3370,14 +3346,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2140", - "user" : "User 2" - } - } + test: "2140", + user: "User 2", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId4) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3387,14 +3363,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2150", - "user" : "User 2" - } - } + test: "2150", + user: "User 2", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId5) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser2}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3404,14 +3380,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2160", - "user" : "User 3" - } - } + test: "2160", + user: "User 3", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId3) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3421,14 +3397,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2170", - "user" : "User 3" - } - } + test: "2170", + user: "User 3", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId4) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3438,14 +3414,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2180", - "user" : "User 3" - } - } + test: "2180", + user: "User 3", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId10) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3455,14 +3431,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2190", - "user" : "User 4" - } - } + test: "2190", + user: "User 4", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId4) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3472,14 +3448,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2200", - "user" : "User 4" - } - } + test: "2200", + user: "User 4", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId5) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3489,14 +3465,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2210", - "user" : "User 4" - } - } + test: "2210", + user: "User 4", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId10) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3506,14 +3482,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2220", - "user" : "User 5" - } - } + test: "2220", + user: "User 5", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId5) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3523,14 +3499,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2230", - "user" : "User 5" - } - } + test: "2230", + user: "User 5", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId6) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3540,14 +3516,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2240", - "user" : "User 5" - } - } + test: "2240", + user: "User 5", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId10) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3557,14 +3533,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2250", - "user" : "Archive Manager" - } - } + test: "2250", + user: "Archive Manager", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId1) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3574,14 +3550,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2260", - "user" : "Archive Manager" - } - } + test: "2260", + user: "Archive Manager", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId10) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.CreationForbiddenStatusCode); @@ -3591,14 +3567,14 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2270", - "user" : "Unauthenticated User" - } - } + test: "2270", + user: "Unauthenticated User", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId1) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); @@ -3607,19 +3583,18 @@ describe("2250: Sample Authorization", () => { const characteristics = { ...TestData.SampleCorrect["sampleCharacteristics"], ...{ - "test" : "2280", - "user" : "Unauthenticated User" - } - } + test: "2280", + user: "Unauthenticated User", + }, + }; return request(appUrl) .patch("/api/v3/Samples/" + sampleId10) - .send({"sampleCharacteristics" : characteristics}) + .send({ sampleCharacteristics: characteristics }) .set("Accept", "application/json") .expect(TestData.CreationForbiddenStatusCode); }); - // delete sample attachment it("4000: delete attachment 1 from sample 1 as Unauthenticated User, which should fail", async () => { return request(appUrl) @@ -3630,7 +3605,9 @@ describe("2250: Sample Authorization", () => { it("4010: delete attachment 10 from sample 10 as Unauthenticated User, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3653,9 +3630,11 @@ describe("2250: Sample Authorization", () => { it("4040: delete attachment 10 from sample 10 as User 5, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser5}` }) + .set({ Authorization: `Bearer ${accessTokenUser5}` }) .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3677,9 +3656,11 @@ describe("2250: Sample Authorization", () => { it("4070: delete attachment 10 from sample 10 as User 4, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser4}` }) + .set({ Authorization: `Bearer ${accessTokenUser4}` }) .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3701,9 +3682,11 @@ describe("2250: Sample Authorization", () => { it("4100: delete attachment 10 from sample 10 as User 3, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3733,9 +3716,11 @@ describe("2250: Sample Authorization", () => { it("4140: delete attachment 10 from sample 10 as User 2, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser3}` }) + .set({ Authorization: `Bearer ${accessTokenUser3}` }) .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3746,7 +3731,7 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulDeleteStatusCode) .expect("Content-Type", /json/); - }); + }); it("4160: delete attachment 4 from sample 4 as User 1, which should fail", async () => { return request(appUrl) @@ -3771,13 +3756,15 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.SuccessfulDeleteStatusCode) .expect("Content-Type", /json/); - }); + }); it("4190: delete attachment 10 from sample 10 as User 1, which should fail", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") - .set({ Authorization: `Bearer ${accessTokenUser1}` }) + .set({ Authorization: `Bearer ${accessTokenUser1}` }) .expect(TestData.DeleteForbiddenStatusCode); }); @@ -3797,7 +3784,7 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.DeleteForbiddenStatusCode); }); - + it("4220: delete attachment 7 from sample 7 as Sample Ingestor, which should fail", async () => { return request(appUrl) .delete("/api/v3/samples/" + sampleId7 + "/attachments/" + attachmentId7) @@ -3805,7 +3792,7 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.DeleteForbiddenStatusCode); }); - + it("4230: delete attachment 8 from sample 8 as Sample Ingestor, wich should fail", async () => { return request(appUrl) .delete("/api/v3/samples/" + sampleId8 + "/attachments/" + attachmentId8) @@ -3813,7 +3800,7 @@ describe("2250: Sample Authorization", () => { .set({ Authorization: `Bearer ${accessTokenSampleIngestor}` }) .expect(TestData.DeleteForbiddenStatusCode); }); - + it("4240: delete attachment 1 from sample 1 as Admin Ingestor", async () => { return request(appUrl) .delete("/api/v3/samples/" + sampleId1 + "/attachments/" + attachmentId1) @@ -3822,10 +3809,12 @@ describe("2250: Sample Authorization", () => { .expect(TestData.SuccessfulDeleteStatusCode) .expect("Content-Type", /json/); }); - + it("4250: delete attachment 3_2 from sample 3 as Admin Ingestor", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId3 + "/attachments/" + attachmentId3_2) + .delete( + "/api/v3/samples/" + sampleId3 + "/attachments/" + attachmentId3_2, + ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenAdminIngestor}` }) .expect(TestData.SuccessfulDeleteStatusCode) @@ -3852,7 +3841,9 @@ describe("2250: Sample Authorization", () => { it("4280: delete attachment 7_2 from sample 7 as Archive Manager", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId7 + "/attachments/" + attachmentId7_2) + .delete( + "/api/v3/samples/" + sampleId7 + "/attachments/" + attachmentId7_2, + ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.SuccessfulDeleteStatusCode) @@ -3861,7 +3852,9 @@ describe("2250: Sample Authorization", () => { it("4290: delete attachment 10 from sample 10 as Archive Manager", async () => { return request(appUrl) - .delete("/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10) + .delete( + "/api/v3/samples/" + sampleId10 + "/attachments/" + attachmentId10, + ) .set("Accept", "application/json") .set({ Authorization: `Bearer ${accessTokenArchiveManager}` }) .expect(TestData.SuccessfulDeleteStatusCode) diff --git a/test/TestData.js b/test/TestData.js index 5a3a5310b..a22884445 100644 --- a/test/TestData.js +++ b/test/TestData.js @@ -684,23 +684,29 @@ const TestData = { ], }, - ArchiveJob: { - emailJobInitiator: "scicatarchivemanger@psi.ch", - type: "archive", - jobStatusMessage: "jobForwarded", - datasetList: [ - { - pid: "dummy", - files: [], - }, - { - pid: "dummy", - files: [], - }, - ], - jobResultObject: { - status: "okay", - message: "All systems okay", + // ArchiveJob: { + // emailJobInitiator: "scicatarchivemanger@psi.ch", + // type: "archive", + // jobStatusMessage: "jobForwarded", + // datasetList: [ + // { + // pid: "dummy", + // files: [], + // }, + // { + // pid: "dummy", + // files: [], + // }, + // ], + // jobResultObject: { + // status: "okay", + // message: "All systems okay", + // }, + // }, + + Job:{ + type: "", + jobParams: { }, }, diff --git a/test/config/jobconfig.json b/test/config/jobconfig.json index b1df4021c..6f2247141 100644 --- a/test/config/jobconfig.json +++ b/test/config/jobconfig.json @@ -1,53 +1,73 @@ -[ +{ + "configVersion": "v1.0 2024-03-01 6f3f38", + "jobs": [ { - "jobType": "archive", + "jobType": "all_access", "create": { - "actions": { - "actionType": "log" - } - }, - "update": { "auth": "#all", - "actions": { - "actionType": "log" - } - }, - "post": { "actions": [ { - "actionType": "email", - "mailer": { - "host": "smtp.myinstitution.ext", - "port": 465, - "secure": true, - "auth": { - "user": "scicatuser", - "pass": "" - } - }, - "to": "{{ join job.recipients ' '}}", - "from": "scicat@example.com", - "subject": "Archive job {{job.pid}} has completed.", - "body": "Dear {{job.owner}},\n\nArchive job {{job.pid}} has completed. Results: {{job.status}}\n" - }, - { - "actionType": "filter", - "filter": { - "status": "SUCCESSFUL" - }, - "actions": [ - { - "actionType": "url", - "url": "myscicat.myinstitution.ext/datablock/archived", - "verb": "post", - "headers": { - "AuthBearer": "{{secrets.jwt_token}}" - }, - "body": "{ structure to create archive files }" - } - ] + "actionType": "log" } ] + }, + "statusUpdate": { + "auth": "#all" + } + }, + { + "jobType": "public_access", + "create": { + "auth": "#datasetPublic" + }, + "statusUpdate": { + "auth": "#all" + } + }, + { + "jobType": "authenticated_access", + "create": { + "auth": "#authenticated" + }, + "statusUpdate": { + "auth": "#all" + } + }, + { + "jobType": "dataset_access", + "create": { + "auth": "#datasetAccess" + }, + "statusUpdate": { + "auth": "#jobOwnerGroup" + } + }, + { + "jobType": "owner_access", + "create": { + "auth": "#datasetOwner" + }, + "statusUpdate": { + "auth": "#jobOwnerUser" + } + }, + { + "jobType": "user_access", + "create": { + "auth": "user5.1" + }, + "statusUpdate": { + "auth": "user5.1" + } + }, + { + "jobType": "group_access", + "create": { + "auth": "@group5" + }, + "statusUpdate": { + "auth": "@group5" } } -] + ] +} diff --git a/test/config/pretest.js b/test/config/pretest.js index e884f4e73..1ffaa0319 100644 --- a/test/config/pretest.js +++ b/test/config/pretest.js @@ -1,19 +1,18 @@ /* eslint-disable @typescript-eslint/no-var-requires */ //NOTE: Here we load and initialize some global variables that are used throughout the tests +require("dotenv").config(); var chaiHttp = require("chai-http"); const { MongoClient } = require("mongodb"); -const uri = "mongodb://localhost:27017/scicat"; - -const client = new MongoClient(uri); +const client = new MongoClient(process.env.MONGODB_URI); async function loadChai() { const { chai } = import("chai"); chai.use(chaiHttp); await client.connect(); } -loadChai(); +loadChai(); global.appUrl = "http://localhost:3000"; global.request = require("supertest"); -global.db = client.db("scicat"); +global.db = client.db();