• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alkem-io / server / #8050

16 Aug 2024 11:21AM UTC coverage: 13.92%. First build
#8050

Pull #4411

travis-ci

Pull Request #4411: Type added to authorization policy entity

80 of 4158 branches covered (1.92%)

Branch coverage included in aggregate %.

61 of 116 new or added lines in 50 files covered. (52.59%)

1945 of 10389 relevant lines covered (18.72%)

3.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

21.43
/src/domain/space/space.defaults/space.defaults.service.ts
1
import { Inject, Injectable, LoggerService } from '@nestjs/common';
17✔
2
import { LogContext } from '@common/enums/logging.context';
3
import { subspaceCommunityRoles } from './definitions/subspace.community.roles';
17✔
4
import { spaceCommunityRoles } from './definitions/space.community.roles';
17✔
5
import { CreateFormInput } from '@domain/common/form/dto/form.dto.create';
17✔
6
import { subspaceCommunityApplicationForm } from './definitions/subspace.community.role.application.form';
17✔
7
import { spaceCommunityApplicationForm } from './definitions/space.community.role.application.form';
17✔
8
import { SpaceLevel } from '@common/enums/space.level';
17✔
9
import { EntityNotInitializedException } from '@common/exceptions/entity.not.initialized.exception';
17✔
10
import { CreateRoleInput } from '@domain/access/role/dto/role.dto.create';
17✔
11
import { CreateCollaborationOnSpaceInput } from '../space/dto/space.dto.create.collaboration';
17✔
12
import { TemplateService } from '@domain/template/template/template.service';
17✔
13
import { InputCreatorService } from '@services/api/input-creator/input.creator.service';
14
import { TemplateDefaultType } from '@common/enums/template.default.type';
17✔
15
import {
16
  RelationshipNotFoundException,
17
  ValidationException,
17✔
18
} from '@common/exceptions';
19
import { ITemplatesManager } from '@domain/template/templates-manager';
20
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
21
import { CalloutsSetService } from '@domain/collaboration/callouts-set/callouts.set.service';
22
import { PlatformTemplatesService } from '@platform/platform-templates/platform.templates.service';
23
import { ITemplate } from '@domain/template/template/template.interface';
17✔
24
import { CreateCollaborationInput } from '@domain/collaboration/collaboration/dto/collaboration.dto.create';
17✔
25
import { TemplatesManagerService } from '@domain/template/templates-manager/templates.manager.service';
17✔
26
import { ITemplateContentSpace } from '@domain/template/template-content-space/template.content.space.interface';
27

