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

EcrituresNumeriques / stylo / 21433867219

28 Jan 2026 10:06AM UTC coverage: 69.336% (-0.5%) from 69.865%
21433867219

Pull #1870

github

web-flow
Merge 2ecb40001 into 3e2a2d1b3
Pull Request #1870: Redesign de l'écran articles

731 of 1151 branches covered (63.51%)

Branch coverage included in aggregate %.

30 of 107 new or added lines in 4 files covered. (28.04%)

36 existing lines in 2 files now uncovered.

4013 of 5691 relevant lines covered (70.51%)

5.8 hits per line

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

61.74
/graphql/models/workspace.js
1
const mongoose = require('mongoose')
6✔
2
const toHex = require('colornames')
6✔
3
const Schema = mongoose.Schema
6✔
4

6✔
5
const WorkspaceMemberSchema = new Schema({
6✔
6
  user: {
6✔
7
    type: mongoose.Schema.Types.ObjectId,
6✔
8
    ref: 'User',
6✔
9
  },
6✔
10
})
6✔
11

6✔
12
const workspaceSchema = new Schema(
6✔
13
  {
6✔
14
    name: {
6✔
15
      type: String,
6✔
16
      required: true,
6✔
17
    },
6✔
18
    color: {
6✔
19
      type: String,
6✔
20
      required: true,
6✔
21
      get: (color) => toHex(color) || color || '#ccc',
6✔
22
    },
6✔
23
    description: {
6✔
24
      type: String,
6✔
25
    },
6✔
26
    bibliographyStyle: {
6✔
27
      type: String,
6✔
28
    },
6✔
29
    formMetadata: {
6✔
30
      data: String,
6✔
31
      ui: String,
6✔
32
    },
6✔
33
    members: [WorkspaceMemberSchema],
6✔
34
    articles: [
6✔
35
      {
6✔
36
        type: Schema.Types.ObjectId,
6✔
37
        ref: 'Article',
6✔
38
      },
6✔
39
    ],
6✔
40
    creator: {
6✔
41
      type: Schema.Types.ObjectId,
6✔
42
      ref: 'User',
6✔
43
    },
6✔
44
  },
6✔
45
  { timestamps: true }
6✔
46
)
6✔
47

6✔
48
/**
6✔
49
 *
6✔
50
 * @param {import('./user')} user
6✔
51
 * @returns {mongoose.Collection} workspaces
6✔
52
 */
6✔
53
workspaceSchema.statics.findByUser = function findWorkspaceByUser(user) {
6✔
54
  return this.find({ 'members.user': user?._id }).sort([['updatedAt', -1]])
4✔
55
}
4✔
56

6✔
57
/**
6✔
58
 * @returns {mongoose.Collection} workspaces
6✔
59
 */
6✔
60
workspaceSchema.statics.findByArticleId = function findWorkspaceByArticleId(
6✔
NEW
61
  articleId
×
NEW
62
) {
×
NEW
63
  return this.find({ articles: articleId }).sort([['updatedAt', -1]])
×
NEW
64
}
×
65

6✔
66
workspaceSchema.methods.findMembersByArticle =
6✔
67
  async function findMembersByArticle(articleId) {
6✔
68
    const result = await this.aggregate([
×
69
      { $match: { articles: articleId } },
×
70
      // flatten members in order to create a unique set
×
71
      { $unwind: '$members' },
×
72
      { $group: { _id: null, memberIds: { $addToSet: '$members' } } },
×
73
      {
×
74
        $lookup: {
×
75
          from: 'users',
×
76
          localField: 'memberIds',
×
77
          foreignField: '_id',
×
78
          as: 'members',
×
79
        },
×
80
      },
×
81
    ])
×
82
    return result[0].members
×
83
  }
×
84

6✔
85
workspaceSchema.statics.deleteArticle = function deleteArticle(
6✔
NEW
86
  workspaceId,
×
NEW
87
  articleId
×
NEW
88
) {
×
NEW
89
  return this.updateOne(
×
NEW
90
    { _id: workspaceId, articles: articleId },
×
NEW
91
    {
×
NEW
92
      $pull: {
×
NEW
93
        articles: articleId,
×
NEW
94
      },
×
NEW
95
    },
×
NEW
96
    { timestamps: false }
×
NEW
97
  )
×
NEW
98
}
×
99

6✔
100
workspaceSchema.statics.addArticle = function addArticle(
6✔
NEW
101
  workspaceId,
×
NEW
102
  articleId
×
NEW
103
) {
×
NEW
104
  return this.updateOne(
×
NEW
105
    { _id: workspaceId, articles: { $nin: [articleId] } },
×
NEW
106
    {
×
NEW
107
      $push: {
×
NEW
108
        articles: articleId,
×
NEW
109
      },
×
NEW
110
    },
×
NEW
111
    { timestamps: false }
×
NEW
112
  )
×
NEW
113
}
×
114

6✔
115
workspaceSchema.statics.getWorkspaceById = function getWorkspaceById(
6✔
116
  workspaceId,
×
117
  user
×
118
) {
×
119
  if (user?.admin === true) {
×
120
    return this.findById(workspaceId)
×
121
  }
×
122

×
123
  return this.findOne({
×
124
    $and: [{ _id: workspaceId }, { 'members.user': user?._id }],
×
125
  })
×
126
}
×
127

6✔
128
/**
6✔
129
 * Removes an article from all workspaces where it appears.
6✔
130
 *
6✔
131
 * @param articleId article unique identifier
6✔
132
 * @returns {Promise<import('mongodb').UpdateResult<import('./workspace')>>}
6✔
133
 */
6✔
134
workspaceSchema.statics.removeArticle = function removeArticle(articleId) {
6✔
135
  return this.updateMany(
2✔
136
    { articles: articleId },
2✔
137
    {
2✔
138
      $pull: {
2✔
139
        articles: articleId,
2✔
140
      },
2✔
141
    },
2✔
142
    { timestamps: true }
2✔
143
  )
2✔
144
}
2✔
145

6✔
146
module.exports = mongoose.model('Workspace', workspaceSchema)
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc