add parseBytes utility function and tests (#1239)
authorBRAINS YUM <43896676+McFlat@users.noreply.github.com>
Sat, 13 Oct 2018 06:43:55 +0000 (01:43 -0500)
committerChocobozzz <me@florianbigard.com>
Sat, 13 Oct 2018 06:43:55 +0000 (08:43 +0200)
* add parseBytes utility function and tests
make it parse TB MB
fix parseBytes; * 1024
test bytes too, and make parseByte to parse quotas
add test in travis.sh in misc

* fix parseBytes and test to pass linting

scripts/travis.sh
server/helpers/core-utils.ts
server/initializers/constants.ts
server/tests/helpers/core-utils.ts [new file with mode: 0644]
server/tests/helpers/index.ts [new file with mode: 0644]

index 5d195f902baae8f3de4abc6b52ff1fa4eedcb9a9..628039ab7170f9cf7ef0dd74ba70fe54a5b1c260 100755 (executable)
@@ -11,8 +11,11 @@ killall -q peertube || true
 
 if [ "$1" = "misc" ]; then
     npm run build -- --light-fr
-    mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/client.ts server/tests/activitypub.ts \
-        server/tests/feeds/index.ts server/tests/misc-endpoints.ts
+    mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/client.ts \
+        server/tests/activitypub.ts \
+        server/tests/feeds/index.ts \
+        server/tests/misc-endpoints.ts \
+        server/tests/helpers/index.ts
 elif [ "$1" = "api" ]; then
     npm run build:server
     mocha --timeout 5000 --exit --require ts-node/register/type-check --bail server/tests/api/index.ts
index 224e4fe92fc9c249224e4674ff01c154d8aecae0..84e33c0e987a253dded722800e7d9b0f460c96ac 100644 (file)
@@ -21,6 +21,7 @@ const timeTable = {
   week:         3600000 * 24 * 7,
   month:        3600000 * 24 * 30
 }
+
 export function parseDuration (duration: number | string): number {
   if (typeof duration === 'number') return duration
 
@@ -41,6 +42,53 @@ export function parseDuration (duration: number | string): number {
   throw new Error('Duration could not be properly parsed')
 }
 
+export function parseBytes (value: string | number): number {
+  if (typeof value === 'number') return value
+
+  const tgm = /^(\d+)\s*TB\s*(\d+)\s*GB\s*(\d+)\s*MB$/
+  const tg = /^(\d+)\s*TB\s*(\d+)\s*GB$/
+  const tm = /^(\d+)\s*TB\s*(\d+)\s*MB$/
+  const gm = /^(\d+)\s*GB\s*(\d+)\s*MB$/
+  const t = /^(\d+)\s*TB$/
+  const g = /^(\d+)\s*GB$/
+  const m = /^(\d+)\s*MB$/
+  const b = /^(\d+)\s*B$/
+  let match
+
+  if (value.match(tgm)) {
+    match = value.match(tgm)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+    + parseInt(match[2], 10) * 1024 * 1024 * 1024
+    + parseInt(match[3], 10) * 1024 * 1024
+  } else if (value.match(tg)) {
+    match = value.match(tg)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+    + parseInt(match[2], 10) * 1024 * 1024 * 1024
+  } else if (value.match(tm)) {
+    match = value.match(tm)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+    + parseInt(match[2], 10) * 1024 * 1024
+  } else if (value.match(gm)) {
+    match = value.match(gm)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024
+    + parseInt(match[2], 10) * 1024 * 1024
+  } else if (value.match(t)) {
+    match = value.match(t)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024 * 1024
+  } else if (value.match(g)) {
+    match = value.match(g)
+    return parseInt(match[1], 10) * 1024 * 1024 * 1024
+  } else if (value.match(m)) {
+    match = value.match(m)
+    return parseInt(match[1], 10) * 1024 * 1024
+  } else if (value.match(b)) {
+    match = value.match(b)
+    return parseInt(match[1], 10) * 1024
+  } else {
+    return parseInt(value, 10)
+  }
+}
+
 function sanitizeUrl (url: string) {
   const urlObject = new URL(url)
 
index a3e5f5dd20e4737de9a6a18678b05c0b6c42f511..e08fd75cd85540df7267e0210a6f9b8c9dd3c61e 100644 (file)
@@ -5,7 +5,7 @@ import { ActivityPubActorType } from '../../shared/models/activitypub'
 import { FollowState } from '../../shared/models/actors'
 import { VideoAbuseState, VideoImportState, VideoPrivacy, VideoTranscodingFPS } from '../../shared/models/videos'
 // Do not use barrels, remain constants as independent as possible
-import { buildPath, isTestInstance, parseDuration, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
+import { buildPath, isTestInstance, parseDuration, parseBytes, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
 import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
 import { invert } from 'lodash'
 import { CronRepeatOptions, EveryRepeatOptions } from 'bull'
@@ -232,8 +232,8 @@ const CONFIG = {
     }
   },
   USER: {
-    get VIDEO_QUOTA () { return config.get<number>('user.video_quota') },
-    get VIDEO_QUOTA_DAILY () { return config.get<number>('user.video_quota_daily') }
+    get VIDEO_QUOTA () { return parseBytes(config.get<number>('user.video_quota')) },
+    get VIDEO_QUOTA_DAILY () { return parseBytes(config.get<number>('user.video_quota_daily')) }
   },
   TRANSCODING: {
     get ENABLED () { return config.get<boolean>('transcoding.enabled') },
diff --git a/server/tests/helpers/core-utils.ts b/server/tests/helpers/core-utils.ts
new file mode 100644 (file)
index 0000000..a6d829a
--- /dev/null
@@ -0,0 +1,48 @@
+/* tslint:disable:no-unused-expression */
+
+import * as chai from 'chai'
+import 'mocha'
+import {
+  parseBytes
+} from '../../helpers/core-utils'
+
+const expect = chai.expect
+
+describe('Parse Bytes', function () {
+  it('Should pass when given valid value', async function () {
+    // just return it
+    expect(parseBytes(1024)).to.be.eq(1024)
+    expect(parseBytes(1048576)).to.be.eq(1048576)
+    expect(parseBytes('1024')).to.be.eq(1024)
+    expect(parseBytes('1048576')).to.be.eq(1048576)
+
+    // sizes
+    expect(parseBytes('1B')).to.be.eq(1024)
+    expect(parseBytes('1MB')).to.be.eq(1048576)
+    expect(parseBytes('1GB')).to.be.eq(1073741824)
+    expect(parseBytes('1TB')).to.be.eq(1099511627776)
+
+    expect(parseBytes('5GB')).to.be.eq(5368709120)
+    expect(parseBytes('5TB')).to.be.eq(5497558138880)
+
+    expect(parseBytes('1024B')).to.be.eq(1048576)
+    expect(parseBytes('1024MB')).to.be.eq(1073741824)
+    expect(parseBytes('1024GB')).to.be.eq(1099511627776)
+    expect(parseBytes('1024TB')).to.be.eq(1125899906842624)
+
+    // with whitespace
+    expect(parseBytes('1 GB')).to.be.eq(1073741824)
+    expect(parseBytes('1\tGB')).to.be.eq(1073741824)
+
+    // sum value
+    expect(parseBytes('1TB 1024MB')).to.be.eq(1100585369600)
+    expect(parseBytes('4GB 1024MB')).to.be.eq(5368709120)
+    expect(parseBytes('4TB 1024GB')).to.be.eq(5497558138880)
+    expect(parseBytes('4TB 1024GB 0MB')).to.be.eq(5497558138880)
+    expect(parseBytes('1024TB 1024GB 1024MB')).to.be.eq(1127000492212224)
+  })
+
+  it('Should be invalid when given invalid value', async function () {
+    expect(parseBytes('6GB 1GB')).to.be.eq(6)
+  })
+})
diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts
new file mode 100644 (file)
index 0000000..40c7dc7
--- /dev/null
@@ -0,0 +1 @@
+import './core-utils'