28
@Injectable()
17✔
29
export class SpaceDefaultsService {
17✔
30
  constructor(
17✔
31
    private templateService: TemplateService,
17✔
32
    private inputCreatorService: InputCreatorService,
17✔
33
    private calloutsSetService: CalloutsSetService,
17✔
34
    private platformTemplatesService: PlatformTemplatesService,
17✔
35
    private templatesManagerService: TemplatesManagerService,
17✔
36
    @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService
17✔
37
  ) {}
17✔
38

17✔
39
  public async createCollaborationInput(
17✔
40
    collaborationData: CreateCollaborationOnSpaceInput,
17✔
41
    templateSpaceContent: ITemplateContentSpace
17✔
42
  ): Promise<CreateCollaborationOnSpaceInput> {
17✔
43
    const collaborationDataFromTemplate =
17✔
44
      await this.getCreateCollaborationInputFromContentSpace(
17✔
45
        templateSpaceContent
17✔
46
      );
17✔
47
    if (!collaborationDataFromTemplate) {
17✔
48
      throw new RelationshipNotFoundException(
17✔
49
        `Collaboration not found in template with ID: ${templateSpaceContent.id}`,
17✔
50
        LogContext.TEMPLATES
17✔
51
      );
52
    }
17✔
53

17✔
54
    if (!collaborationData.innovationFlowData) {
17✔
55
      if (collaborationDataFromTemplate) {
17✔
56
        collaborationData.innovationFlowData =
17✔
57
          collaborationDataFromTemplate.innovationFlowData;
58
      }
59
      // If still not present, throw an error
17✔
60
      if (!collaborationData.innovationFlowData) {
61
        throw new ValidationException(
×
62
          'No innovation flow data provided',
×
63
          LogContext.SPACES
×
64
        );
×
65
      }
66
    }
×
67

68
    // Enforce innovation flow settings:
×
69
    if (!templateSpaceContent.collaboration?.innovationFlow?.settings) {
70
      throw new RelationshipNotFoundException(
71
        'Innovation flow settings not found in template',
72
        LogContext.TEMPLATES,
×
NEW
73
        { templateSpaceContentId: templateSpaceContent.id }
×
74
      );
75
    }
76
    const { maximumNumberOfStates, minimumNumberOfStates } =
77
      templateSpaceContent.collaboration.innovationFlow.settings;
×
78
    if (
79
      maximumNumberOfStates < minimumNumberOfStates ||
80
      maximumNumberOfStates < 1 ||
81
      minimumNumberOfStates < 1
82
    ) {
83
      throw new ValidationException(
84
        `Invalid min (${minimumNumberOfStates})/max (${maximumNumberOfStates}) number of states.`,
×
85
        LogContext.SPACES,
86
        { templateSpaceContentId: templateSpaceContent.id }
×
87
      );
88
    }
89

90
    collaborationData.innovationFlowData.settings.maximumNumberOfStates =
×
91
      maximumNumberOfStates;
92
    collaborationData.innovationFlowData.settings.minimumNumberOfStates =
93
      minimumNumberOfStates;
94

95
    if (
96
      collaborationData.innovationFlowData.states.length > maximumNumberOfStates
×
97
    ) {
×
98
      collaborationData.innovationFlowData.states =
99
        collaborationData.innovationFlowData.states.slice(
100
          0,
101
          maximumNumberOfStates
102
        );
×
103
    }
104
    if (
105
      collaborationData.innovationFlowData.states.length < minimumNumberOfStates
×
106
    ) {
×
107
      throw new ValidationException(
108
        `Innovation flow must have at least ${collaborationData.innovationFlowData.settings.minimumNumberOfStates} states.`,
109
        LogContext.SPACES
110
      );
×
111
    }
112

113
    if (collaborationData.addCallouts) {
114
      if (!collaborationData.calloutsSetData.calloutsData) {
115
        collaborationData.calloutsSetData.calloutsData =
116
          collaborationDataFromTemplate?.calloutsSetData.calloutsData;
117
      } else if (collaborationDataFromTemplate.calloutsSetData.calloutsData) {
×
118
        // The request includes the calloutsData, so merge template callouts with request callouts
×
119
        collaborationData.calloutsSetData.calloutsData.push(
×
120
          ...collaborationDataFromTemplate.calloutsSetData.calloutsData
121
        );
122
      }
123
    } else {
124
      collaborationData.calloutsSetData.calloutsData = [];
125
    }
×
126

×
127
    // Move callouts that are not in valid flowStates to the default first flowState
128
    const validFlowStateNames =
129
      collaborationData.innovationFlowData?.states?.map(
130
        state => state.displayName
×
131
      );
132

133
    this.calloutsSetService.moveCalloutsToDefaultFlowState(
134
      validFlowStateNames ?? [],
135
      collaborationData.calloutsSetData.calloutsData ?? []
136
    );
×
137

×
138
    return collaborationData;
×
139
  }
140

141
  public async getTemplateSpaceContentToAugmentFrom(
142
    spaceLevel: SpaceLevel,
143
    spaceTemplateID?: string,
144
    spaceL0TemplatesManager?: ITemplatesManager
×
145
  ): Promise<string> {
146
    // First get the template to augment the provided data with
147
    let templateWithSpaceContent: ITemplate | undefined = undefined;
×
148

×
149
    if (spaceTemplateID) {
150
      templateWithSpaceContent =
151
        await this.templateService.getTemplateOrFail(spaceTemplateID);
152
    } else {
×
153
      switch (spaceLevel) {
154
        case SpaceLevel.L0:
155
          templateWithSpaceContent =
156
            await this.platformTemplatesService.getPlatformDefaultTemplateByType(
×
157
              TemplateDefaultType.PLATFORM_SPACE
158
            );
×
159
          break;
160
        case SpaceLevel.L1:
×
161
        case SpaceLevel.L2: {
162
          // First try to get the template from the library of the L0 space
×
163
          if (spaceL0TemplatesManager) {
164
            try {
×
165
              templateWithSpaceContent =
166
                await this.templatesManagerService.getTemplateFromTemplateDefault(
×
167
                  spaceL0TemplatesManager.id,
168
                  TemplateDefaultType.SPACE_SUBSPACE
×
169
                );
170
            } catch (e) {
171
              // Space does not have a subspace default template, just use the platform default
172
              this.logger.warn(
173
                `Space does not have a subspace default template, using platform default parentSpaceTemplatesManager.id: ${spaceL0TemplatesManager?.id}, ${e}`,
174
                undefined,
175
                LogContext.TEMPLATES
176
              );
×
177
            }
178
          }
179
          if (!templateWithSpaceContent) {
180
            templateWithSpaceContent =
181
              await this.platformTemplatesService.getPlatformDefaultTemplateByType(
×
182
                TemplateDefaultType.PLATFORM_SUBSPACE
183
              );
×
184
          }
185
          break;
×
186
        }
187
      }
188
    }
189

190
    if (!templateWithSpaceContent) {
191
      throw new ValidationException(
192
        `Unable to get template content space to use: ${spaceLevel}, templateID: ${spaceTemplateID}`,
193
        LogContext.TEMPLATES
194
      );
195
    }
×
196
    // Reload to ensure we have the content space
197
    templateWithSpaceContent = await this.templateService.getTemplateOrFail(
198
      templateWithSpaceContent.id,
×
199
      {
200
        relations: {
×
201
          contentSpace: true,
202
        },
×
203
      }
204
    );
205
    if (!templateWithSpaceContent.contentSpace) {
206
      throw new ValidationException(
207
        `Have template without template content space to use: ${spaceLevel}, templateID: ${spaceTemplateID}`,
208
        LogContext.TEMPLATES
209
      );
210
    }
×
211

212
    return templateWithSpaceContent.contentSpace.id;
×
213
  }
214

×
215
  public async addTutorialCalloutsFromTemplate(
216
    collaborationData: CreateCollaborationInput
×
217
  ): Promise<CreateCollaborationInput> {
218
    const tutorialsSpaceContentTemplate =
219
      await this.platformTemplatesService.getPlatformDefaultTemplateByType(
220
        TemplateDefaultType.PLATFORM_SPACE_TUTORIALS
221
      );
×
222
    const contentSpaceFromTemplate =
223
      await this.templateService.getTemplateContentSpace(
224
        tutorialsSpaceContentTemplate.id
×
225
      );
226
    const tutorialsInputFromTemplate =
×
227
      await this.getCreateCollaborationInputFromContentSpace(
228
        contentSpaceFromTemplate
229
      );
230

231
    if (tutorialsInputFromTemplate?.calloutsSetData.calloutsData) {
×
232
      collaborationData.calloutsSetData.calloutsData?.push(
233
        ...tutorialsInputFromTemplate.calloutsSetData.calloutsData
×
234
      );
235
    }
×
236

237
    // Move callouts that are not in valid flowStates to the default first flowState
×
238
    const validFlowStateNames =
239
      collaborationData.innovationFlowData?.states?.map(
×
240
        state => state.displayName
241
      );
×
242

243
    this.calloutsSetService.moveCalloutsToDefaultFlowState(
×
244
      validFlowStateNames ?? [],
245
      collaborationData.calloutsSetData.calloutsData ?? []
246
    );
247

248
    return collaborationData;
249
  }
250

251
  private async getCreateCollaborationInputFromContentSpace(
252
    contentSpaceFromTemplate: ITemplateContentSpace
253
  ): Promise<CreateCollaborationInput | undefined> {
×
254
    if (!contentSpaceFromTemplate?.collaboration) {
255
      throw new RelationshipNotFoundException(
256
        `Collaboration not found in SpaceContent with ID: ${contentSpaceFromTemplate.id}`,
257
        LogContext.TEMPLATES
×
258
      );
259
    }
×
260
    const collaborationInput =
261
      await this.inputCreatorService.buildCreateCollaborationInputFromCollaboration(
×
262
        contentSpaceFromTemplate.collaboration.id
263
      );
×
264
    return collaborationInput;
265
  }
×
266

267
  public getRoleSetCommunityRoles(spaceLevel: SpaceLevel): CreateRoleInput[] {
×
268
    switch (spaceLevel) {
269
      case SpaceLevel.L1:
×
270
      case SpaceLevel.L2:
271
        return subspaceCommunityRoles;
272
      case SpaceLevel.L0:
273
        return spaceCommunityRoles;
274
      default:
275
        throw new EntityNotInitializedException(
276
          `Invalid space level: ${spaceLevel}`,
277
          LogContext.ROLES
278
        );
279
    }
×
280
  }
281

×
282
  public getRoleSetCommunityApplicationForm(
283
    spaceLevel: SpaceLevel
×
284
  ): CreateFormInput {
285
    switch (spaceLevel) {
×
286
      case SpaceLevel.L1:
287
      case SpaceLevel.L2:
×
288
        return subspaceCommunityApplicationForm;
289
      case SpaceLevel.L0:
×
290
        return spaceCommunityApplicationForm;
291
    }
×
292
  }
293
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc