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

GEWIS / sudosos-backend / 27943291760

22 Jun 2026 09:33AM UTC coverage: 92.043%. First build
27943291760

Pull #963

github

web-flow
Merge f70131f8d into f15e028bd
Pull Request #963: feat: ToS version acceptance tracking

4235 of 4838 branches covered (87.54%)

Branch coverage included in aggregate %.

164 of 176 new or added lines in 20 files covered. (93.18%)

21837 of 23488 relevant lines covered (92.97%)

841.92 hits per line

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

82.28
/src/controller/request/validators/general-validators.ts
1
/**
1✔
2
 *  SudoSOS back-end API service.
3
 *  Copyright (C) 2026 Study association GEWIS
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU Affero General Public License as published
7
 *  by the Free Software Foundation, either version 3 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU Affero General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU Affero General Public License
16
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
 *
18
 *  @license
19
 */
1✔
20

21
/**
1✔
22
 * This is the module page of the general-validators.
23
 *
24
 * @module internal/spec
25
 */
1✔
26

27
import { toFail, toPass, ValidationError } from '../../../helpers/specification-validation';
28
import User, { TermsOfServiceStatus, UserType } from '../../../entity/user/user';
29
import {
30
  EMPTY_ARRAY,
31
  INVALID_ACTIVE_USER_ID, INVALID_CUSTOM_ROLE_ID,
32
  INVALID_ORGAN_ID,
33
  INVALID_ROLE_ID,
34
  INVALID_USER_ID, TOS_NOT_ACCEPTED,
35
} from './validation-errors';
36
import { In } from 'typeorm';
37
import Role from '../../../entity/rbac/role';
38
import TermsOfServiceService from '../../../service/terms-of-service-service';
39

40
export const positiveNumber = async (p: number) => {
1✔
41
  if (p <= 0) return toFail(new ValidationError('Number must be positive'));
×
42
  return toPass(p);
×
43
};
×
44

45
export const userMustExist = async (p: number) => {
1✔
46
  const user = await User.findOne({ where: { id: p } });
12✔
47
  if (user == null) {
12✔
48
    return toFail(INVALID_USER_ID());
2✔
49
  }
2✔
50
  const status = await TermsOfServiceService.getUserTosStatus(user);
10✔
51
  if (status === TermsOfServiceStatus.NOT_ACCEPTED) {
12!
NEW
52
    return toFail(TOS_NOT_ACCEPTED());
×
NEW
53
  }
✔
54
  return toPass(p);
10✔
55
};
10✔
56

57
export const activeUserMustExist = async (p: number) => {
1✔
58
  if (await User.findOne({ where: { id: p, active: true } }) == null) {
×
59
    return toFail(INVALID_ACTIVE_USER_ID());
×
60
  }
×
61
  return toPass(p);
×
62
};
×
63

64
export const ownerIsOrgan = async (id: number) => {
1✔
65
  const owner = await User.findOne({ where: { id, deleted: false, type: UserType.ORGAN } });
6✔
66
  if (!owner) return toFail(INVALID_ORGAN_ID());
6✔
67
  return toPass(id);
3✔
68
};
3✔
69

70
export const nonEmptyArray = async <T>(list: T[]) => {
1✔
71
  if (list.length === 0) {
17!
72
    return toFail(EMPTY_ARRAY());
×
73
  }
×
74
  return toPass(list);
17✔
75
};
17✔
76

77
export const rolesMustExist = async (ids: number[] | undefined) => {
1✔
78
  if (ids == undefined) return toPass(ids);
12✔
79
  const roles = await Role.find({ where: { id: In(ids) } });
7✔
80
  const foundIds = roles.map((role) => role.id);
7✔
81
  for (let id of ids) {
7✔
82
    if (!foundIds.includes(id)) {
7✔
83
      return toFail(INVALID_ROLE_ID(id));
2✔
84
    }
2✔
85
  }
7✔
86
  return toPass(ids);
5✔
87
};
5✔
88

89
export const rolesCannotBeSystemDefault = async (ids: number[]) => {
1✔
90
  if (ids == undefined) return toPass(ids);
10✔
91
  const roles = await Role.find({ where: { id: In(ids) } });
5✔
92
  const systemDefaultRoles = roles.filter((r) => r.systemDefault);
5✔
93
  if (systemDefaultRoles.length > 0) {
9✔
94
    return toFail(INVALID_CUSTOM_ROLE_ID(systemDefaultRoles[0].id));
2✔
95
  }
2✔
96
  return toPass(ids);
3✔
97
};
3✔
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

© 2026 Coveralls, Inc