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

EcrituresNumeriques / stylo / 13302570211

13 Feb 2025 07:27AM UTC coverage: 70.091% (-0.1%) from 70.202%
13302570211

push

github

web-flow
Merge pull request #1265 from EcrituresNumeriques/fix/1264

Supprime le champ `user.admin`

211 of 260 branches covered (81.15%)

Branch coverage included in aggregate %.

50 of 81 new or added lines in 5 files covered. (61.73%)

2 existing lines in 2 files now uncovered.

2484 of 3585 relevant lines covered (69.29%)

2.1 hits per line

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

65.64
/graphql/resolvers/workspaceResolver.js
1
const { ObjectId } = require('mongoose').Types
1✔
2
const { ApiError } = require('../helpers/errors')
1✔
3
const Workspace = require('../models/workspace')
1✔
4
const Article = require('../models/article')
1✔
5
const Corpus = require('../models/corpus')
1✔
6

1✔
NEW
7
async function workspace(_, { workspaceId }, { user, token }) {
×
NEW
8
  if (token?.admin) {
×
9
    const workspace = await Workspace.findById(workspaceId)
×
10
    if (!workspace) {
×
NEW
11
      throw new ApiError(
×
NEW
12
        'NOT_FOUND',
×
NEW
13
        `Unable to find workspace with id ${workspaceId}`
×
NEW
14
      )
×
15
    }
×
16
    return workspace
×
17
  }
×
18
  const workspace = await Workspace.findOne({
×
NEW
19
    $and: [{ _id: workspaceId }, { 'members.user': user?._id }],
×
20
  })
×
21
  if (!workspace) {
×
NEW
22
    throw new ApiError(
×
NEW
23
      'NOT_FOUND',
×
NEW
24
      `Unable to find workspace with id ${workspaceId} for user with id ${user?._id}`
×
NEW
25
    )
×
26
  }
×
27
  return workspace
×
28
}
×
29

1✔
30
class WorkspaceArticle {
1✔
31
  constructor(workspace, article) {
1✔
32
    this.workspace = workspace
1✔
33
    this.article = article
1✔
34
  }
1✔
35

1✔
36
  async remove() {
1✔
37
    if (this.article) {
1✔
38
      this.workspace.articles.pull({ _id: this.article._id })
1✔
39
      return this.workspace.save()
1✔
40
    }
1!
41
    return this.workspace
×
42
  }
×
43
}
1✔
44

1✔
45
class WorkspaceMember {
1✔
46
  constructor(workspace, member) {
1✔
47
    this.workspace = workspace
1✔
48
    this.member = member
1✔
49
  }
1✔
50

1✔
51
  async remove() {
1✔
52
    if (this.member) {
1✔
53
      this.workspace.members.pull({ _id: this.member._id })
1✔
54
      return this.workspace.save()
1✔
55
    }
1!
56
    return this.workspace
×
57
  }
×
58
}
1✔
59

