Fix multiple server tests
authorChocobozzz <me@florianbigard.com>
Thu, 1 Aug 2019 08:15:28 +0000 (10:15 +0200)
committerChocobozzz <me@florianbigard.com>
Thu, 1 Aug 2019 08:15:28 +0000 (10:15 +0200)
client/angular.json
server/lib/activitypub/process/process-dislike.ts
server/lib/activitypub/process/process-like.ts
server/lib/activitypub/video-comments.ts
server/lib/video-comment.ts
server/models/account/account-video-rate.ts
server/models/video/video-comment.ts
server/models/video/video-share.ts
shared/extra-utils/videos/videos.ts

index 8a709e26989afb078394b4fa3b0a22eccc81b641..cce930b82e638e1bef0ec84da98d29149428bb71 100644 (file)
               "buildOptimizer": true,
               "serviceWorker": true,
               "ngswConfigPath": "src/ngsw-config.json",
+              "budgets": [
+                {
+                  "type": "initial",
+                  "type": "initial",
+                  "maximumWarning": "2mb",
+                  "maximumWarning": "2mb",
+                  "maximumError": "5mb"
+                  "maximumError": "5mb"
+                },
+                {
+                  "type": "anyComponentStyle",
+                  "maximumWarning": "6kb",
+                  "maximumError": "10kb"
+                }
+              ],
               "fileReplacements": [
                 {
                   "replace": "src/environments/environment.ts",
index bfd69e07a2dd4223e5782a511506f542571ecb39..ed8afd3d2608a0fdb0f74719b985fae3ba92b558 100644 (file)
@@ -29,20 +29,21 @@ async function processDislike (activity: ActivityCreate | ActivityDislike, byAct
   const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject })
 
   return sequelizeTypescript.transaction(async t => {
-    const rate = {
+    const url = getVideoDislikeActivityPubUrl(byActor, video)
+
+    const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, url)
+    if (existingRate && existingRate.type === 'dislike') return
+
+    await AccountVideoRateModel.create({
       type: 'dislike' as 'dislike',
       videoId: video.id,
-      accountId: byAccount.id
-    }
+      accountId: byAccount.id,
+      url
+    }, { transaction: t })
 
-    const [ , created ] = await AccountVideoRateModel.findOrCreate({
-      where: rate,
-      defaults: Object.assign({}, rate, { url: getVideoDislikeActivityPubUrl(byActor, video) }),
-      transaction: t
-    })
-    if (created === true) await video.increment('dislikes', { transaction: t })
+    await video.increment('dislikes', { transaction: t })
 
-    if (video.isOwned() && created === true) {
+    if (video.isOwned()) {
       // Don't resend the activity to the sender
       const exceptions = [ byActor ]
 
index 2a04167d78a5c72364981a75c8f6fc5d64493096..8b97aae556bd985e9b2747f8d953bf239ba83564 100644 (file)
@@ -29,19 +29,21 @@ async function processLikeVideo (byActor: ActorModel, activity: ActivityLike) {
   const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl })
 
   return sequelizeTypescript.transaction(async t => {
-    const rate = {
+    const url = getVideoLikeActivityPubUrl(byActor, video)
+
+    const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, url)
+    if (existingRate && existingRate.type === 'like') return
+
+    await AccountVideoRateModel.create({
       type: 'like' as 'like',
       videoId: video.id,
-      accountId: byAccount.id
-    }
-    const [ , created ] = await AccountVideoRateModel.findOrCreate({
-      where: rate,
-      defaults: Object.assign({}, rate, { url: getVideoLikeActivityPubUrl(byActor, video) }),
-      transaction: t
-    })
-    if (created === true) await video.increment('likes', { transaction: t })
-
-    if (video.isOwned() && created === true) {
+      accountId: byAccount.id,
+      url
+    }, { transaction: t })
+
+    await video.increment('likes', { transaction: t })
+
+    if (video.isOwned()) {
       // Don't resend the activity to the sender
       const exceptions = [ byActor ]
 
index 2f26ddefd3bdcc34806192b6360b6bf990cc7ca9..921abdb8db2015882e67c3501711c41fca76a6fa 100644 (file)
@@ -54,7 +54,7 @@ async function addVideoComment (videoInstance: VideoModel, commentUrl: string) {
   })
 
   if (sanitizeAndCheckVideoCommentObject(body) === false) {
-    logger.debug('Remote video comment JSON is not valid.', { body })
+    logger.debug('Remote video comment JSON %s is not valid.', commentUrl, { body })
     return { created: false }
   }
 
index bfe22d225b88ecfb7b7b3aa6846f2e35c41b492c..449aa74cb10a1f503bf48e58fd6229078c380f1f 100644 (file)
@@ -27,10 +27,10 @@ async function createVideoComment (obj: {
     inReplyToCommentId,
     videoId: obj.video.id,
     accountId: obj.account.id,
-    url: 'fake url'
-  }, { transaction: t, validate: false } as any) // FIXME: sequelize typings
+    url: new Date().toISOString()
+  }, { transaction: t, validate: false })
 
-  comment.set('url', getVideoCommentActivityPubUrl(obj.video, comment))
+  comment.url = getVideoCommentActivityPubUrl(obj.video, comment)
 
   const savedComment = await comment.save({ transaction: t })
   savedComment.InReplyToVideoComment = obj.inReplyToComment
index 85af9e3782c38535cab1ed01b53e2df1d7606031..d5c214ecbc69b1a9e82395404b88b5c680642aab 100644 (file)
@@ -89,6 +89,25 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
     return AccountVideoRateModel.findOne(options)
   }
 
+  static loadByAccountAndVideoOrUrl (accountId: number, videoId: number, url: string, transaction?: Transaction) {
+    const options: FindOptions = {
+      where: {
+        [ Op.or]: [
+          {
+            accountId,
+            videoId
+          },
+          {
+            url
+          }
+        ]
+      }
+    }
+    if (transaction) options.transaction = transaction
+
+    return AccountVideoRateModel.findOne(options)
+  }
+
   static listByAccountForApi (options: {
     start: number,
     count: number,
@@ -202,6 +221,23 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
           videoId,
           type
         },
+        include: [
+          {
+            model: AccountModel.unscoped(),
+            required: true,
+            include: [
+              {
+                model: ActorModel.unscoped(),
+                required: true,
+                where: {
+                  serverId: {
+                    [Op.ne]: null
+                  }
+                }
+              }
+            ]
+          }
+        ],
         transaction: t
       }
 
index 536b6cb3ec0a0485eab87da53b1bc94dab9542f8..28e5818cd3acf846e0f87ae05685f28104b00634 100644 (file)
@@ -472,7 +472,24 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
           [Op.lt]: beforeUpdatedAt
         },
         videoId
-      }
+      },
+      include: [
+        {
+          required: true,
+          model: AccountModel.unscoped(),
+          include: [
+            {
+              required: true,
+              model: ActorModel.unscoped(),
+              where: {
+                serverId: {
+                  [Op.ne]: null
+                }
+              }
+            }
+          ]
+        }
+      ]
     }
 
     return VideoCommentModel.destroy(query)
index fda2d7cea42e2231671bc59b023a8525d8550351..3bab3c0273892cea1324494f8dd29197a1a5da6b 100644 (file)
@@ -1,4 +1,3 @@
-import * as Sequelize from 'sequelize'
 import * as Bluebird from 'bluebird'
 import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
 import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
@@ -8,6 +7,7 @@ import { ActorModel } from '../activitypub/actor'
 import { throwIfNotValid } from '../utils'
 import { VideoModel } from './video'
 import { VideoChannelModel } from './video-channel'
+import { Op, Transaction } from 'sequelize'
 
 enum ScopeNames {
   FULL = 'FULL',
@@ -88,7 +88,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
   })
   Video: VideoModel
 
-  static load (actorId: number, videoId: number, t?: Sequelize.Transaction) {
+  static load (actorId: number, videoId: number, t?: Transaction) {
     return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
       where: {
         actorId,
@@ -98,7 +98,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
     })
   }
 
-  static loadByUrl (url: string, t: Sequelize.Transaction) {
+  static loadByUrl (url: string, t: Transaction) {
     return VideoShareModel.scope(ScopeNames.FULL).findOne({
       where: {
         url
@@ -107,7 +107,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
     })
   }
 
-  static loadActorsByShare (videoId: number, t: Sequelize.Transaction) {
+  static loadActorsByShare (videoId: number, t: Transaction) {
     const query = {
       where: {
         videoId
@@ -125,7 +125,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
       .then(res => res.map(r => r.Actor))
   }
 
-  static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
+  static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird<ActorModel[]> {
     const query = {
       attributes: [],
       include: [
@@ -163,7 +163,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
       .then(res => res.map(r => r.Actor))
   }
 
-  static loadActorsByVideoChannel (videoChannelId: number, t: Sequelize.Transaction): Bluebird<ActorModel[]> {
+  static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird<ActorModel[]> {
     const query = {
       attributes: [],
       include: [
@@ -188,7 +188,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
       .then(res => res.map(r => r.Actor))
   }
 
-  static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Sequelize.Transaction) {
+  static listAndCountByVideoId (videoId: number, start: number, count: number, t?: Transaction) {
     const query = {
       offset: start,
       limit: count,
@@ -205,10 +205,21 @@ export class VideoShareModel extends Model<VideoShareModel> {
     const query = {
       where: {
         updatedAt: {
-          [Sequelize.Op.lt]: beforeUpdatedAt
+          [Op.lt]: beforeUpdatedAt
         },
         videoId
-      }
+      },
+      include: [
+        {
+          model: ActorModel.unscoped(),
+          required: true,
+          where: {
+            serverId: {
+              [ Op.ne ]: null
+            }
+          }
+        }
+      ]
     }
 
     return VideoShareModel.destroy(query)
index c785632328b63407a5c6b51ae4727582970640bb..1533f37aba1a772bc2cce4f903898a3bb9688bda 100644 (file)
@@ -379,7 +379,8 @@ async function uploadVideo (url: string, accessToken: string, videoAttributesArg
     req.field('licence', attributes.licence.toString())
   }
 
-  for (let i = 0; i < attributes.tags.length; i++) {
+  const tags = attributes.tags || []
+  for (let i = 0; i < tags.length; i++) {
     req.field('tags[' + i + ']', attributes.tags[i])
   }