Lowercase video tags search
authorChocobozzz <me@florianbigard.com>
Thu, 29 Aug 2019 14:47:32 +0000 (16:47 +0200)
committerChocobozzz <me@florianbigard.com>
Thu, 29 Aug 2019 14:47:32 +0000 (16:47 +0200)
server/models/video/tag.ts
server/models/video/video.ts
server/tests/api/search/search-videos.ts

index b110f2a436e55dc8044c19de1feb547867d1ec6a..ed8df8b48aa84367003161035dda9256eac13c76 100644 (file)
@@ -1,5 +1,5 @@
 import * as Bluebird from 'bluebird'
-import { QueryTypes, Transaction } from 'sequelize'
+import { fn, QueryTypes, Transaction, col } from 'sequelize'
 import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
 import { isVideoTagValid } from '../../helpers/custom-validators/videos'
 import { throwIfNotValid } from '../utils'
@@ -15,6 +15,10 @@ import { MTag } from '@server/typings/models'
     {
       fields: [ 'name' ],
       unique: true
+    },
+    {
+      name: 'tag_lower_name',
+      fields: [ fn('lower', col('name')) ] as any // FIXME: typings
     }
   ]
 })
index 6a95f6ef7e58d10bf51c2b27aac4f9b46cf57db3..6856dcd9f057baa5f7d0f7c895afee3d7df8e43f 100644 (file)
@@ -468,13 +468,15 @@ export type AvailableForListIDsOptions = {
     // FIXME: issues with sequelize count when making a join on n:m relation, so we just make a IN()
     if (options.tagsAllOf || options.tagsOneOf) {
       if (options.tagsOneOf) {
+        const tagsOneOfLower = options.tagsOneOf.map(t => t.toLowerCase())
+
         whereAnd.push({
           id: {
             [ Op.in ]: Sequelize.literal(
               '(' +
               'SELECT "videoId" FROM "videoTag" ' +
               'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
-              'WHERE "tag"."name" IN (' + createSafeIn(VideoModel, options.tagsOneOf) + ')' +
+              'WHERE lower("tag"."name") IN (' + createSafeIn(VideoModel, tagsOneOfLower) + ')' +
               ')'
             )
           }
@@ -482,14 +484,16 @@ export type AvailableForListIDsOptions = {
       }
 
       if (options.tagsAllOf) {
+        const tagsAllOfLower = options.tagsAllOf.map(t => t.toLowerCase())
+
         whereAnd.push({
           id: {
             [ Op.in ]: Sequelize.literal(
               '(' +
               'SELECT "videoId" FROM "videoTag" ' +
               'INNER JOIN "tag" ON "tag"."id" = "videoTag"."tagId" ' +
-              'WHERE "tag"."name" IN (' + createSafeIn(VideoModel, options.tagsAllOf) + ')' +
-              'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + options.tagsAllOf.length +
+              'WHERE lower("tag"."name") IN (' + createSafeIn(VideoModel, tagsAllOfLower) + ')' +
+              'GROUP BY "videoTag"."videoId" HAVING COUNT(*) = ' + tagsAllOfLower.length +
               ')'
             )
           }
index c06200ffe4fc83da99354cbeebf46d85d87fa2c1..a3e05156b189dc4d3efd825595f180da0e33d535 100644 (file)
@@ -206,7 +206,7 @@ describe('Test videos search', function () {
     const query = {
       search: '9999',
       categoryOneOf: [ 1 ],
-      tagsOneOf: [ 'aaaa', 'ffff' ]
+      tagsOneOf: [ 'aAaa', 'ffff' ]
     }
     const res1 = await advancedVideosSearch(server.url, query)
     expect(res1.body.total).to.equal(2)
@@ -219,15 +219,15 @@ describe('Test videos search', function () {
     const query = {
       search: '9999',
       categoryOneOf: [ 1 ],
-      tagsAllOf: [ 'cccc' ]
+      tagsAllOf: [ 'CCcc' ]
     }
     const res1 = await advancedVideosSearch(server.url, query)
     expect(res1.body.total).to.equal(2)
 
-    const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'blabla' ] }))
+    const res2 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'blAbla' ] }))
     expect(res2.body.total).to.equal(0)
 
-    const res3 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'bbbb', 'cccc' ] }))
+    const res3 = await advancedVideosSearch(server.url, immutableAssign(query, { tagsAllOf: [ 'bbbb', 'CCCC' ] }))
     expect(res3.body.total).to.equal(1)
   })