1✔
60
module.exports = {
1✔
61
  Mutation: {
1✔
62
    async createWorkspace(_, args, { user }) {
1✔
63
      const { createWorkspaceInput } = args
1✔
64
      if (!user) {
1!
NEW
65
        throw new ApiError(
×
NEW
66
          'UNAUTHENTICATED',
×
NEW
67
          'Unable to create a workspace as an unauthenticated user'
×
NEW
68
        )
×
UNCOV
69
      }
×
70
      // any user can create a workspace
1✔
71
      const newWorkspace = new Workspace({
1✔
72
        name: createWorkspaceInput.name,
1✔
73
        color: createWorkspaceInput.color,
1✔
74
        description: createWorkspaceInput.description,
1✔
75
        members: [{ user: user._id }],
1✔
76
        articles: [],
1✔
77
        creator: user._id,
1✔
78
      })
1✔
79
      return newWorkspace.save()
1✔
80
    },
1✔
81

1✔
82
    /**
1✔
83
     *
1✔
84
     */
1✔
85
    workspace,
1✔
86
  },
1✔
87

1✔
88
  Query: {
1✔
89
    /**
1✔
90
     *
1✔
91
     */
1✔
92
    workspace,
1✔
93

1✔
94
    /**
1✔
95
     *
1✔
96
     */
1✔
97
    async workspaces(_root, _args, { user }) {
1✔
98
      if (user?.admin) {
4!
99
        return Workspace.find()
×
100
      }
×
101
      return Workspace.find({ 'members.user': user?._id }).sort([
4✔
102
        ['updatedAt', -1],
4✔
103
      ])
4✔
104
    },
4✔
105
  },
1✔
106

1✔
107
  WorkspaceArticle: {
1✔
108
    async article(workspaceArticle, { articleId }) {
1✔
NEW
109
      const article = workspace.articles.find(
×
NEW
110
        (a) => String(a._id) === articleId
×
NEW
111
      )
×
112
      return new WorkspaceArticle(workspace, article)
×
113
    },
×
114
  },
1✔
115

1✔
116
  Workspace: {
1✔
117
    async article(workspace, { articleId }) {
1✔
118
      const article = workspace.articles.find(
1✔
119
        (a) => String(a._id) === articleId
1✔
120
      )
1✔
121
      return new WorkspaceArticle(workspace, article)
1✔
122
    },
1✔
123

1✔
124
    /**
1✔
125
     *
1✔
126
     * @param workspace
1✔
127
     * @param _args
1✔
128
     * @param {{ loaders: { articles } }} context
1✔
129
     * @returns {Promise<*>}
1✔
130
     */
1✔
131
    async articles(workspace, _args, context) {
1✔
132
      return Article.getArticles({
×
133
        filter: { _id: { $in: workspace.articles } },
×
134
        loaders: context.loaders,
×
135
      })
×
136
    },
1✔
137

1✔
138
    async corpus(workspace) {
1✔
NEW
139
      return Corpus.find({ workspace: workspace._id })
×
140
        .populate([{ path: 'creator' }])
×
141
        .sort([['updatedAt', -1]])
×
142
    },
1✔
143

1✔
144
    async member(workspace, { userId }) {
1✔
145
      const member = workspace.members.find((m) => String(m.user) === userId)
1✔
146
      return new WorkspaceMember(workspace, member)
1✔
147
    },
1✔
148

1✔
149
    async members(workspace, { limit }) {
1✔
150
      await workspace
1✔
151
        .populate({ path: 'members', populate: 'user', limit })
1✔
152
        .execPopulate()
1✔
153
      return workspace.members.map((m) => m.user)
1✔
154
    },
1✔
155

1✔
156
    async stats(workspace) {
1✔
157
      return {
×
158
        articlesCount: workspace.articles.length,
×
159
        membersCount: workspace.members.length,
×
160
      }
×
161
    },
1✔
162

1✔
163
    async creator(workspace, _args, context) {
1✔
164
      return await context.loaders.users.load(workspace.creator)
×
165
    },
1✔
166

1✔
167
    // mutations
1✔
168

1✔
169
    async leave(workspace, args, { user }) {
1✔
170
      if (!user) {
×
NEW
171
        throw new ApiError(
×
NEW
172
          'UNAUTHENTICATED',
×
NEW
173
          'Unable to leave a workspace as an unauthenticated user'
×
NEW
174
        )
×
175
      }
×
176

×
177
      // TODO: remove workspace if there's no member left!
×
178
      return Workspace.findOneAndUpdate(
×
NEW
179
        { _id: ObjectId(workspace._id) },
×
180
        { $pull: { members: { user: ObjectId(user.id) } } },
×
181
        { lean: true }
×
182
      )
×
183
    },
1✔
184

1✔
185
    async addArticle(workspace, { articleId }) {
1✔
NEW
186
      const articleAlreadyAdded = workspace.articles.find(
×
NEW
187
        (id) => String(id) === articleId
×
NEW
188
      )
×
189
      if (articleAlreadyAdded) {
×
190
        return workspace
×
191
      }
×
192
      workspace.articles.push({ _id: articleId })
×
193
      return workspace.save()
×
194
    },
1✔
195

1✔
196
    async inviteMember(workspace, { userId, role }) {
1✔
197
      // question: should we check that the authenticated user "knows" the member?
1✔
198
      const memberAlreadyInvited = workspace.members.find(
1✔
199
        (id) => String(id) === userId
1✔
200
      )
1✔
201
      if (memberAlreadyInvited) {
1!
202
        return workspace
×
203
      }
×
204
      workspace.members.push({ user: userId, role })
1✔
205
      return workspace.save()
1✔
206
    },
1✔
207
  },
1✔
208
}
1✔
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