]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/video-comment.ts
Begin unit tests
[github/Chocobozzz/PeerTube.git] / server / models / video / video-comment.ts
CommitLineData
6d852470
C
1import * as Sequelize from 'sequelize'
2import {
bf1f6508 3 AfterDestroy, AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, IFindOptions, Is, Model, Scopes, Table,
6d852470
C
4 UpdatedAt
5} from 'sequelize-typescript'
bf1f6508 6import { VideoComment } from '../../../shared/models/videos/video-comment.model'
6d852470
C
7import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub'
8import { CONSTRAINTS_FIELDS } from '../../initializers'
d3ea8975 9import { AccountModel } from '../account/account'
bf1f6508 10import { getSort, throwIfNotValid } from '../utils'
6d852470
C
11import { VideoModel } from './video'
12
bf1f6508 13enum ScopeNames {
d3ea8975 14 WITH_ACCOUNT = 'WITH_ACCOUNT'
bf1f6508
C
15}
16
17@Scopes({
d3ea8975 18 [ScopeNames.WITH_ACCOUNT]: {
bf1f6508 19 include: [
d3ea8975 20 () => AccountModel
bf1f6508
C
21 ]
22 }
23})
6d852470
C
24@Table({
25 tableName: 'videoComment',
26 indexes: [
27 {
28 fields: [ 'videoId' ]
bf1f6508
C
29 },
30 {
31 fields: [ 'videoId', 'originCommentId' ]
6d852470
C
32 }
33 ]
34})
35export class VideoCommentModel extends Model<VideoCommentModel> {
36 @CreatedAt
37 createdAt: Date
38
39 @UpdatedAt
40 updatedAt: Date
41
42 @AllowNull(false)
43 @Is('VideoCommentUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
44 @Column(DataType.STRING(CONSTRAINTS_FIELDS.VIDEOS.URL.max))
45 url: string
46
47 @AllowNull(false)
48 @Column(DataType.TEXT)
49 text: string
50
51 @ForeignKey(() => VideoCommentModel)
52 @Column
53 originCommentId: number
54
55 @BelongsTo(() => VideoCommentModel, {
56 foreignKey: {
57 allowNull: true
58 },
59 onDelete: 'CASCADE'
60 })
61 OriginVideoComment: VideoCommentModel
62
63 @ForeignKey(() => VideoCommentModel)
64 @Column
65 inReplyToCommentId: number
66
67 @BelongsTo(() => VideoCommentModel, {
68 foreignKey: {
69 allowNull: true
70 },
71 onDelete: 'CASCADE'
72 })
73 InReplyToVideoComment: VideoCommentModel
74
75 @ForeignKey(() => VideoModel)
76 @Column
77 videoId: number
78
79 @BelongsTo(() => VideoModel, {
80 foreignKey: {
81 allowNull: false
82 },
83 onDelete: 'CASCADE'
84 })
85 Video: VideoModel
86
d3ea8975 87 @ForeignKey(() => AccountModel)
6d852470 88 @Column
d3ea8975 89 accountId: number
6d852470 90
d3ea8975 91 @BelongsTo(() => AccountModel, {
6d852470
C
92 foreignKey: {
93 allowNull: false
94 },
95 onDelete: 'CASCADE'
96 })
d3ea8975 97 Account: AccountModel
6d852470 98
bf1f6508
C
99 @AfterDestroy
100 static sendDeleteIfOwned (instance: VideoCommentModel) {
101 // TODO
102 return undefined
103 }
104
105 static loadById (id: number, t?: Sequelize.Transaction) {
106 const query: IFindOptions<VideoCommentModel> = {
107 where: {
108 id
109 }
110 }
111
112 if (t !== undefined) query.transaction = t
113
114 return VideoCommentModel.findOne(query)
115 }
116
6d852470
C
117 static loadByUrl (url: string, t?: Sequelize.Transaction) {
118 const query: IFindOptions<VideoCommentModel> = {
119 where: {
120 url
121 }
122 }
123
124 if (t !== undefined) query.transaction = t
125
126 return VideoCommentModel.findOne(query)
127 }
bf1f6508
C
128
129 static listThreadsForApi (videoId: number, start: number, count: number, sort: string) {
130 const query = {
131 offset: start,
132 limit: count,
133 order: [ getSort(sort) ],
134 where: {
d3ea8975
C
135 videoId,
136 inReplyToCommentId: null
bf1f6508
C
137 }
138 }
139
140 return VideoCommentModel
d3ea8975 141 .scope([ ScopeNames.WITH_ACCOUNT ])
bf1f6508
C
142 .findAndCountAll(query)
143 .then(({ rows, count }) => {
144 return { total: count, data: rows }
145 })
146 }
147
148 static listThreadCommentsForApi (videoId: number, threadId: number) {
149 const query = {
d3ea8975 150 order: [ [ 'id', 'ASC' ] ],
bf1f6508
C
151 where: {
152 videoId,
153 [ Sequelize.Op.or ]: [
154 { id: threadId },
155 { originCommentId: threadId }
156 ]
157 }
158 }
159
160 return VideoCommentModel
d3ea8975 161 .scope([ ScopeNames.WITH_ACCOUNT ])
bf1f6508
C
162 .findAndCountAll(query)
163 .then(({ rows, count }) => {
164 return { total: count, data: rows }
165 })
166 }
167
168 toFormattedJSON () {
169 return {
170 id: this.id,
171 url: this.url,
172 text: this.text,
173 threadId: this.originCommentId || this.id,
174 inReplyToCommentId: this.inReplyToCommentId,
175 videoId: this.videoId,
176 createdAt: this.createdAt,
d3ea8975
C
177 updatedAt: this.updatedAt,
178 account: {
179 name: this.Account.name
180 }
bf1f6508
C
181 } as VideoComment
182 }
6d852470 183}