-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathuuid-mongodb_spec.js
156 lines (142 loc) Β· 5.5 KB
/
uuid-mongodb_spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const assert = require('assert');
const { v1: uuidv1 } = require('uuid');
const { v4: uuidv4 } = require('uuid');
const { Binary } = require('mongodb');
const MUUID = require('../lib');
const hasHexUpperCase = (s) => !!/[A-F]/.exec(s);
// accept and generate uuids according to spec - (see https://www.itu.int/rec/T-REC-X.667-201210-I/en)
describe('MUUID', function () {
describe('v1()', () => {
it('should generate a valid v1 uuid', function () {
const mUUID = MUUID.v1();
assert.equal(validate(mUUID.toString()), true);
// ensure generated uuids are always lowercase
// as per spec - (see https://www.itu.int/rec/T-REC-X.667-201210-I/en)
assert.equal(hasHexUpperCase(mUUID.toString()), false);
});
});
describe('v4()', () => {
it('should generate a validate v4 uuid', function () {
const mUUID = MUUID.v4();
assert.equal(validate(mUUID.toString()), true);
// ensure generated uuids are always lowercase
// as per spec - (see https://www.itu.int/rec/T-REC-X.667-201210-I/en)
assert.equal(hasHexUpperCase(mUUID.toString()), false);
});
});
describe('from(uuid)', () => {
it('should convert uuid from string', () => {
const mUUID = MUUID.from(uuidv4());
assert.equal(validate(mUUID.toString()), true);
});
it("should accept uuid's with capital letters, but return with lowercase", () => {
const mUUID = MUUID.from(uuidv4().toUpperCase());
assert.equal(hasHexUpperCase(mUUID.toString()), false);
assert.equal(validate(mUUID.toString()), true);
});
it('should convert uuid from string', () => {
const mUUID = MUUID.from(uuidv4());
assert.equal(validate(mUUID.toString()), true);
});
it('should throw when converting an invalid uuid', () => {
assert.throws(() => MUUID.from('invalid-uuid'), /Invalid UUID\.$/);
assert.throws(
() => MUUID.from('802ac0f09b7311e89bb69baebe1aa0bf'),
/Invalid UUID\.$/
);
});
it('should convert uuid from mongo BSON binary', () => {
const mUUID = MUUID.from(
new Binary(uuidv1(null, Buffer.alloc(16)), Binary.SUBTYPE_UUID)
);
assert.equal(mUUID instanceof Binary, true);
assert.equal(validate(mUUID.toString()), true);
});
it('should throw when attempting to store 36 byte string representation as UUID', () => {
const binary = new Binary(Buffer.from(uuidv1()), Binary.SUBTYPE_UUID);
assert.throws(() => MUUID.from(binary), /Invalid UUID\.$/);
});
it('should throw when converting an Binary non SUBTYPE_UUID', () => {
const binary = new Binary(
uuidv1(null, Buffer.alloc(16)),
Binary.SUBTYPE_USER_DEFINED
);
assert.throws(
() => MUUID.from(binary),
/Unexpected UUID type\. UUID must be a string or a MongoDB Binary \(SUBTYPE_UUID\)\.$/
);
});
});
describe('formatting', () => {
it('should format with default (dashes)', function () {
const mUUID = MUUID.v1();
assert.equal(validate(mUUID.toString()), true);
// ensure generated uuids are always lowercase
// as per spec - (see https://www.itu.int/rec/T-REC-X.667-201210-I/en)
assert.equal(hasHexUpperCase(mUUID.toString()), false);
});
it("should format with format 'D' (dashes)", function () {
const mUUID = MUUID.v1();
const uuid = mUUID.toString('D');
assert.equal(validate(uuid, 'D'), true);
assert.equal(hasHexUpperCase(mUUID.toString('D')), false);
});
it("should format with format 'N' no delimiter", function () {
const mUUID = MUUID.v1();
const uuid = mUUID.toString('N');
assert.equal(validate(uuid, 'N'), true);
assert.equal(hasHexUpperCase(uuid), false);
});
it("should format with format 'B' (curly braces)", function () {
const mUUID = MUUID.v1();
const uuid = mUUID.toString('B');
assert.equal(validate(uuid, 'B'), true);
assert.equal(hasHexUpperCase(uuid), false);
});
it("should format with format 'P' (parens)", function () {
const mUUID = MUUID.v1();
const uuid = mUUID.toString('P');
assert.equal(validate(uuid, 'P'), true);
assert.equal(hasHexUpperCase(uuid), false);
});
});
describe('modes', () => {
it('relaxed mode should print friendly uuid in hex', function () {
const mUUID = MUUID.mode('relaxed').v1();
assert.equal(isBase64(JSON.stringify(mUUID)), false);
assert.equal(validate(mUUID.toString()), true);
assert.equal(hasHexUpperCase(mUUID.toString()), false);
});
it('canonical mode should print base64 uuid ', function () {
const mUUID = MUUID.mode('canonical').v1();
const c = JSON.parse(JSON.stringify(mUUID));
assert.equal(isBase64(c), true);
assert.equal(validate(mUUID.toString()), true);
assert.equal(hasHexUpperCase(mUUID.toString()), false);
});
});
});
function validate(uuid, format) {
if (format === 'N') {
return !!/^[0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12}$/.exec(
uuid
);
} else if (format === 'B') {
return !!/^\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}$/.exec(
uuid
);
} else if (format === 'P') {
return !!/^\([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\)$/.exec(
uuid
);
} else {
return !!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.exec(
uuid
);
}
}
function isBase64(s) {
const bc = /[A-Za-z0-9+/=]/.test(s);
const lc = /.*=$/.test(s); // make sure it ends with '='
return bc && lc;
}