• 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

17.72
/src/platform/forum-discussion/discussion.service.ts
1
import { Inject, Injectable, LoggerService } from '@nestjs/common';
5✔
2
import { InjectRepository } from '@nestjs/typeorm';
5✔
3
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
5✔
4
import { FindOneOptions, FindOptionsRelations, Repository } from 'typeorm';
5✔
5
import { EntityNotFoundException } from '@common/exceptions';
5✔
6
import { LogContext, ProfileType } from '@common/enums';
5✔
7
import { Discussion } from './discussion.entity';
5✔
8
import { IDiscussion } from './discussion.interface';
9
import { UpdateDiscussionInput } from './dto/discussion.dto.update';
10
import { DeleteDiscussionInput } from './dto/discussion.dto.delete';
11
import { RoomService } from '../../domain/communication/room/room.service';
5✔
12
import { AuthorizationPolicy } from '@domain/common/authorization-policy/authorization.policy.entity';
5✔
13
import { ProfileService } from '@domain/common/profile/profile.service';
5✔
14
import { IRoom } from '../../domain/communication/room/room.interface';
5✔
15
import { RoomType } from '@common/enums/room.type';
16
import { IProfile } from '@domain/common/profile/profile.interface';
17
import { TagsetReservedName } from '@common/enums/tagset.reserved.name';
18
import { IStorageAggregator } from '@domain/storage/storage-aggregator/storage.aggregator.interface';
5✔
19
import { ForumCreateDiscussionInput } from '@platform/forum/dto/forum.dto.create.discussion';
20
import { AuthorizationPolicyType } from '@common/enums/authorization.policy.type';
21

5✔
22
@Injectable()
23
export class DiscussionService {
24
  constructor(
5✔
25
    @InjectRepository(Discussion)
26
    private discussionRepository: Repository<Discussion>,
27
    private profileService: ProfileService,
×
28
    private roomService: RoomService,
×
29
    @Inject(WINSTON_MODULE_NEST_PROVIDER) private readonly logger: LoggerService
×
30
  ) {}
×
31

32
  async createDiscussion(
33
    discussionData: ForumCreateDiscussionInput,
34
    userID: string,
35
    communicationDisplayName: string,
36
    roomType: RoomType,
37
    storageAggregator: IStorageAggregator
38
  ): Promise<IDiscussion> {
39
    const discussion: IDiscussion = Discussion.create(discussionData);
40
    discussion.profile = await this.profileService.createProfile(
×
41
      discussionData.profile,
×
42
      ProfileType.DISCUSSION,
43
      storageAggregator
44
    );
45

46
    await this.profileService.addOrUpdateTagsetOnProfile(discussion.profile, {
47
      name: TagsetReservedName.DEFAULT,
×
48
      tags: discussionData.tags || [],
49
    });
×
50

51
    discussion.authorization = new AuthorizationPolicy(
NEW
52
      AuthorizationPolicyType.DISCUSSION
×
53
    );
54

55
    discussion.comments = await this.roomService.createRoom(
56
      `${communicationDisplayName}-discussion-${discussion.profile.displayName}`,
×
57
      roomType
58
    );
59

60
    discussion.createdBy = userID;
61

×
62
    return await this.save(discussion);
63
  }
×
64

65
  async removeDiscussion(
66
    deleteData: DeleteDiscussionInput
67
  ): Promise<IDiscussion> {
68
    const discussionID = deleteData.ID;
69
    const discussion = await this.getDiscussionOrFail(discussionID, {
×
70
      relations: { profile: true, comments: true },
×
71
    });
72

73
    if (discussion.profile) {
74
      await this.profileService.deleteProfile(discussion.profile.id);
×
75
    }
×
76

77
    if (discussion.comments) {
78
      await this.roomService.deleteRoom(discussion.comments);
×
79
    }
×
80

81
    const result = await this.discussionRepository.remove(
82
      discussion as Discussion
×
83
    );
84

85
    result.id = discussionID;
86
    return result;
×
87
  }
×
88

89
  async getDiscussionOrFail(
90
    discussionID: string,
91
    options?: FindOneOptions<Discussion>
92
  ): Promise<IDiscussion> {
93
    const discussion = await this.discussionRepository.findOne({
94
      where: { id: discussionID },
×
95
      ...options,
×
96
    });
×
97

98
    if (!discussion)
99
      throw new EntityNotFoundException(
100
        `Not able to locate Discussion with the specified ID: ${discussionID}`,
101
        LogContext.COMMUNICATION
×
102
      );
103
    return discussion;
×
104
  }
105

106
  async deleteDiscussion(discussionID: string): Promise<IDiscussion> {
107
    const discussion = await this.getDiscussionOrFail(discussionID, {
108
      relations: { profile: true },
109
    });
×
110
    if (discussion.profile) {
×
111
      await this.profileService.deleteProfile(discussion.profile.id);
112
    }
113
    const result = await this.discussionRepository.remove(
114
      discussion as Discussion
×
115
    );
116
    result.id = discussionID;
117
    return result;
118
  }
×
119

120
  async updateDiscussion(
121
    discussion: IDiscussion,
×
122
    updateDiscussionData: UpdateDiscussionInput
×
123
  ): Promise<IDiscussion> {
124
    if (updateDiscussionData.profileData) {
×
125
      discussion.profile = await this.profileService.updateProfile(
126
        discussion.profile,
127
        updateDiscussionData.profileData
×
128
      );
×
129
    }
130
    if (updateDiscussionData.category)
131
      discussion.category = updateDiscussionData.category;
132

133
    return await this.save(discussion);
134
  }
135

×
136
  async save(discussion: IDiscussion): Promise<IDiscussion> {
×
137
    return await this.discussionRepository.save(discussion);
138
  }
139

140
  public async getProfile(
141
    discussionInput: IDiscussion,
×
142
    relations?: FindOptionsRelations<IDiscussion>
×
143
  ): Promise<IProfile> {
144
    const discussion = await this.getDiscussionOrFail(discussionInput.id, {
×
145
      relations: { profile: true, ...relations },
146
    });
147
    if (!discussion.profile)
148
      throw new EntityNotFoundException(
×
149
        `Discussion profile not initialised: ${discussionInput.id}`,
150
        LogContext.COLLABORATION
151
      );
152

153
    return discussion.profile;
154
  }
155

×
156
  public async getComments(discussionID: string): Promise<IRoom> {
157
    const discussionWithComments = await this.getDiscussionOrFail(
158
      discussionID,
×
159
      {
×
160
        relations: { comments: true },
161
      }
162
    );
163
    const room = discussionWithComments.comments;
164
    if (!room)
×
165
      throw new EntityNotFoundException(
166
        `Not able to locate comments room on Discussion with the specified ID: ${discussionID}`,
167
        LogContext.COMMUNICATION
168
      );
×
169
    return room;
170
  }
171

172
  async isDiscussionInForum(
173
    discussionID: string,
174
    forumID: string
×
175
  ): Promise<boolean> {
×
176
    const discussion = await this.discussionRepository
×
177
      .createQueryBuilder('discussion')
178
      .where('discussion.id = :discussionID')
179
      .andWhere('discussion.forumId = :forumID')
180
      .setParameters({
×
181
        discussionID: `${discussionID}`,
182
        forumID: `${forumID}`,
183
      })
184
      .getOne();
185
    if (discussion) return true;
186
    return false;
187
  }
×
188
}
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