joi 7.2.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/test/string.js CHANGED
@@ -34,24 +34,6 @@ describe('string', () => {
34
34
 
35
35
  describe('valid()', () => {
36
36
 
37
- it('should throw error on input not matching type', (done) => {
38
-
39
- expect(() => {
40
-
41
- Joi.string().valid({});
42
- }).to.throw();
43
- done();
44
- });
45
-
46
- it('should not throw on input matching type', (done) => {
47
-
48
- expect(() => {
49
-
50
- Joi.string().valid('joi');
51
- }).to.not.throw();
52
- done();
53
- });
54
-
55
37
  it('validates case sensitive values', (done) => {
56
38
 
57
39
  Helper.validate(Joi.string().valid('a', 'b'), [
@@ -88,24 +70,6 @@ describe('string', () => {
88
70
 
89
71
  describe('invalid()', () => {
90
72
 
91
- it('should throw error on input not matching type', (done) => {
92
-
93
- expect(() => {
94
-
95
- Joi.string().invalid({});
96
- }).to.throw();
97
- done();
98
- });
99
-
100
- it('should not throw on input matching type', (done) => {
101
-
102
- expect(() => {
103
-
104
- Joi.string().invalid('joi');
105
- }).to.not.throw();
106
- done();
107
- });
108
-
109
73
  it('invalidates case sensitive values', (done) => {
110
74
 
111
75
  Helper.validate(Joi.string().invalid('a', 'b'), [
@@ -496,6 +460,89 @@ describe('string', () => {
496
460
  }).to.not.throw();
497
461
  done();
498
462
  });
463
+
464
+ it('validates email', (done) => {
465
+
466
+ const schema = Joi.string().email();
467
+ Helper.validate(schema, [
468
+ ['joe@example.com', true],
469
+ ['"joe"@example.com', true],
470
+ ['@iaminvalid.com', false],
471
+ ['joe@[IPv6:2a00:1450:4001:c02::1b]', true],
472
+ ['12345678901234567890123456789012345678901234567890123456789012345@walmartlabs.com', false],
473
+ ['123456789012345678901234567890123456789012345678901234567890@12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345.toolong.com', false]
474
+ ], done);
475
+ });
476
+
477
+ it('validates email with tldWhitelist as array', (done) => {
478
+
479
+ const schema = Joi.string().email({ tldWhitelist: ['com', 'org'] });
480
+ Helper.validate(schema, [
481
+ ['joe@example.com', true],
482
+ ['joe@example.org', true],
483
+ ['joe@example.edu', false]
484
+ ], done);
485
+ });
486
+
487
+ it('validates email with tldWhitelist as object', (done) => {
488
+
489
+ const schema = Joi.string().email({ tldWhitelist: { com: true, org: true } });
490
+ Helper.validate(schema, [
491
+ ['joe@example.com', true],
492
+ ['joe@example.org', true],
493
+ ['joe@example.edu', false]
494
+ ], done);
495
+ });
496
+
497
+ it('validates email with minDomainAtoms', (done) => {
498
+
499
+ const schema = Joi.string().email({ minDomainAtoms: 4 });
500
+ Helper.validate(schema, [
501
+ ['joe@example.com', false],
502
+ ['joe@www.example.com', false],
503
+ ['joe@sub.www.example.com', true]
504
+ ], done);
505
+ });
506
+
507
+ it('validates email with errorLevel as boolean', (done) => {
508
+
509
+ let schema = Joi.string().email({ errorLevel: false });
510
+ Helper.validate(schema, [
511
+ ['joe@example.com', true],
512
+ ['joe@www.example.com', true],
513
+ ['joe@localhost', true],
514
+ ['joe', false]
515
+ ]);
516
+
517
+ schema = Joi.string().email({ errorLevel: true });
518
+ Helper.validate(schema, [
519
+ ['joe@example.com', true],
520
+ ['joe@www.example.com', true],
521
+ ['joe@localhost', false],
522
+ ['joe', false]
523
+ ], done);
524
+ });
525
+
526
+ it('validates email with errorLevel as integer', (done) => {
527
+
528
+ const schema = Joi.string().email({ errorLevel: 10 });
529
+ Helper.validate(schema, [
530
+ ['joe@example.com', true],
531
+ ['joe@www.example.com', true],
532
+ ['joe@localhost', true],
533
+ ['joe', false]
534
+ ], done);
535
+ });
536
+
537
+ it('validates email with a friendly error message', (done) => {
538
+
539
+ const schema = { item: Joi.string().email() };
540
+ Joi.compile(schema).validate({ item: 'something' }, (err, value) => {
541
+
542
+ expect(err.message).to.contain('must be a valid email');
543
+ done();
544
+ });
545
+ });
499
546
  });
500
547
 
501
548
  describe('hostname()', () => {
@@ -1329,520 +1376,725 @@ describe('string', () => {
1329
1376
  });
1330
1377
  });
1331
1378
 
1332
- describe('validate()', () => {
1379
+ describe('uri()', () => {
1333
1380
 
1334
- it('should, by default, allow undefined, deny empty string', (done) => {
1381
+ it('validates uri', (done) => {
1335
1382
 
1336
- Helper.validate(Joi.string(), [
1337
- [undefined, true],
1338
- ['', false]
1383
+ // Handful of tests taken from Node: https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/test/simple/test-url.js
1384
+ // Also includes examples from RFC 8936: http://tools.ietf.org/html/rfc3986#page-7
1385
+ const schema = Joi.string().uri();
1386
+
1387
+ Helper.validate(schema, [
1388
+ ['foo://example.com:8042/over/there?name=ferret#nose', true],
1389
+ ['urn:example:animal:ferret:nose', true],
1390
+ ['ftp://ftp.is.co.za/rfc/rfc1808.txt', true],
1391
+ ['http://www.ietf.org/rfc/rfc2396.txt', true],
1392
+ ['ldap://[2001:db8::7]/c=GB?objectClass?one', true],
1393
+ ['mailto:John.Doe@example.com', true],
1394
+ ['news:comp.infosystems.www.servers.unix', true],
1395
+ ['tel:+1-816-555-1212', true],
1396
+ ['telnet://192.0.2.16:80/', true],
1397
+ ['urn:oasis:names:specification:docbook:dtd:xml:4.1.2', true],
1398
+ ['file:///example.txt', true],
1399
+ ['http://asdf:qw%20er@localhost:8000?asdf=12345&asda=fc%2F#bacon', true],
1400
+ ['http://asdf@localhost:8000', true],
1401
+ ['http://[v1.09azAZ-._~!$&\'()*+,;=:]', true],
1402
+ ['http://[a:b:c:d:e::1.2.3.4]', true],
1403
+ ['coap://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]', true],
1404
+ ['http://[1080:0:0:0:8:800:200C:417A]', true],
1405
+ ['http://127.0.0.1:8000/foo?bar', true],
1406
+ ['http://asdf:qwer@localhost:8000', true],
1407
+ ['http://user:pass%3A@localhost:80', true],
1408
+ ['http://localhost:123', true],
1409
+ ['https://localhost:123', true],
1410
+ ['file:///whatever', true],
1411
+ ['mailto:asdf@asdf.com', true],
1412
+ ['ftp://www.example.com', true],
1413
+ ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
1414
+ ['xmpp:isaacschlueter@jabber.org', true],
1415
+ ['f://some.host/path', true],
1416
+ ['http://localhost:18/asdf', true],
1417
+ ['http://localhost:42/asdf?qwer=zxcv', true],
1418
+ ['HTTP://www.example.com/', true],
1419
+ ['HTTP://www.example.com', true],
1420
+ ['http://www.ExAmPlE.com/', true],
1421
+ ['http://user:pw@www.ExAmPlE.com/', true],
1422
+ ['http://USER:PW@www.ExAmPlE.com/', true],
1423
+ ['http://user@www.example.com/', true],
1424
+ ['http://user%3Apw@www.example.com/', true],
1425
+ ['http://x.com/path?that%27s#all,%20folks', true],
1426
+ ['HTTP://X.COM/Y', true],
1427
+ ['http://www.narwhaljs.org/blog/categories?id=news', true],
1428
+ ['http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=', true],
1429
+ ['http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
1430
+ ['http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
1431
+ ['http://_jabber._tcp.google.com:80/test', true],
1432
+ ['http://user:pass@_jabber._tcp.google.com:80/test', true],
1433
+ ['http://[fe80::1]/a/b?a=b#abc', true],
1434
+ ['http://user:password@[3ffe:2a00:100:7031::1]:8080', true],
1435
+ ['coap://[1080:0:0:0:8:800:200C:417A]:61616/', true],
1436
+ ['git+http://github.com/joyent/node.git', true],
1437
+ ['http://bucket_name.s3.amazonaws.com/image.jpg', true],
1438
+ ['dot.test://foo/bar', true],
1439
+ ['svn+ssh://foo/bar', true],
1440
+ ['dash-test://foo/bar', true],
1441
+ ['xmpp:isaacschlueter@jabber.org', true],
1442
+ ['http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar', true],
1443
+ ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
1444
+ ['file://localhost/etc/node/', true],
1445
+ ['file:///etc/node/', true],
1446
+ ['http://USER:PW@www.ExAmPlE.com/', true],
1447
+ ['mailto:local1@domain1?query1', true],
1448
+ ['http://example/a/b?c/../d', true],
1449
+ ['http://example/x%2Fabc', true],
1450
+ ['http://a/b/c/d;p=1/g;x=1/y', true],
1451
+ ['http://a/b/c/g#s/../x', true],
1452
+ ['http://a/b/c/.foo', true],
1453
+ ['http://example.com/b//c//d;p?q#blarg', true],
1454
+ ['g:h', true],
1455
+ ['http://a/b/c/g', true],
1456
+ ['http://a/b/c/g/', true],
1457
+ ['http://a/g', true],
1458
+ ['http://g', true],
1459
+ ['http://a/b/c/d;p?y', true],
1460
+ ['http://a/b/c/g?y', true],
1461
+ ['http://a/b/c/d;p?q#s', true],
1462
+ ['http://a/b/c/g#s', true],
1463
+ ['http://a/b/c/g?y#s', true],
1464
+ ['http://a/b/c/;x', true],
1465
+ ['http://a/b/c/g;x', true],
1466
+ ['http://a/b/c/g;x?y#s', true],
1467
+ ['http://a/b/c/d;p?q', true],
1468
+ ['http://a/b/c/', true],
1469
+ ['http://a/b/', true],
1470
+ ['http://a/b/g', true],
1471
+ ['http://a/', true],
1472
+ ['http://a/g', true],
1473
+ ['http://a/g', true],
1474
+ ['file:/asda', true],
1475
+ ['qwerty', false],
1476
+ ['invalid uri', false],
1477
+ ['1http://google.com', false],
1478
+ ['http://testdomain`,.<>/?\'";{}][++\\|~!@#$%^&*().org', false],
1479
+ ['', false],
1480
+ ['(╯°□°)╯︵ ┻━┻', false],
1481
+ ['one/two/three?value=abc&value2=123#david-rules', false],
1482
+ ['//username:password@test.example.com/one/two/three?value=abc&value2=123#david-rules', false],
1483
+ ['http://a\r" \t\n<\'b:b@c\r\nd/e?f', false],
1484
+ ['/absolute', false]
1339
1485
  ], done);
1340
1486
  });
1341
1487
 
1342
- it('should, when .required(), deny undefined, deny empty string', (done) => {
1488
+ it('validates uri with a single scheme provided', (done) => {
1343
1489
 
1344
- Helper.validate(Joi.string().required(), [
1345
- [undefined, false],
1346
- ['', false]
1490
+ const schema = Joi.string().uri({
1491
+ scheme: 'http'
1492
+ });
1493
+
1494
+ Helper.validate(schema, [
1495
+ ['http://google.com', true],
1496
+ ['https://google.com', false],
1497
+ ['ftp://google.com', false],
1498
+ ['file:/asdf', false],
1499
+ ['/path?query=value#hash', false]
1347
1500
  ], done);
1348
1501
  });
1349
1502
 
1350
- it('should, when .required(), print a friend error message for an empty string', (done) => {
1351
-
1352
- const schema = Joi.string().required();
1353
- Joi.compile(schema).validate('', (err, value) => {
1503
+ it('validates uri with a single regex scheme provided', (done) => {
1354
1504
 
1355
- expect(err.message).to.contain('be empty');
1356
- done();
1505
+ const schema = Joi.string().uri({
1506
+ scheme: /https?/
1357
1507
  });
1358
- });
1359
1508
 
1360
- it('should, when .required(), validate non-empty strings', (done) => {
1361
-
1362
- const schema = Joi.string().required();
1363
1509
  Helper.validate(schema, [
1364
- ['test', true],
1365
- ['0', true],
1366
- [null, false]
1510
+ ['http://google.com', true],
1511
+ ['https://google.com', true],
1512
+ ['ftp://google.com', false],
1513
+ ['file:/asdf', false],
1514
+ ['/path?query=value#hash', false]
1367
1515
  ], done);
1368
1516
  });
1369
1517
 
1370
- it('validates invalid values', (done) => {
1518
+ it('validates uri with multiple schemes provided', (done) => {
1371
1519
 
1372
- const schema = Joi.string().invalid('a', 'b', 'c');
1373
- Helper.validate(schema, [
1374
- ['x', true],
1375
- ['a', false],
1376
- ['c', false]
1377
- ], done);
1378
- });
1379
-
1380
- it('should invalidate invalid values', (done) => {
1520
+ const schema = Joi.string().uri({
1521
+ scheme: [/https?/, 'ftp', 'file', 'git+http']
1522
+ });
1381
1523
 
1382
- const schema = Joi.string().valid('a', 'b', 'c');
1383
1524
  Helper.validate(schema, [
1384
- ['x', false],
1385
- ['a', true],
1386
- ['c', true]
1525
+ ['http://google.com', true],
1526
+ ['https://google.com', true],
1527
+ ['ftp://google.com', true],
1528
+ ['file:/asdf', true],
1529
+ ['git+http://github.com/hapijs/joi', true],
1530
+ ['/path?query=value#hash', false]
1387
1531
  ], done);
1388
1532
  });
1389
1533
 
1390
- it('validates array arguments correctly', (done) => {
1534
+ it('validates uri with a friendly error message', (done) => {
1391
1535
 
1392
- const schema = Joi.string().valid(['a', 'b', 'c']);
1393
- Helper.validate(schema, [
1394
- ['x', false],
1395
- ['a', true],
1396
- ['c', true]
1397
- ], done);
1398
- });
1536
+ const schema = { item: Joi.string().uri() };
1399
1537
 
1400
- it('validates minimum length when min is used', (done) => {
1538
+ Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
1401
1539
 
1402
- const schema = Joi.string().min(3);
1403
- Helper.validate(schema, [
1404
- ['test', true],
1405
- ['0', false],
1406
- [null, false]
1407
- ], done);
1540
+ expect(err.message).to.contain('must be a valid uri');
1541
+ done();
1542
+ });
1408
1543
  });
1409
1544
 
1410
- it('validates minimum length when min is 0', (done) => {
1545
+ it('validates uri with a custom scheme with a friendly error message', (done) => {
1411
1546
 
1412
- const schema = Joi.string().min(0).required();
1413
- Helper.validate(schema, [
1414
- ['0', true],
1415
- [null, false],
1416
- [undefined, false]
1417
- ], done);
1418
- });
1547
+ const schema = {
1548
+ item: Joi.string().uri({
1549
+ scheme: 'http'
1550
+ })
1551
+ };
1419
1552
 
1420
- it('should return false with minimum length and a null value passed in', (done) => {
1553
+ Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
1421
1554
 
1422
- const schema = Joi.string().min(3);
1423
- Helper.validate(schema, [
1424
- [null, false]
1425
- ], done);
1555
+ expect(err.message).to.contain('must be a valid uri with a scheme matching the http pattern');
1556
+ done();
1557
+ });
1426
1558
  });
1427
1559
 
1428
- it('null allowed overrides min length requirement', (done) => {
1560
+ it('validates uri with a custom array of schemes with a friendly error message', (done) => {
1429
1561
 
1430
- const schema = Joi.string().min(3).allow(null);
1431
- Helper.validate(schema, [
1432
- [null, true]
1433
- ], done);
1434
- });
1562
+ const schema = {
1563
+ item: Joi.string().uri({
1564
+ scheme: ['http', /https?/]
1565
+ })
1566
+ };
1435
1567
 
1436
- it('validates maximum length when max is used', (done) => {
1568
+ Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
1437
1569
 
1438
- const schema = Joi.string().max(3);
1439
- Helper.validate(schema, [
1440
- ['test', false],
1441
- ['0', true],
1442
- [null, false]
1443
- ], done);
1570
+ expect(err.message).to.contain('must be a valid uri with a scheme matching the http|https? pattern');
1571
+ done();
1572
+ });
1444
1573
  });
1445
1574
 
1446
- it('should return true with max and not required when value is undefined', (done) => {
1575
+ it('validates uri treats scheme as optional', (done) => {
1447
1576
 
1448
- const schema = Joi.string().max(3);
1449
- Helper.validate(schema, [
1450
- [undefined, true]
1451
- ], done);
1452
- });
1577
+ expect(() => {
1453
1578
 
1454
- it('validates length requirements', (done) => {
1579
+ Joi.string().uri({});
1580
+ }).to.not.throw();
1455
1581
 
1456
- const schema = Joi.string().length(3);
1457
- Helper.validate(schema, [
1458
- ['test', false],
1459
- ['0', false],
1460
- [null, false],
1461
- ['abc', true]
1462
- ], done);
1582
+ done();
1463
1583
  });
1464
1584
 
1465
- it('validates regex', (done) => {
1585
+ it('validates uri requires uriOptions as an object with a friendly error message', (done) => {
1466
1586
 
1467
- const schema = Joi.string().regex(/^[0-9][-][a-z]+$/);
1468
- Helper.validate(schema, [
1469
- ['van', false],
1470
- ['0-www', true]
1471
- ], done);
1472
- });
1587
+ expect(() => {
1473
1588
 
1474
- it('validates regex (ignoring global flag)', (done) => {
1589
+ Joi.string().uri('http');
1590
+ }).to.throw(Error, 'options must be an object');
1475
1591
 
1476
- const schema = Joi.string().regex(/a/g);
1477
- Helper.validate(schema, [
1478
- ['ab', true],
1479
- ['ac', true]
1480
- ], done);
1592
+ done();
1481
1593
  });
1482
1594
 
1483
- it('validates token', (done) => {
1595
+ it('validates uri requires scheme to be a RegExp, String, or Array with a friendly error message', (done) => {
1484
1596
 
1485
- const schema = Joi.string().token();
1486
- Helper.validate(schema, [
1487
- ['w0rld_of_w4lm4rtl4bs', true],
1488
- ['w0rld of_w4lm4rtl4bs', false],
1489
- ['abcd#f?h1j orly?', false]
1490
- ], done);
1491
- });
1597
+ expect(() => {
1492
1598
 
1493
- it('validates alphanum', (done) => {
1599
+ Joi.string().uri({
1600
+ scheme: {}
1601
+ });
1602
+ }).to.throw(Error, 'scheme must be a RegExp, String, or Array');
1494
1603
 
1495
- const schema = Joi.string().alphanum();
1496
- Helper.validate(schema, [
1497
- ['w0rld of w4lm4rtl4bs', false],
1498
- ['w0rldofw4lm4rtl4bs', true],
1499
- ['abcd#f?h1j orly?', false]
1500
- ], done);
1604
+ done();
1501
1605
  });
1502
1606
 
1503
- it('validates email', (done) => {
1607
+ it('validates uri requires scheme to not be an empty array', (done) => {
1504
1608
 
1505
- const schema = Joi.string().email();
1506
- Helper.validate(schema, [
1507
- ['joe@example.com', true],
1508
- ['"joe"@example.com', true],
1509
- ['@iaminvalid.com', false],
1510
- ['joe@[IPv6:2a00:1450:4001:c02::1b]', true],
1511
- ['12345678901234567890123456789012345678901234567890123456789012345@walmartlabs.com', false],
1512
- ['123456789012345678901234567890123456789012345678901234567890@12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345678901234567890123456789012345678901234567890123456789.12345.toolong.com', false]
1513
- ], done);
1514
- });
1609
+ expect(() => {
1515
1610
 
1516
- it('validates email with tldWhitelist as array', (done) => {
1611
+ Joi.string().uri({
1612
+ scheme: []
1613
+ });
1614
+ }).to.throw(Error, 'scheme must have at least 1 scheme specified');
1517
1615
 
1518
- const schema = Joi.string().email({ tldWhitelist: ['com', 'org'] });
1519
- Helper.validate(schema, [
1520
- ['joe@example.com', true],
1521
- ['joe@example.org', true],
1522
- ['joe@example.edu', false]
1523
- ], done);
1616
+ done();
1524
1617
  });
1525
1618
 
1526
- it('validates email with tldWhitelist as object', (done) => {
1619
+ it('validates uri requires scheme to be an Array of schemes to all be valid schemes with a friendly error message', (done) => {
1527
1620
 
1528
- const schema = Joi.string().email({ tldWhitelist: { com: true, org: true } });
1529
- Helper.validate(schema, [
1530
- ['joe@example.com', true],
1531
- ['joe@example.org', true],
1532
- ['joe@example.edu', false]
1533
- ], done);
1534
- });
1621
+ expect(() => {
1535
1622
 
1536
- it('validates email with minDomainAtoms', (done) => {
1623
+ Joi.string().uri({
1624
+ scheme: [
1625
+ 'http',
1626
+ '~!@#$%^&*()_'
1627
+ ]
1628
+ });
1629
+ }).to.throw(Error, 'scheme at position 1 must be a valid scheme');
1537
1630
 
1538
- const schema = Joi.string().email({ minDomainAtoms: 4 });
1539
- Helper.validate(schema, [
1540
- ['joe@example.com', false],
1541
- ['joe@www.example.com', false],
1542
- ['joe@sub.www.example.com', true]
1543
- ], done);
1631
+ done();
1544
1632
  });
1545
1633
 
1546
- it('validates email with errorLevel as boolean', (done) => {
1547
-
1548
- let schema = Joi.string().email({ errorLevel: false });
1549
- Helper.validate(schema, [
1550
- ['joe@example.com', true],
1551
- ['joe@www.example.com', true],
1552
- ['joe@localhost', true],
1553
- ['joe', false]
1554
- ]);
1634
+ it('validates uri requires scheme to be an Array of schemes to be strings or RegExp', (done) => {
1555
1635
 
1556
- schema = Joi.string().email({ errorLevel: true });
1557
- Helper.validate(schema, [
1558
- ['joe@example.com', true],
1559
- ['joe@www.example.com', true],
1560
- ['joe@localhost', false],
1561
- ['joe', false]
1562
- ], done);
1563
- });
1636
+ expect(() => {
1564
1637
 
1565
- it('validates email with errorLevel as integer', (done) => {
1638
+ Joi.string().uri({
1639
+ scheme: [
1640
+ 'http',
1641
+ {}
1642
+ ]
1643
+ });
1644
+ }).to.throw(Error, 'scheme at position 1 must be a RegExp or String');
1566
1645
 
1567
- const schema = Joi.string().email({ errorLevel: 10 });
1568
- Helper.validate(schema, [
1569
- ['joe@example.com', true],
1570
- ['joe@www.example.com', true],
1571
- ['joe@localhost', true],
1572
- ['joe', false]
1573
- ], done);
1646
+ done();
1574
1647
  });
1575
1648
 
1576
- it('validates email with a friendly error message', (done) => {
1577
-
1578
- const schema = { item: Joi.string().email() };
1579
- Joi.compile(schema).validate({ item: 'something' }, (err, value) => {
1580
-
1581
- expect(err.message).to.contain('must be a valid email');
1582
- done();
1583
- });
1584
- });
1649
+ it('validates uri requires scheme to be a valid String scheme with a friendly error message', (done) => {
1585
1650
 
1586
- it('should return false for denied value', (done) => {
1651
+ expect(() => {
1587
1652
 
1588
- const text = Joi.string().invalid('joi');
1589
- text.validate('joi', (err, value) => {
1653
+ Joi.string().uri({
1654
+ scheme: '~!@#$%^&*()_'
1655
+ });
1656
+ }).to.throw(Error, 'scheme at position 0 must be a valid scheme');
1590
1657
 
1591
- expect(err).to.exist();
1592
- done();
1593
- });
1658
+ done();
1594
1659
  });
1595
1660
 
1596
- it('should return true for allowed value', (done) => {
1597
-
1598
- const text = Joi.string().allow('hapi');
1599
- text.validate('result', (err, value) => {
1661
+ it('validates relative uri', (done) => {
1600
1662
 
1601
- expect(err).to.not.exist();
1602
- done();
1603
- });
1663
+ const schema = Joi.string().uri({ allowRelative: true });
1664
+ Helper.validate(schema, [
1665
+ ['foo://example.com:8042/over/there?name=ferret#nose', true],
1666
+ ['urn:example:animal:ferret:nose', true],
1667
+ ['ftp://ftp.is.co.za/rfc/rfc1808.txt', true],
1668
+ ['http://www.ietf.org/rfc/rfc2396.txt', true],
1669
+ ['ldap://[2001:db8::7]/c=GB?objectClass?one', true],
1670
+ ['mailto:John.Doe@example.com', true],
1671
+ ['news:comp.infosystems.www.servers.unix', true],
1672
+ ['tel:+1-816-555-1212', true],
1673
+ ['telnet://192.0.2.16:80/', true],
1674
+ ['urn:oasis:names:specification:docbook:dtd:xml:4.1.2', true],
1675
+ ['file:///example.txt', true],
1676
+ ['http://asdf:qw%20er@localhost:8000?asdf=12345&asda=fc%2F#bacon', true],
1677
+ ['http://asdf@localhost:8000', true],
1678
+ ['http://[v1.09azAZ-._~!$&\'()*+,;=:]', true],
1679
+ ['http://[a:b:c:d:e::1.2.3.4]', true],
1680
+ ['coap://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]', true],
1681
+ ['http://[1080:0:0:0:8:800:200C:417A]', true],
1682
+ ['http://127.0.0.1:8000/foo?bar', true],
1683
+ ['http://asdf:qwer@localhost:8000', true],
1684
+ ['http://user:pass%3A@localhost:80', true],
1685
+ ['http://localhost:123', true],
1686
+ ['https://localhost:123', true],
1687
+ ['file:///whatever', true],
1688
+ ['mailto:asdf@asdf.com', true],
1689
+ ['ftp://www.example.com', true],
1690
+ ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
1691
+ ['xmpp:isaacschlueter@jabber.org', true],
1692
+ ['f://some.host/path', true],
1693
+ ['http://localhost:18/asdf', true],
1694
+ ['http://localhost:42/asdf?qwer=zxcv', true],
1695
+ ['HTTP://www.example.com/', true],
1696
+ ['HTTP://www.example.com', true],
1697
+ ['http://www.ExAmPlE.com/', true],
1698
+ ['http://user:pw@www.ExAmPlE.com/', true],
1699
+ ['http://USER:PW@www.ExAmPlE.com/', true],
1700
+ ['http://user@www.example.com/', true],
1701
+ ['http://user%3Apw@www.example.com/', true],
1702
+ ['http://x.com/path?that%27s#all,%20folks', true],
1703
+ ['HTTP://X.COM/Y', true],
1704
+ ['http://www.narwhaljs.org/blog/categories?id=news', true],
1705
+ ['http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=', true],
1706
+ ['http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
1707
+ ['http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
1708
+ ['http://_jabber._tcp.google.com:80/test', true],
1709
+ ['http://user:pass@_jabber._tcp.google.com:80/test', true],
1710
+ ['http://[fe80::1]/a/b?a=b#abc', true],
1711
+ ['http://user:password@[3ffe:2a00:100:7031::1]:8080', true],
1712
+ ['coap://[1080:0:0:0:8:800:200C:417A]:61616/', true],
1713
+ ['git+http://github.com/joyent/node.git', true],
1714
+ ['http://bucket_name.s3.amazonaws.com/image.jpg', true],
1715
+ ['dot.test://foo/bar', true],
1716
+ ['svn+ssh://foo/bar', true],
1717
+ ['dash-test://foo/bar', true],
1718
+ ['xmpp:isaacschlueter@jabber.org', true],
1719
+ ['http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar', true],
1720
+ ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
1721
+ ['file://localhost/etc/node/', true],
1722
+ ['file:///etc/node/', true],
1723
+ ['http://USER:PW@www.ExAmPlE.com/', true],
1724
+ ['mailto:local1@domain1?query1', true],
1725
+ ['http://example/a/b?c/../d', true],
1726
+ ['http://example/x%2Fabc', true],
1727
+ ['http://a/b/c/d;p=1/g;x=1/y', true],
1728
+ ['http://a/b/c/g#s/../x', true],
1729
+ ['http://a/b/c/.foo', true],
1730
+ ['http://example.com/b//c//d;p?q#blarg', true],
1731
+ ['g:h', true],
1732
+ ['http://a/b/c/g', true],
1733
+ ['http://a/b/c/g/', true],
1734
+ ['http://a/g', true],
1735
+ ['http://g', true],
1736
+ ['http://a/b/c/d;p?y', true],
1737
+ ['http://a/b/c/g?y', true],
1738
+ ['http://a/b/c/d;p?q#s', true],
1739
+ ['http://a/b/c/g#s', true],
1740
+ ['http://a/b/c/g?y#s', true],
1741
+ ['http://a/b/c/;x', true],
1742
+ ['http://a/b/c/g;x', true],
1743
+ ['http://a/b/c/g;x?y#s', true],
1744
+ ['http://a/b/c/d;p?q', true],
1745
+ ['http://a/b/c/', true],
1746
+ ['http://a/b/', true],
1747
+ ['http://a/b/g', true],
1748
+ ['http://a/', true],
1749
+ ['http://a/g', true],
1750
+ ['http://a/g', true],
1751
+ ['file:/asda', true],
1752
+ ['qwerty', true],
1753
+ ['invalid uri', false],
1754
+ ['1http://google.com', false],
1755
+ ['http://testdomain`,.<>/?\'";{}][++\\|~!@#$%^&*().org', false],
1756
+ ['', false],
1757
+ ['(╯°□°)╯︵ ┻━┻', false],
1758
+ ['one/two/three?value=abc&value2=123#david-rules', true],
1759
+ ['//username:password@test.example.com/one/two/three?value=abc&value2=123#david-rules', true],
1760
+ ['http://a\r" \t\n<\'b:b@c\r\nd/e?f', false],
1761
+ ['/absolute', true]
1762
+ ], done);
1604
1763
  });
1764
+ });
1605
1765
 
1606
- it('validates with one validator (min)', (done) => {
1766
+ describe('validate()', () => {
1607
1767
 
1608
- const text = Joi.string().min(3);
1609
- text.validate('joi', (err, value) => {
1768
+ it('should, by default, allow undefined, deny empty string', (done) => {
1610
1769
 
1611
- expect(err).to.not.exist();
1612
- done();
1613
- });
1770
+ Helper.validate(Joi.string(), [
1771
+ [undefined, true],
1772
+ ['', false]
1773
+ ], done);
1614
1774
  });
1615
1775
 
1616
- it('validates with two validators (min, required)', (done) => {
1776
+ it('should, when .required(), deny undefined, deny empty string', (done) => {
1617
1777
 
1618
- const text = Joi.string().min(3).required();
1619
- text.validate('joi', (err, value) => {
1778
+ Helper.validate(Joi.string().required(), [
1779
+ [undefined, false],
1780
+ ['', false]
1781
+ ], done);
1782
+ });
1620
1783
 
1621
- expect(err).to.not.exist();
1784
+ it('should, when .required(), print a friend error message for an empty string', (done) => {
1622
1785
 
1623
- text.validate('', (err2, value2) => {
1786
+ const schema = Joi.string().required();
1787
+ Joi.compile(schema).validate('', (err, value) => {
1624
1788
 
1625
- expect(err2).to.exist();
1626
- done();
1627
- });
1789
+ expect(err.message).to.contain('be empty');
1790
+ done();
1628
1791
  });
1629
1792
  });
1630
1793
 
1631
- it('validates null with allow(null)', (done) => {
1794
+ it('should, when .required(), validate non-empty strings', (done) => {
1632
1795
 
1633
- Helper.validate(Joi.string().allow(null), [
1634
- [null, true]
1796
+ const schema = Joi.string().required();
1797
+ Helper.validate(schema, [
1798
+ ['test', true],
1799
+ ['0', true],
1800
+ [null, false]
1635
1801
  ], done);
1636
1802
  });
1637
1803
 
1638
- it('validates "" (empty string) with allow(\'\')', (done) => {
1804
+ it('validates invalid values', (done) => {
1639
1805
 
1640
- Helper.validate(Joi.string().allow(''), [
1641
- ['', true],
1642
- ['', true]
1806
+ const schema = Joi.string().invalid('a', 'b', 'c');
1807
+ Helper.validate(schema, [
1808
+ ['x', true],
1809
+ ['a', false],
1810
+ ['c', false]
1643
1811
  ], done);
1644
1812
  });
1645
1813
 
1646
- it('validates combination of required and min', (done) => {
1814
+ it('should invalidate invalid values', (done) => {
1647
1815
 
1648
- const rule = Joi.string().required().min(3);
1649
- Helper.validate(rule, [
1816
+ const schema = Joi.string().valid('a', 'b', 'c');
1817
+ Helper.validate(schema, [
1650
1818
  ['x', false],
1651
- ['123', true],
1652
- ['', false],
1653
- [null, false]
1819
+ ['a', true],
1820
+ ['c', true]
1654
1821
  ], done);
1655
1822
  });
1656
1823
 
1657
- it('validates combination of required and max', (done) => {
1824
+ it('validates array arguments correctly', (done) => {
1658
1825
 
1659
- const rule = Joi.string().required().max(3);
1660
- Helper.validate(rule, [
1661
- ['x', true],
1662
- ['123', true],
1663
- ['1234', false],
1664
- ['', false],
1665
- [null, false]
1826
+ const schema = Joi.string().valid(['a', 'b', 'c']);
1827
+ Helper.validate(schema, [
1828
+ ['x', false],
1829
+ ['a', true],
1830
+ ['c', true]
1666
1831
  ], done);
1667
1832
  });
1668
1833
 
1669
- it('validates combination of allow(\'\') and min', (done) => {
1834
+ it('validates minimum length when min is used', (done) => {
1670
1835
 
1671
- const rule = Joi.string().allow('').min(3);
1672
- Helper.validate(rule, [
1673
- ['x', false],
1674
- ['123', true],
1675
- ['1234', true],
1676
- ['', true],
1836
+ const schema = Joi.string().min(3);
1837
+ Helper.validate(schema, [
1838
+ ['test', true],
1839
+ ['0', false],
1677
1840
  [null, false]
1678
1841
  ], done);
1679
1842
  });
1680
1843
 
1681
- it('validates combination of allow(\'\') and max', (done) => {
1844
+ it('validates minimum length when min is 0', (done) => {
1682
1845
 
1683
- const rule = Joi.string().allow('').max(3);
1684
- Helper.validate(rule, [
1685
- ['x', true],
1686
- ['123', true],
1687
- ['1234', false],
1688
- ['', true],
1689
- [null, false]
1846
+ const schema = Joi.string().min(0).required();
1847
+ Helper.validate(schema, [
1848
+ ['0', true],
1849
+ [null, false],
1850
+ [undefined, false]
1690
1851
  ], done);
1691
1852
  });
1692
1853
 
1693
- it('validates combination of null allowed and max', (done) => {
1854
+ it('should return false with minimum length and a null value passed in', (done) => {
1694
1855
 
1695
- const rule = Joi.string().allow(null).max(3);
1696
- Helper.validate(rule, [
1697
- ['x', true],
1698
- ['123', true],
1699
- ['1234', false],
1700
- ['', false],
1701
- [null, true]
1856
+ const schema = Joi.string().min(3);
1857
+ Helper.validate(schema, [
1858
+ [null, false]
1702
1859
  ], done);
1703
1860
  });
1704
1861
 
1705
- it('validates combination of min and max', (done) => {
1862
+ it('null allowed overrides min length requirement', (done) => {
1706
1863
 
1707
- const rule = Joi.string().min(2).max(3);
1708
- Helper.validate(rule, [
1709
- ['x', false],
1710
- ['123', true],
1711
- ['1234', false],
1712
- ['12', true],
1713
- ['', false],
1714
- [null, false]
1864
+ const schema = Joi.string().min(3).allow(null);
1865
+ Helper.validate(schema, [
1866
+ [null, true]
1715
1867
  ], done);
1716
1868
  });
1717
1869
 
1718
- it('validates combination of min, max, and allow(\'\')', (done) => {
1870
+ it('validates maximum length when max is used', (done) => {
1719
1871
 
1720
- const rule = Joi.string().min(2).max(3).allow('');
1721
- Helper.validate(rule, [
1722
- ['x', false],
1723
- ['123', true],
1724
- ['1234', false],
1725
- ['12', true],
1726
- ['', true],
1872
+ const schema = Joi.string().max(3);
1873
+ Helper.validate(schema, [
1874
+ ['test', false],
1875
+ ['0', true],
1727
1876
  [null, false]
1728
1877
  ], done);
1729
1878
  });
1730
1879
 
1731
- it('validates combination of min, max, and required', (done) => {
1880
+ it('should return true with max and not required when value is undefined', (done) => {
1732
1881
 
1733
- const rule = Joi.string().min(2).max(3).required();
1734
- Helper.validate(rule, [
1735
- ['x', false],
1736
- ['123', true],
1737
- ['1234', false],
1738
- ['12', true],
1739
- ['', false],
1740
- [null, false]
1882
+ const schema = Joi.string().max(3);
1883
+ Helper.validate(schema, [
1884
+ [undefined, true]
1741
1885
  ], done);
1742
1886
  });
1743
1887
 
1744
- it('validates combination of min, max, and regex', (done) => {
1888
+ it('validates length requirements', (done) => {
1745
1889
 
1746
- const rule = Joi.string().min(2).max(3).regex(/^a/);
1747
- Helper.validate(rule, [
1748
- ['x', false],
1749
- ['123', false],
1750
- ['1234', false],
1751
- ['12', false],
1890
+ const schema = Joi.string().length(3);
1891
+ Helper.validate(schema, [
1892
+ ['test', false],
1893
+ ['0', false],
1894
+ [null, false],
1895
+ ['abc', true]
1896
+ ], done);
1897
+ });
1898
+
1899
+ it('validates regex', (done) => {
1900
+
1901
+ const schema = Joi.string().regex(/^[0-9][-][a-z]+$/);
1902
+ Helper.validate(schema, [
1903
+ ['van', false],
1904
+ ['0-www', true]
1905
+ ], done);
1906
+ });
1907
+
1908
+ it('validates regex (ignoring global flag)', (done) => {
1909
+
1910
+ const schema = Joi.string().regex(/a/g);
1911
+ Helper.validate(schema, [
1752
1912
  ['ab', true],
1753
- ['abc', true],
1754
- ['abcd', false],
1913
+ ['ac', true]
1914
+ ], done);
1915
+ });
1916
+
1917
+ it('validates token', (done) => {
1918
+
1919
+ const schema = Joi.string().token();
1920
+ Helper.validate(schema, [
1921
+ ['w0rld_of_w4lm4rtl4bs', true],
1922
+ ['w0rld of_w4lm4rtl4bs', false],
1923
+ ['abcd#f?h1j orly?', false]
1924
+ ], done);
1925
+ });
1926
+
1927
+ it('validates alphanum', (done) => {
1928
+
1929
+ const schema = Joi.string().alphanum();
1930
+ Helper.validate(schema, [
1931
+ ['w0rld of w4lm4rtl4bs', false],
1932
+ ['w0rldofw4lm4rtl4bs', true],
1933
+ ['abcd#f?h1j orly?', false]
1934
+ ], done);
1935
+ });
1936
+
1937
+ it('should return false for denied value', (done) => {
1938
+
1939
+ const text = Joi.string().invalid('joi');
1940
+ text.validate('joi', (err, value) => {
1941
+
1942
+ expect(err).to.exist();
1943
+ done();
1944
+ });
1945
+ });
1946
+
1947
+ it('should return true for allowed value', (done) => {
1948
+
1949
+ const text = Joi.string().allow('hapi');
1950
+ text.validate('result', (err, value) => {
1951
+
1952
+ expect(err).to.not.exist();
1953
+ done();
1954
+ });
1955
+ });
1956
+
1957
+ it('validates with one validator (min)', (done) => {
1958
+
1959
+ const text = Joi.string().min(3);
1960
+ text.validate('joi', (err, value) => {
1961
+
1962
+ expect(err).to.not.exist();
1963
+ done();
1964
+ });
1965
+ });
1966
+
1967
+ it('validates with two validators (min, required)', (done) => {
1968
+
1969
+ const text = Joi.string().min(3).required();
1970
+ text.validate('joi', (err, value) => {
1971
+
1972
+ expect(err).to.not.exist();
1973
+
1974
+ text.validate('', (err2, value2) => {
1975
+
1976
+ expect(err2).to.exist();
1977
+ done();
1978
+ });
1979
+ });
1980
+ });
1981
+
1982
+ it('validates null with allow(null)', (done) => {
1983
+
1984
+ Helper.validate(Joi.string().allow(null), [
1985
+ [null, true]
1986
+ ], done);
1987
+ });
1988
+
1989
+ it('validates "" (empty string) with allow(\'\')', (done) => {
1990
+
1991
+ Helper.validate(Joi.string().allow(''), [
1992
+ ['', true],
1993
+ ['', true]
1994
+ ], done);
1995
+ });
1996
+
1997
+ it('validates combination of required and min', (done) => {
1998
+
1999
+ const rule = Joi.string().required().min(3);
2000
+ Helper.validate(rule, [
2001
+ ['x', false],
2002
+ ['123', true],
1755
2003
  ['', false],
1756
2004
  [null, false]
1757
2005
  ], done);
1758
2006
  });
1759
2007
 
1760
- it('validates combination of min, max, regex, and allow(\'\')', (done) => {
2008
+ it('validates combination of required and max', (done) => {
1761
2009
 
1762
- const rule = Joi.string().min(2).max(3).regex(/^a/).allow('');
2010
+ const rule = Joi.string().required().max(3);
2011
+ Helper.validate(rule, [
2012
+ ['x', true],
2013
+ ['123', true],
2014
+ ['1234', false],
2015
+ ['', false],
2016
+ [null, false]
2017
+ ], done);
2018
+ });
2019
+
2020
+ it('validates combination of allow(\'\') and min', (done) => {
2021
+
2022
+ const rule = Joi.string().allow('').min(3);
1763
2023
  Helper.validate(rule, [
1764
2024
  ['x', false],
1765
- ['123', false],
2025
+ ['123', true],
2026
+ ['1234', true],
2027
+ ['', true],
2028
+ [null, false]
2029
+ ], done);
2030
+ });
2031
+
2032
+ it('validates combination of allow(\'\') and max', (done) => {
2033
+
2034
+ const rule = Joi.string().allow('').max(3);
2035
+ Helper.validate(rule, [
2036
+ ['x', true],
2037
+ ['123', true],
1766
2038
  ['1234', false],
1767
- ['12', false],
1768
- ['ab', true],
1769
- ['abc', true],
1770
- ['abcd', false],
1771
2039
  ['', true],
1772
2040
  [null, false]
1773
2041
  ], done);
1774
2042
  });
1775
2043
 
1776
- it('validates combination of min, max, regex, and required', (done) => {
2044
+ it('validates combination of null allowed and max', (done) => {
1777
2045
 
1778
- const rule = Joi.string().min(2).max(3).regex(/^a/).required();
2046
+ const rule = Joi.string().allow(null).max(3);
1779
2047
  Helper.validate(rule, [
1780
- ['x', false],
1781
- ['123', false],
2048
+ ['x', true],
2049
+ ['123', true],
1782
2050
  ['1234', false],
1783
- ['12', false],
1784
- ['ab', true],
1785
- ['abc', true],
1786
- ['abcd', false],
1787
2051
  ['', false],
1788
- [null, false]
2052
+ [null, true]
1789
2053
  ], done);
1790
2054
  });
1791
2055
 
1792
- it('validates combination of min, max, and alphanum', (done) => {
2056
+ it('validates combination of min and max', (done) => {
1793
2057
 
1794
- const rule = Joi.string().min(2).max(3).alphanum();
2058
+ const rule = Joi.string().min(2).max(3);
1795
2059
  Helper.validate(rule, [
1796
2060
  ['x', false],
1797
2061
  ['123', true],
1798
2062
  ['1234', false],
1799
2063
  ['12', true],
1800
- ['ab', true],
1801
- ['abc', true],
1802
- ['abcd', false],
1803
- ['*ab', false],
1804
2064
  ['', false],
1805
2065
  [null, false]
1806
2066
  ], done);
1807
2067
  });
1808
2068
 
1809
- it('validates combination of min, max, alphanum, and allow(\'\')', (done) => {
2069
+ it('validates combination of min, max, and allow(\'\')', (done) => {
1810
2070
 
1811
- const rule = Joi.string().min(2).max(3).alphanum().allow('');
2071
+ const rule = Joi.string().min(2).max(3).allow('');
1812
2072
  Helper.validate(rule, [
1813
2073
  ['x', false],
1814
2074
  ['123', true],
1815
2075
  ['1234', false],
1816
2076
  ['12', true],
1817
- ['ab', true],
1818
- ['abc', true],
1819
- ['abcd', false],
1820
- ['*ab', false],
1821
2077
  ['', true],
1822
2078
  [null, false]
1823
2079
  ], done);
1824
2080
  });
1825
2081
 
1826
- it('validates combination of min, max, alphanum, and required', (done) => {
2082
+ it('validates combination of min, max, and required', (done) => {
1827
2083
 
1828
- const rule = Joi.string().min(2).max(3).alphanum().required();
2084
+ const rule = Joi.string().min(2).max(3).required();
1829
2085
  Helper.validate(rule, [
1830
2086
  ['x', false],
1831
2087
  ['123', true],
1832
2088
  ['1234', false],
1833
2089
  ['12', true],
1834
- ['ab', true],
1835
- ['abc', true],
1836
- ['abcd', false],
1837
- ['*ab', false],
1838
2090
  ['', false],
1839
2091
  [null, false]
1840
2092
  ], done);
1841
2093
  });
1842
2094
 
1843
- it('validates combination of min, max, alphanum, and regex', (done) => {
2095
+ it('validates combination of min, max, and regex', (done) => {
1844
2096
 
1845
- const rule = Joi.string().min(2).max(3).alphanum().regex(/^a/);
2097
+ const rule = Joi.string().min(2).max(3).regex(/^a/);
1846
2098
  Helper.validate(rule, [
1847
2099
  ['x', false],
1848
2100
  ['123', false],
@@ -1850,17 +2102,15 @@ describe('string', () => {
1850
2102
  ['12', false],
1851
2103
  ['ab', true],
1852
2104
  ['abc', true],
1853
- ['a2c', true],
1854
2105
  ['abcd', false],
1855
- ['*ab', false],
1856
2106
  ['', false],
1857
2107
  [null, false]
1858
2108
  ], done);
1859
2109
  });
1860
2110
 
1861
- it('validates combination of min, max, alphanum, required, and regex', (done) => {
2111
+ it('validates combination of min, max, regex, and allow(\'\')', (done) => {
1862
2112
 
1863
- const rule = Joi.string().min(2).max(3).alphanum().required().regex(/^a/);
2113
+ const rule = Joi.string().min(2).max(3).regex(/^a/).allow('');
1864
2114
  Helper.validate(rule, [
1865
2115
  ['x', false],
1866
2116
  ['123', false],
@@ -1868,17 +2118,15 @@ describe('string', () => {
1868
2118
  ['12', false],
1869
2119
  ['ab', true],
1870
2120
  ['abc', true],
1871
- ['a2c', true],
1872
2121
  ['abcd', false],
1873
- ['*ab', false],
1874
- ['', false],
2122
+ ['', true],
1875
2123
  [null, false]
1876
2124
  ], done);
1877
2125
  });
1878
2126
 
1879
- it('validates combination of min, max, alphanum, allow(\'\'), and regex', (done) => {
2127
+ it('validates combination of min, max, regex, and required', (done) => {
1880
2128
 
1881
- const rule = Joi.string().min(2).max(3).alphanum().allow('').regex(/^a/);
2129
+ const rule = Joi.string().min(2).max(3).regex(/^a/).required();
1882
2130
  Helper.validate(rule, [
1883
2131
  ['x', false],
1884
2132
  ['123', false],
@@ -1886,458 +2134,282 @@ describe('string', () => {
1886
2134
  ['12', false],
1887
2135
  ['ab', true],
1888
2136
  ['abc', true],
1889
- ['a2c', true],
1890
2137
  ['abcd', false],
1891
- ['*ab', false],
1892
- ['', true],
1893
- [null, false]
1894
- ], done);
1895
- });
1896
-
1897
- it('validates combination of email and min', (done) => {
1898
-
1899
- const rule = Joi.string().email().min(8);
1900
- Helper.validate(rule, [
1901
- ['x@x.com', false],
1902
- ['123@x.com', true],
1903
2138
  ['', false],
1904
2139
  [null, false]
1905
2140
  ], done);
1906
2141
  });
1907
2142
 
1908
- it('validates combination of email, min, and max', (done) => {
2143
+ it('validates combination of min, max, and alphanum', (done) => {
1909
2144
 
1910
- const rule = Joi.string().email().min(8).max(10);
2145
+ const rule = Joi.string().min(2).max(3).alphanum();
1911
2146
  Helper.validate(rule, [
1912
- ['x@x.com', false],
1913
- ['123@x.com', true],
1914
- ['1234@x.com', true],
1915
- ['12345@x.com', false],
2147
+ ['x', false],
2148
+ ['123', true],
2149
+ ['1234', false],
2150
+ ['12', true],
2151
+ ['ab', true],
2152
+ ['abc', true],
2153
+ ['abcd', false],
2154
+ ['*ab', false],
1916
2155
  ['', false],
1917
2156
  [null, false]
1918
2157
  ], done);
1919
2158
  });
1920
2159
 
1921
- it('validates combination of email, min, max, and invalid', (done) => {
2160
+ it('validates combination of min, max, alphanum, and allow(\'\')', (done) => {
1922
2161
 
1923
- const rule = Joi.string().email().min(8).max(10).invalid('123@x.com');
2162
+ const rule = Joi.string().min(2).max(3).alphanum().allow('');
1924
2163
  Helper.validate(rule, [
1925
- ['x@x.com', false],
1926
- ['123@x.com', false],
1927
- ['1234@x.com', true],
1928
- ['12345@x.com', false],
1929
- ['', false],
2164
+ ['x', false],
2165
+ ['123', true],
2166
+ ['1234', false],
2167
+ ['12', true],
2168
+ ['ab', true],
2169
+ ['abc', true],
2170
+ ['abcd', false],
2171
+ ['*ab', false],
2172
+ ['', true],
1930
2173
  [null, false]
1931
2174
  ], done);
1932
2175
  });
1933
2176
 
1934
- it('validates combination of email, min, max, and allow', (done) => {
2177
+ it('validates combination of min, max, alphanum, and required', (done) => {
1935
2178
 
1936
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com');
1937
- Helper.validate(rule, [
1938
- ['x@x.com', true],
1939
- ['123@x.com', true],
1940
- ['1234@x.com', true],
1941
- ['12345@x.com', false],
1942
- ['', false],
1943
- [null, false]
1944
- ], done);
1945
- });
1946
-
1947
- it('validates combination of email, min, max, allow, and invalid', (done) => {
1948
-
1949
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com');
1950
- Helper.validate(rule, [
1951
- ['x@x.com', true],
1952
- ['123@x.com', false],
1953
- ['1234@x.com', true],
1954
- ['12345@x.com', false],
1955
- ['', false],
1956
- [null, false]
1957
- ], done);
1958
- });
1959
-
1960
- it('validates combination of email, min, max, allow, invalid, and allow(\'\')', (done) => {
1961
-
1962
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').allow('');
1963
- Helper.validate(rule, [
1964
- ['x@x.com', true],
1965
- ['123@x.com', false],
1966
- ['1234@x.com', true],
1967
- ['12345@x.com', false],
1968
- ['', true],
1969
- [null, false]
1970
- ], done);
1971
- });
1972
-
1973
- it('validates combination of email, min, max, allow, and allow(\'\')', (done) => {
1974
-
1975
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com').allow('');
1976
- Helper.validate(rule, [
1977
- ['x@x.com', true],
1978
- ['123@x.com', true],
1979
- ['1234@x.com', true],
1980
- ['12345@x.com', false],
1981
- ['', true],
1982
- [null, false]
1983
- ], done);
1984
- });
1985
-
1986
- it('validates combination of email, min, max, allow, invalid, and regex', (done) => {
1987
-
1988
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/);
1989
- Helper.validate(rule, [
1990
- ['x@x.com', true],
1991
- ['123@x.com', false],
1992
- ['1234@x.com', true],
1993
- ['12345@x.com', false],
1994
- ['', false],
1995
- [null, false]
1996
- ], done);
1997
- });
1998
-
1999
- it('validates combination of email, min, max, allow, invalid, regex, and allow(\'\')', (done) => {
2000
-
2001
- const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/).allow('');
2002
- Helper.validate(rule, [
2003
- ['x@x.com', true],
2004
- ['123@x.com', false],
2005
- ['1234@x.com', true],
2006
- ['12345@x.com', false],
2007
- ['', true],
2008
- [null, false]
2009
- ], done);
2010
- });
2011
-
2012
- it('validates combination of email, min, max, and allow(\'\')', (done) => {
2013
-
2014
- const rule = Joi.string().email().min(8).max(10).allow('');
2015
- Helper.validate(rule, [
2016
- ['x@x.com', false],
2017
- ['123@x.com', true],
2018
- ['1234@x.com', true],
2019
- ['12345@x.com', false],
2020
- ['', true],
2021
- [null, false]
2022
- ], done);
2023
- });
2024
-
2025
- it('validates combination of email, min, max, and regex', (done) => {
2026
-
2027
- const rule = Joi.string().email().min(8).max(10).regex(/^1234/);
2028
- Helper.validate(rule, [
2029
- ['x@x.com', false],
2030
- ['123@x.com', false],
2031
- ['1234@x.com', true],
2032
- ['12345@x.com', false],
2033
- ['', false],
2034
- [null, false]
2035
- ], done);
2036
- });
2037
-
2038
- it('validates combination of email, min, max, regex, and allow(\'\')', (done) => {
2039
-
2040
- const rule = Joi.string().email().min(8).max(10).regex(/^1234/).allow('');
2041
- Helper.validate(rule, [
2042
- ['x@x.com', false],
2043
- ['123@x.com', false],
2044
- ['1234@x.com', true],
2045
- ['12345@x.com', false],
2046
- ['', true],
2047
- [null, false]
2048
- ], done);
2049
- });
2050
-
2051
- it('validates combination of email, min, max, regex, and required', (done) => {
2052
-
2053
- const rule = Joi.string().email().min(8).max(10).regex(/^1234/).required();
2179
+ const rule = Joi.string().min(2).max(3).alphanum().required();
2054
2180
  Helper.validate(rule, [
2055
- ['x@x.com', false],
2056
- ['123@x.com', false],
2057
- ['1234@x.com', true],
2058
- ['12345@x.com', false],
2181
+ ['x', false],
2182
+ ['123', true],
2183
+ ['1234', false],
2184
+ ['12', true],
2185
+ ['ab', true],
2186
+ ['abc', true],
2187
+ ['abcd', false],
2188
+ ['*ab', false],
2059
2189
  ['', false],
2060
2190
  [null, false]
2061
2191
  ], done);
2062
2192
  });
2063
2193
 
2064
- it('validates uri', (done) => {
2065
-
2066
- // Handful of tests taken from Node: https://github.com/joyent/node/blob/cfcb1de130867197cbc9c6012b7e84e08e53d032/test/simple/test-url.js
2067
- // Also includes examples from RFC 8936: http://tools.ietf.org/html/rfc3986#page-7
2068
- const schema = Joi.string().uri();
2069
-
2070
- Helper.validate(schema, [
2071
- ['foo://example.com:8042/over/there?name=ferret#nose', true],
2072
- ['urn:example:animal:ferret:nose', true],
2073
- ['ftp://ftp.is.co.za/rfc/rfc1808.txt', true],
2074
- ['http://www.ietf.org/rfc/rfc2396.txt', true],
2075
- ['ldap://[2001:db8::7]/c=GB?objectClass?one', true],
2076
- ['mailto:John.Doe@example.com', true],
2077
- ['news:comp.infosystems.www.servers.unix', true],
2078
- ['tel:+1-816-555-1212', true],
2079
- ['telnet://192.0.2.16:80/', true],
2080
- ['urn:oasis:names:specification:docbook:dtd:xml:4.1.2', true],
2081
- ['file:///example.txt', true],
2082
- ['http://asdf:qw%20er@localhost:8000?asdf=12345&asda=fc%2F#bacon', true],
2083
- ['http://asdf@localhost:8000', true],
2084
- ['http://[v1.09azAZ-._~!$&\'()*+,;=:]', true],
2085
- ['http://[a:b:c:d:e::1.2.3.4]', true],
2086
- ['coap://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]', true],
2087
- ['http://[1080:0:0:0:8:800:200C:417A]', true],
2088
- ['http://127.0.0.1:8000/foo?bar', true],
2089
- ['http://asdf:qwer@localhost:8000', true],
2090
- ['http://user:pass%3A@localhost:80', true],
2091
- ['http://localhost:123', true],
2092
- ['https://localhost:123', true],
2093
- ['file:///whatever', true],
2094
- ['mailto:asdf@asdf.com', true],
2095
- ['ftp://www.example.com', true],
2096
- ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
2097
- ['xmpp:isaacschlueter@jabber.org', true],
2098
- ['f://some.host/path', true],
2099
- ['http://localhost:18/asdf', true],
2100
- ['http://localhost:42/asdf?qwer=zxcv', true],
2101
- ['HTTP://www.example.com/', true],
2102
- ['HTTP://www.example.com', true],
2103
- ['http://www.ExAmPlE.com/', true],
2104
- ['http://user:pw@www.ExAmPlE.com/', true],
2105
- ['http://USER:PW@www.ExAmPlE.com/', true],
2106
- ['http://user@www.example.com/', true],
2107
- ['http://user%3Apw@www.example.com/', true],
2108
- ['http://x.com/path?that%27s#all,%20folks', true],
2109
- ['HTTP://X.COM/Y', true],
2110
- ['http://www.narwhaljs.org/blog/categories?id=news', true],
2111
- ['http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=', true],
2112
- ['http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
2113
- ['http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=', true],
2114
- ['http://_jabber._tcp.google.com:80/test', true],
2115
- ['http://user:pass@_jabber._tcp.google.com:80/test', true],
2116
- ['http://[fe80::1]/a/b?a=b#abc', true],
2117
- ['http://user:password@[3ffe:2a00:100:7031::1]:8080', true],
2118
- ['coap://[1080:0:0:0:8:800:200C:417A]:61616/', true],
2119
- ['git+http://github.com/joyent/node.git', true],
2120
- ['http://bucket_name.s3.amazonaws.com/image.jpg', true],
2121
- ['dot.test://foo/bar', true],
2122
- ['svn+ssh://foo/bar', true],
2123
- ['dash-test://foo/bar', true],
2124
- ['xmpp:isaacschlueter@jabber.org', true],
2125
- ['http://atpass:foo%40bar@127.0.0.1:8080/path?search=foo#bar', true],
2126
- ['javascript:alert(\'hello\');', true], // eslint-disable-line no-script-url
2127
- ['file://localhost/etc/node/', true],
2128
- ['file:///etc/node/', true],
2129
- ['http://USER:PW@www.ExAmPlE.com/', true],
2130
- ['mailto:local1@domain1?query1', true],
2131
- ['http://example/a/b?c/../d', true],
2132
- ['http://example/x%2Fabc', true],
2133
- ['http://a/b/c/d;p=1/g;x=1/y', true],
2134
- ['http://a/b/c/g#s/../x', true],
2135
- ['http://a/b/c/.foo', true],
2136
- ['http://example.com/b//c//d;p?q#blarg', true],
2137
- ['g:h', true],
2138
- ['http://a/b/c/g', true],
2139
- ['http://a/b/c/g/', true],
2140
- ['http://a/g', true],
2141
- ['http://g', true],
2142
- ['http://a/b/c/d;p?y', true],
2143
- ['http://a/b/c/g?y', true],
2144
- ['http://a/b/c/d;p?q#s', true],
2145
- ['http://a/b/c/g#s', true],
2146
- ['http://a/b/c/g?y#s', true],
2147
- ['http://a/b/c/;x', true],
2148
- ['http://a/b/c/g;x', true],
2149
- ['http://a/b/c/g;x?y#s', true],
2150
- ['http://a/b/c/d;p?q', true],
2151
- ['http://a/b/c/', true],
2152
- ['http://a/b/', true],
2153
- ['http://a/b/g', true],
2154
- ['http://a/', true],
2155
- ['http://a/g', true],
2156
- ['http://a/g', true],
2157
- ['file:/asda', true],
2158
- ['qwerty', false],
2159
- ['invalid uri', false],
2160
- ['1http://google.com', false],
2161
- ['http://testdomain`,.<>/?\'";{}][++\\|~!@#$%^&*().org', false],
2162
- ['', false],
2163
- ['(╯°□°)╯︵ ┻━┻', false],
2164
- ['one/two/three?value=abc&value2=123#david-rules', false],
2165
- ['//username:password@test.example.com/one/two/three?value=abc&value2=123#david-rules', false],
2166
- ['http://a\r" \t\n<\'b:b@c\r\nd/e?f', false]
2167
- ], done);
2168
- });
2169
-
2170
- it('validates uri with a single scheme provided', (done) => {
2171
-
2172
- const schema = Joi.string().uri({
2173
- scheme: 'http'
2174
- });
2175
-
2176
- Helper.validate(schema, [
2177
- ['http://google.com', true],
2178
- ['https://google.com', false],
2179
- ['ftp://google.com', false],
2180
- ['file:/asdf', false],
2181
- ['/path?query=value#hash', false]
2182
- ], done);
2183
- });
2184
-
2185
- it('validates uri with a single regex scheme provided', (done) => {
2186
-
2187
- const schema = Joi.string().uri({
2188
- scheme: /https?/
2189
- });
2190
-
2191
- Helper.validate(schema, [
2192
- ['http://google.com', true],
2193
- ['https://google.com', true],
2194
- ['ftp://google.com', false],
2195
- ['file:/asdf', false],
2196
- ['/path?query=value#hash', false]
2197
- ], done);
2198
- });
2199
-
2200
- it('validates uri with multiple schemes provided', (done) => {
2201
-
2202
- const schema = Joi.string().uri({
2203
- scheme: [/https?/, 'ftp', 'file', 'git+http']
2204
- });
2205
-
2206
- Helper.validate(schema, [
2207
- ['http://google.com', true],
2208
- ['https://google.com', true],
2209
- ['ftp://google.com', true],
2210
- ['file:/asdf', true],
2211
- ['git+http://github.com/hapijs/joi', true],
2212
- ['/path?query=value#hash', false]
2213
- ], done);
2214
- });
2215
-
2216
- it('validates uri with a friendly error message', (done) => {
2217
-
2218
- const schema = { item: Joi.string().uri() };
2219
-
2220
- Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
2221
-
2222
- expect(err.message).to.contain('must be a valid uri');
2223
- done();
2224
- });
2225
- });
2226
-
2227
- it('validates uri with a custom scheme with a friendly error message', (done) => {
2228
-
2229
- const schema = {
2230
- item: Joi.string().uri({
2231
- scheme: 'http'
2232
- })
2233
- };
2234
-
2235
- Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
2236
-
2237
- expect(err.message).to.contain('must be a valid uri with a scheme matching the http pattern');
2238
- done();
2239
- });
2240
- });
2241
-
2242
- it('validates uri with a custom array of schemes with a friendly error message', (done) => {
2194
+ it('validates combination of min, max, alphanum, and regex', (done) => {
2243
2195
 
2244
- const schema = {
2245
- item: Joi.string().uri({
2246
- scheme: ['http', /https?/]
2247
- })
2248
- };
2196
+ const rule = Joi.string().min(2).max(3).alphanum().regex(/^a/);
2197
+ Helper.validate(rule, [
2198
+ ['x', false],
2199
+ ['123', false],
2200
+ ['1234', false],
2201
+ ['12', false],
2202
+ ['ab', true],
2203
+ ['abc', true],
2204
+ ['a2c', true],
2205
+ ['abcd', false],
2206
+ ['*ab', false],
2207
+ ['', false],
2208
+ [null, false]
2209
+ ], done);
2210
+ });
2249
2211
 
2250
- Joi.compile(schema).validate({ item: 'something invalid' }, (err, value) => {
2212
+ it('validates combination of min, max, alphanum, required, and regex', (done) => {
2251
2213
 
2252
- expect(err.message).to.contain('must be a valid uri with a scheme matching the http|https? pattern');
2253
- done();
2254
- });
2214
+ const rule = Joi.string().min(2).max(3).alphanum().required().regex(/^a/);
2215
+ Helper.validate(rule, [
2216
+ ['x', false],
2217
+ ['123', false],
2218
+ ['1234', false],
2219
+ ['12', false],
2220
+ ['ab', true],
2221
+ ['abc', true],
2222
+ ['a2c', true],
2223
+ ['abcd', false],
2224
+ ['*ab', false],
2225
+ ['', false],
2226
+ [null, false]
2227
+ ], done);
2255
2228
  });
2256
2229
 
2257
- it('validates uri treats scheme as optional', (done) => {
2230
+ it('validates combination of min, max, alphanum, allow(\'\'), and regex', (done) => {
2258
2231
 
2259
- expect(() => {
2232
+ const rule = Joi.string().min(2).max(3).alphanum().allow('').regex(/^a/);
2233
+ Helper.validate(rule, [
2234
+ ['x', false],
2235
+ ['123', false],
2236
+ ['1234', false],
2237
+ ['12', false],
2238
+ ['ab', true],
2239
+ ['abc', true],
2240
+ ['a2c', true],
2241
+ ['abcd', false],
2242
+ ['*ab', false],
2243
+ ['', true],
2244
+ [null, false]
2245
+ ], done);
2246
+ });
2260
2247
 
2261
- Joi.string().uri({});
2262
- }).to.not.throw();
2248
+ it('validates combination of email and min', (done) => {
2263
2249
 
2264
- done();
2250
+ const rule = Joi.string().email().min(8);
2251
+ Helper.validate(rule, [
2252
+ ['x@x.com', false],
2253
+ ['123@x.com', true],
2254
+ ['', false],
2255
+ [null, false]
2256
+ ], done);
2265
2257
  });
2266
2258
 
2267
- it('validates uri requires uriOptions as an object with a friendly error message', (done) => {
2259
+ it('validates combination of email, min, and max', (done) => {
2268
2260
 
2269
- expect(() => {
2261
+ const rule = Joi.string().email().min(8).max(10);
2262
+ Helper.validate(rule, [
2263
+ ['x@x.com', false],
2264
+ ['123@x.com', true],
2265
+ ['1234@x.com', true],
2266
+ ['12345@x.com', false],
2267
+ ['', false],
2268
+ [null, false]
2269
+ ], done);
2270
+ });
2270
2271
 
2271
- Joi.string().uri('http');
2272
- }).to.throw(Error, 'options must be an object');
2272
+ it('validates combination of email, min, max, and invalid', (done) => {
2273
2273
 
2274
- done();
2274
+ const rule = Joi.string().email().min(8).max(10).invalid('123@x.com');
2275
+ Helper.validate(rule, [
2276
+ ['x@x.com', false],
2277
+ ['123@x.com', false],
2278
+ ['1234@x.com', true],
2279
+ ['12345@x.com', false],
2280
+ ['', false],
2281
+ [null, false]
2282
+ ], done);
2275
2283
  });
2276
2284
 
2277
- it('validates uri requires scheme to be a RegExp, String, or Array with a friendly error message', (done) => {
2285
+ it('validates combination of email, min, max, and allow', (done) => {
2278
2286
 
2279
- expect(() => {
2287
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com');
2288
+ Helper.validate(rule, [
2289
+ ['x@x.com', true],
2290
+ ['123@x.com', true],
2291
+ ['1234@x.com', true],
2292
+ ['12345@x.com', false],
2293
+ ['', false],
2294
+ [null, false]
2295
+ ], done);
2296
+ });
2280
2297
 
2281
- Joi.string().uri({
2282
- scheme: {}
2283
- });
2284
- }).to.throw(Error, 'scheme must be a RegExp, String, or Array');
2298
+ it('validates combination of email, min, max, allow, and invalid', (done) => {
2285
2299
 
2286
- done();
2300
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com');
2301
+ Helper.validate(rule, [
2302
+ ['x@x.com', true],
2303
+ ['123@x.com', false],
2304
+ ['1234@x.com', true],
2305
+ ['12345@x.com', false],
2306
+ ['', false],
2307
+ [null, false]
2308
+ ], done);
2287
2309
  });
2288
2310
 
2289
- it('validates uri requires scheme to not be an empty array', (done) => {
2311
+ it('validates combination of email, min, max, allow, invalid, and allow(\'\')', (done) => {
2290
2312
 
2291
- expect(() => {
2313
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').allow('');
2314
+ Helper.validate(rule, [
2315
+ ['x@x.com', true],
2316
+ ['123@x.com', false],
2317
+ ['1234@x.com', true],
2318
+ ['12345@x.com', false],
2319
+ ['', true],
2320
+ [null, false]
2321
+ ], done);
2322
+ });
2292
2323
 
2293
- Joi.string().uri({
2294
- scheme: []
2295
- });
2296
- }).to.throw(Error, 'scheme must have at least 1 scheme specified');
2324
+ it('validates combination of email, min, max, allow, and allow(\'\')', (done) => {
2297
2325
 
2298
- done();
2326
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com').allow('');
2327
+ Helper.validate(rule, [
2328
+ ['x@x.com', true],
2329
+ ['123@x.com', true],
2330
+ ['1234@x.com', true],
2331
+ ['12345@x.com', false],
2332
+ ['', true],
2333
+ [null, false]
2334
+ ], done);
2299
2335
  });
2300
2336
 
2301
- it('validates uri requires scheme to be an Array of schemes to all be valid schemes with a friendly error message', (done) => {
2337
+ it('validates combination of email, min, max, allow, invalid, and regex', (done) => {
2302
2338
 
2303
- expect(() => {
2339
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/);
2340
+ Helper.validate(rule, [
2341
+ ['x@x.com', true],
2342
+ ['123@x.com', false],
2343
+ ['1234@x.com', true],
2344
+ ['12345@x.com', false],
2345
+ ['', false],
2346
+ [null, false]
2347
+ ], done);
2348
+ });
2304
2349
 
2305
- Joi.string().uri({
2306
- scheme: [
2307
- 'http',
2308
- '~!@#$%^&*()_'
2309
- ]
2310
- });
2311
- }).to.throw(Error, 'scheme at position 1 must be a valid scheme');
2350
+ it('validates combination of email, min, max, allow, invalid, regex, and allow(\'\')', (done) => {
2312
2351
 
2313
- done();
2352
+ const rule = Joi.string().email().min(8).max(10).allow('x@x.com').invalid('123@x.com').regex(/^1/).allow('');
2353
+ Helper.validate(rule, [
2354
+ ['x@x.com', true],
2355
+ ['123@x.com', false],
2356
+ ['1234@x.com', true],
2357
+ ['12345@x.com', false],
2358
+ ['', true],
2359
+ [null, false]
2360
+ ], done);
2314
2361
  });
2315
2362
 
2316
- it('validates uri requires scheme to be an Array of schemes to be strings or RegExp', (done) => {
2363
+ it('validates combination of email, min, max, and allow(\'\')', (done) => {
2317
2364
 
2318
- expect(() => {
2365
+ const rule = Joi.string().email().min(8).max(10).allow('');
2366
+ Helper.validate(rule, [
2367
+ ['x@x.com', false],
2368
+ ['123@x.com', true],
2369
+ ['1234@x.com', true],
2370
+ ['12345@x.com', false],
2371
+ ['', true],
2372
+ [null, false]
2373
+ ], done);
2374
+ });
2319
2375
 
2320
- Joi.string().uri({
2321
- scheme: [
2322
- 'http',
2323
- {}
2324
- ]
2325
- });
2326
- }).to.throw(Error, 'scheme at position 1 must be a RegExp or String');
2376
+ it('validates combination of email, min, max, and regex', (done) => {
2327
2377
 
2328
- done();
2378
+ const rule = Joi.string().email().min(8).max(10).regex(/^1234/);
2379
+ Helper.validate(rule, [
2380
+ ['x@x.com', false],
2381
+ ['123@x.com', false],
2382
+ ['1234@x.com', true],
2383
+ ['12345@x.com', false],
2384
+ ['', false],
2385
+ [null, false]
2386
+ ], done);
2329
2387
  });
2330
2388
 
2331
- it('validates uri requires scheme to be a valid String scheme with a friendly error message', (done) => {
2389
+ it('validates combination of email, min, max, regex, and allow(\'\')', (done) => {
2332
2390
 
2333
- expect(() => {
2391
+ const rule = Joi.string().email().min(8).max(10).regex(/^1234/).allow('');
2392
+ Helper.validate(rule, [
2393
+ ['x@x.com', false],
2394
+ ['123@x.com', false],
2395
+ ['1234@x.com', true],
2396
+ ['12345@x.com', false],
2397
+ ['', true],
2398
+ [null, false]
2399
+ ], done);
2400
+ });
2334
2401
 
2335
- Joi.string().uri({
2336
- scheme: '~!@#$%^&*()_'
2337
- });
2338
- }).to.throw(Error, 'scheme at position 0 must be a valid scheme');
2402
+ it('validates combination of email, min, max, regex, and required', (done) => {
2339
2403
 
2340
- done();
2404
+ const rule = Joi.string().email().min(8).max(10).regex(/^1234/).required();
2405
+ Helper.validate(rule, [
2406
+ ['x@x.com', false],
2407
+ ['123@x.com', false],
2408
+ ['1234@x.com', true],
2409
+ ['12345@x.com', false],
2410
+ ['', false],
2411
+ [null, false]
2412
+ ], done);
2341
2413
  });
2342
2414
 
2343
2415
  it('validates isoDate', (done) => {
@@ -3042,5 +3114,28 @@ describe('string', () => {
3042
3114
  ['123afg', false, null, '"value" must only contain hexadecimal characters']
3043
3115
  ], done);
3044
3116
  });
3117
+
3118
+ it('validates combination of uppercase, min, max, alphanum and valid', (done) => {
3119
+
3120
+ const rule = Joi.string().uppercase().min(2).max(3).alphanum().valid('AB', 'BC');
3121
+ Helper.validate(rule, [
3122
+ ['x', false],
3123
+ ['123', false],
3124
+ ['1234', false],
3125
+ ['12', false],
3126
+ ['ab', true],
3127
+ ['abc', false],
3128
+ ['a2c', false],
3129
+ ['abcd', false],
3130
+ ['*ab', false],
3131
+ ['', false],
3132
+ ['bc', true],
3133
+ ['BC', true],
3134
+ ['de', false],
3135
+ ['ABc', false],
3136
+ ['AB', true],
3137
+ [null, false]
3138
+ ], done);
3139
+ });
3045
3140
  });
3046
3141
  });