stated-protocol-parser 1.0.3 → 1.0.5
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/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +1 -0
- package/dist/constants.js.map +1 -0
- package/dist/esm/constants.d.ts +47 -0
- package/dist/esm/constants.d.ts.map +1 -0
- package/dist/esm/constants.js +47 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/hash.browser.d.ts +31 -0
- package/dist/esm/hash.browser.d.ts.map +1 -0
- package/dist/esm/hash.browser.js +58 -0
- package/dist/esm/hash.browser.js.map +1 -0
- package/dist/esm/hash.node.d.ts +31 -0
- package/dist/esm/hash.node.d.ts.map +1 -0
- package/dist/esm/hash.node.js +43 -0
- package/dist/esm/hash.node.js.map +1 -0
- package/dist/esm/hash.test.d.ts +2 -0
- package/dist/esm/hash.test.d.ts.map +1 -0
- package/dist/esm/hash.test.js +181 -0
- package/dist/esm/hash.test.js.map +1 -0
- package/dist/esm/index.d.ts +44 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +643 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/index.test.d.ts +2 -0
- package/dist/esm/index.test.d.ts.map +1 -0
- package/dist/esm/index.test.js +293 -0
- package/dist/esm/index.test.js.map +1 -0
- package/dist/esm/types.d.ts +149 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +4 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +23 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/esm/v3.d.ts +5 -0
- package/dist/esm/v3.d.ts.map +1 -0
- package/dist/esm/v3.js +60 -0
- package/dist/esm/v3.js.map +1 -0
- package/dist/hash.browser.d.ts +1 -0
- package/dist/hash.browser.d.ts.map +1 -0
- package/dist/hash.browser.js +1 -0
- package/dist/hash.browser.js.map +1 -0
- package/dist/hash.node.d.ts +1 -0
- package/dist/hash.node.d.ts.map +1 -0
- package/dist/hash.node.js +1 -0
- package/dist/hash.node.js.map +1 -0
- package/dist/hash.test.d.ts +2 -0
- package/dist/hash.test.d.ts.map +1 -0
- package/dist/hash.test.js +183 -0
- package/dist/hash.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +295 -0
- package/dist/index.test.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -0
- package/dist/v3.d.ts +1 -0
- package/dist/v3.d.ts.map +1 -0
- package/dist/v3.js +1 -0
- package/dist/v3.js.map +1 -0
- package/package.json +7 -13
- package/src/constants.ts +61 -0
- package/src/hash.browser.ts +65 -0
- package/src/hash.node.ts +47 -0
- package/src/hash.test.ts +217 -0
- package/src/index.test.ts +378 -0
- package/src/index.ts +678 -0
- package/src/types.ts +186 -0
- package/src/utils.ts +18 -0
- package/src/v3.ts +62 -0
package/src/hash.test.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { sha256, verify, fromUrlSafeBase64, toUrlSafeBase64 } from './hash.node';
|
|
2
|
+
|
|
3
|
+
describe('Hash utilities', () => {
|
|
4
|
+
describe('sha256', () => {
|
|
5
|
+
it('should hash a simple string', () => {
|
|
6
|
+
const input = 'hello world';
|
|
7
|
+
const hash = sha256(input);
|
|
8
|
+
|
|
9
|
+
// Verify it's URL-safe (no +, /, or =)
|
|
10
|
+
expect(hash).not.toContain('+');
|
|
11
|
+
expect(hash).not.toContain('/');
|
|
12
|
+
expect(hash).not.toContain('=');
|
|
13
|
+
|
|
14
|
+
// Verify consistent output
|
|
15
|
+
const hash2 = sha256(input);
|
|
16
|
+
expect(hash).toBe(hash2);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should produce correct hash for known input', () => {
|
|
20
|
+
const input = 'hello world';
|
|
21
|
+
const expectedHash = 'uU0nuZNNPgilLlLX2n2r-sSE7-N6U4DukIj3rOLvzek';
|
|
22
|
+
const hash = sha256(input);
|
|
23
|
+
expect(hash).toBe(expectedHash);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should handle empty string', () => {
|
|
27
|
+
const hash = sha256('');
|
|
28
|
+
expect(hash).toBeTruthy();
|
|
29
|
+
expect(typeof hash).toBe('string');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should handle unicode characters', () => {
|
|
33
|
+
const input = '你好世界 🌍';
|
|
34
|
+
const hash = sha256(input);
|
|
35
|
+
expect(hash).toBeTruthy();
|
|
36
|
+
expect(typeof hash).toBe('string');
|
|
37
|
+
|
|
38
|
+
// Verify consistency
|
|
39
|
+
const hash2 = sha256(input);
|
|
40
|
+
expect(hash).toBe(hash2);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should handle Buffer input', () => {
|
|
44
|
+
const data = Buffer.from('hello world');
|
|
45
|
+
const hash = sha256(data);
|
|
46
|
+
|
|
47
|
+
// Should produce same hash as string input
|
|
48
|
+
const stringHash = sha256('hello world');
|
|
49
|
+
expect(hash).toBe(stringHash);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('should produce different hashes for different inputs', () => {
|
|
53
|
+
const hash1 = sha256('hello');
|
|
54
|
+
const hash2 = sha256('world');
|
|
55
|
+
expect(hash1).not.toBe(hash2);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should produce 43-character URL-safe base64 string', () => {
|
|
59
|
+
const hash = sha256('test');
|
|
60
|
+
// SHA-256 produces 256 bits = 32 bytes
|
|
61
|
+
// Base64 encoding: 32 bytes * 4/3 = 42.67, rounded up = 43 chars (without padding)
|
|
62
|
+
expect(hash.length).toBe(43);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('verify', () => {
|
|
67
|
+
it('should verify correct hash', () => {
|
|
68
|
+
const content = 'hello world';
|
|
69
|
+
const hash = sha256(content);
|
|
70
|
+
const isValid = verify(content, hash);
|
|
71
|
+
expect(isValid).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should reject incorrect hash', () => {
|
|
75
|
+
const content = 'hello world';
|
|
76
|
+
const wrongHash = 'incorrect_hash_value_here_1234567890';
|
|
77
|
+
const isValid = verify(content, wrongHash);
|
|
78
|
+
expect(isValid).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should reject hash for different content', () => {
|
|
82
|
+
const content1 = 'hello world';
|
|
83
|
+
const content2 = 'goodbye world';
|
|
84
|
+
const hash1 = sha256(content1);
|
|
85
|
+
const isValid = verify(content2, hash1);
|
|
86
|
+
expect(isValid).toBe(false);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should work with Buffer', () => {
|
|
90
|
+
const data = Buffer.from('test data');
|
|
91
|
+
const hash = sha256(data);
|
|
92
|
+
const isValid = verify(data, hash);
|
|
93
|
+
expect(isValid).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('fromUrlSafeBase64', () => {
|
|
98
|
+
it('should convert URL-safe base64 to standard base64', () => {
|
|
99
|
+
// Use a URL-safe string that contains both - and _ characters
|
|
100
|
+
const urlSafe = 'abc-def_ghi';
|
|
101
|
+
const standard = fromUrlSafeBase64(urlSafe);
|
|
102
|
+
|
|
103
|
+
// Should replace - with + and _ with /
|
|
104
|
+
expect(standard).toContain('+');
|
|
105
|
+
expect(standard).toContain('/');
|
|
106
|
+
// Should add padding
|
|
107
|
+
expect(standard.endsWith('=')).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should add correct padding', () => {
|
|
111
|
+
// Test different padding scenarios
|
|
112
|
+
const testCases = [
|
|
113
|
+
{ input: 'abc', expectedPadding: 1 },
|
|
114
|
+
{ input: 'abcd', expectedPadding: 0 },
|
|
115
|
+
{ input: 'abcde', expectedPadding: 3 },
|
|
116
|
+
{ input: 'abcdef', expectedPadding: 2 },
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
testCases.forEach(({ input, expectedPadding }) => {
|
|
120
|
+
const result = fromUrlSafeBase64(input);
|
|
121
|
+
const paddingCount = (result.match(/=/g) || []).length;
|
|
122
|
+
expect(paddingCount).toBe(expectedPadding);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should handle strings without special characters', () => {
|
|
127
|
+
const input = 'abcdefghijklmnop';
|
|
128
|
+
const result = fromUrlSafeBase64(input);
|
|
129
|
+
expect(result).toBeTruthy();
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('toUrlSafeBase64', () => {
|
|
134
|
+
it('should convert standard base64 to URL-safe', () => {
|
|
135
|
+
const standard = 'uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=';
|
|
136
|
+
const urlSafe = toUrlSafeBase64(standard);
|
|
137
|
+
|
|
138
|
+
// Should not contain standard base64 special characters
|
|
139
|
+
expect(urlSafe).not.toContain('+');
|
|
140
|
+
expect(urlSafe).not.toContain('/');
|
|
141
|
+
expect(urlSafe).not.toContain('=');
|
|
142
|
+
|
|
143
|
+
// Should contain URL-safe replacements
|
|
144
|
+
expect(urlSafe).toContain('-');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should remove padding', () => {
|
|
148
|
+
const withPadding = 'abc=';
|
|
149
|
+
const result = toUrlSafeBase64(withPadding);
|
|
150
|
+
expect(result).not.toContain('=');
|
|
151
|
+
expect(result).toBe('abc');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('should be reversible with fromUrlSafeBase64', () => {
|
|
155
|
+
// Start with a standard base64 string with special chars
|
|
156
|
+
const original = 'test+data/with==';
|
|
157
|
+
const urlSafe = toUrlSafeBase64(original);
|
|
158
|
+
const restored = fromUrlSafeBase64(urlSafe);
|
|
159
|
+
|
|
160
|
+
// Should restore to equivalent base64 (padding might differ slightly)
|
|
161
|
+
expect(restored.replace(/=+$/, '')).toBe(original.replace(/=+$/, ''));
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe('Round-trip conversions', () => {
|
|
166
|
+
it('should maintain hash integrity through URL-safe conversion', () => {
|
|
167
|
+
const content = 'test content for hashing';
|
|
168
|
+
const hash = sha256(content);
|
|
169
|
+
|
|
170
|
+
// Convert to standard base64 and back
|
|
171
|
+
const standard = fromUrlSafeBase64(hash);
|
|
172
|
+
const backToUrlSafe = toUrlSafeBase64(standard);
|
|
173
|
+
|
|
174
|
+
expect(backToUrlSafe).toBe(hash);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('should verify hash after conversion', () => {
|
|
178
|
+
const content = 'verification test';
|
|
179
|
+
const hash = sha256(content);
|
|
180
|
+
|
|
181
|
+
// Convert and back
|
|
182
|
+
const standard = fromUrlSafeBase64(hash);
|
|
183
|
+
const urlSafe = toUrlSafeBase64(standard);
|
|
184
|
+
|
|
185
|
+
// Should still verify
|
|
186
|
+
const isValid = verify(content, urlSafe);
|
|
187
|
+
expect(isValid).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe('Edge cases', () => {
|
|
192
|
+
it('should handle very long strings', () => {
|
|
193
|
+
const longString = 'a'.repeat(10000);
|
|
194
|
+
const hash = sha256(longString);
|
|
195
|
+
expect(hash).toBeTruthy();
|
|
196
|
+
expect(hash.length).toBe(43);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should handle special characters', () => {
|
|
200
|
+
const special = '!@#$%^&*()_+-=[]{}|;:,.<>?';
|
|
201
|
+
const hash = sha256(special);
|
|
202
|
+
expect(hash).toBeTruthy();
|
|
203
|
+
|
|
204
|
+
const isValid = verify(special, hash);
|
|
205
|
+
expect(isValid).toBe(true);
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should handle newlines and whitespace', () => {
|
|
209
|
+
const withNewlines = 'line1\nline2\r\nline3\ttab';
|
|
210
|
+
const hash = sha256(withNewlines);
|
|
211
|
+
expect(hash).toBeTruthy();
|
|
212
|
+
|
|
213
|
+
const isValid = verify(withNewlines, hash);
|
|
214
|
+
expect(isValid).toBe(true);
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseRating,
|
|
3
|
+
parseStatement,
|
|
4
|
+
parseOrganisationVerification,
|
|
5
|
+
parsePDFSigning,
|
|
6
|
+
parsePersonVerification,
|
|
7
|
+
parseDisputeAuthenticity,
|
|
8
|
+
parseDisputeContent,
|
|
9
|
+
parseVote,
|
|
10
|
+
parsePoll,
|
|
11
|
+
parseQuotation,
|
|
12
|
+
parseBounty,
|
|
13
|
+
parseBoycott,
|
|
14
|
+
parseObservation,
|
|
15
|
+
parseResponseContent,
|
|
16
|
+
buildResponseContent,
|
|
17
|
+
buildRating,
|
|
18
|
+
buildStatement,
|
|
19
|
+
buildBounty,
|
|
20
|
+
buildDisputeAuthenticityContent,
|
|
21
|
+
buildDisputeContentContent,
|
|
22
|
+
buildPDFSigningContent,
|
|
23
|
+
buildPersonVerificationContent,
|
|
24
|
+
buildPollContent,
|
|
25
|
+
buildQuotationContent,
|
|
26
|
+
buildVoteContent,
|
|
27
|
+
buildOrganisationVerificationContent,
|
|
28
|
+
buildBoycott,
|
|
29
|
+
buildObservation,
|
|
30
|
+
} from './index'
|
|
31
|
+
|
|
32
|
+
const randomUnicodeString = () =>
|
|
33
|
+
Array.from({ length: 20 }, () =>
|
|
34
|
+
String.fromCharCode(Math.floor(Math.random() * 65536))
|
|
35
|
+
)
|
|
36
|
+
.join('')
|
|
37
|
+
.replace(/[\n;>=<"''\\]/g, '')
|
|
38
|
+
|
|
39
|
+
test('parse statement', () => {
|
|
40
|
+
const statement = `Publishing domain: localhost
|
|
41
|
+
Author: chris
|
|
42
|
+
Time: Tue, 18 Apr 2023 18:20:26 GMT
|
|
43
|
+
Tags: hashtag1, hashtag2
|
|
44
|
+
Format version: 4
|
|
45
|
+
Statement content: hi
|
|
46
|
+
`
|
|
47
|
+
const parsedStatement = parseStatement({ statement })
|
|
48
|
+
expect(parsedStatement.content).toBe(`hi
|
|
49
|
+
`)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('statement build & parse function compatibility: input=parse(build(input))', () => {
|
|
53
|
+
const [domain, author, representative, content, supersededStatement] =
|
|
54
|
+
Array.from({ length: 5 }, randomUnicodeString)
|
|
55
|
+
const tags = Array.from({ length: 4 }, randomUnicodeString)
|
|
56
|
+
const contentWithTrailingNewline =
|
|
57
|
+
content + (content.match(/\n$/) ? '' : '\n')
|
|
58
|
+
const time = new Date('Sun, 04 Sep 2022 14:48:50 GMT')
|
|
59
|
+
const statementContent = buildStatement({
|
|
60
|
+
domain,
|
|
61
|
+
author,
|
|
62
|
+
time,
|
|
63
|
+
content: contentWithTrailingNewline,
|
|
64
|
+
representative,
|
|
65
|
+
supersededStatement,
|
|
66
|
+
tags,
|
|
67
|
+
})
|
|
68
|
+
const parsedStatement = parseStatement({ statement: statementContent })
|
|
69
|
+
expect(parsedStatement.domain).toBe(domain)
|
|
70
|
+
expect(parsedStatement.author).toBe(author)
|
|
71
|
+
expect(parsedStatement.time?.toUTCString()).toBe(time.toUTCString())
|
|
72
|
+
expect(parsedStatement.content).toBe(contentWithTrailingNewline)
|
|
73
|
+
expect(parsedStatement.representative).toBe(representative)
|
|
74
|
+
expect(parsedStatement.supersededStatement).toBe(supersededStatement)
|
|
75
|
+
expect(parsedStatement.tags?.sort()).toStrictEqual(tags.sort())
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('parse quotation', () => {
|
|
79
|
+
let quotation = `Publishing domain: rixdata.net
|
|
80
|
+
Author: Example Inc.
|
|
81
|
+
Time: Sun, 04 Sep 2022 14:48:50 GMT
|
|
82
|
+
Format version: 4
|
|
83
|
+
Statement content:
|
|
84
|
+
Type: Quotation
|
|
85
|
+
Original author: XYZ Company Inc.
|
|
86
|
+
Author verification: eXoVsm2CdF5Ri-SEAr33RNkG3DBuehvFoDBQ_pO9CXE
|
|
87
|
+
Original publication time: Sun, 04 Sep 2022 14:48:50 GMT
|
|
88
|
+
Source: https://www.facebook.com/companyxzy/posts/XXXX
|
|
89
|
+
Picture proof: 5HKiyQXGV4xavq-Nn9RXi_ndUH-2BEux3ccFIjaSk_8
|
|
90
|
+
Confidence: 0.9
|
|
91
|
+
Quotation: we give example.com a 2/5 star rating
|
|
92
|
+
Paraphrased statement:
|
|
93
|
+
Type: Rating
|
|
94
|
+
Organisation name: example
|
|
95
|
+
Organisation domain: example.com
|
|
96
|
+
Our rating: 2/5 Stars
|
|
97
|
+
`
|
|
98
|
+
const parsedStatement = parseStatement({ statement: quotation })
|
|
99
|
+
const parsedQuotation = parseQuotation(parsedStatement.content)
|
|
100
|
+
const type = parsedQuotation.type
|
|
101
|
+
expect(type).toBe('rating')
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('quotation build & parse function compatibility: input=parse(build(input))', () => {
|
|
105
|
+
const [originalAuthor, source, picture, quotation, paraphrasedStatement] =
|
|
106
|
+
Array.from({ length: 6 }, randomUnicodeString)
|
|
107
|
+
const authorVerification = 'yXoVsm2CdF5Ri-SEAr33RNkG3DBuehvFoDBQ_pO9CXE'
|
|
108
|
+
const originalTime = 'Sun, 04 Sep 2022 14:48:50 GMT'
|
|
109
|
+
const confidence = '' + Math.random()
|
|
110
|
+
const quotationContent = buildQuotationContent({
|
|
111
|
+
originalAuthor,
|
|
112
|
+
authorVerification,
|
|
113
|
+
originalTime,
|
|
114
|
+
source,
|
|
115
|
+
picture,
|
|
116
|
+
confidence,
|
|
117
|
+
quotation,
|
|
118
|
+
paraphrasedStatement,
|
|
119
|
+
})
|
|
120
|
+
const parsedQuotation = parseQuotation(quotationContent)
|
|
121
|
+
expect(parsedQuotation.originalAuthor).toBe(originalAuthor)
|
|
122
|
+
expect(parsedQuotation.originalTime).toBe(originalTime)
|
|
123
|
+
expect(parsedQuotation.source).toBe(source)
|
|
124
|
+
expect(parsedQuotation.picture).toBe(picture)
|
|
125
|
+
expect(parsedQuotation.confidence).toBe(confidence)
|
|
126
|
+
expect(parsedQuotation.quotation).toBe(quotation)
|
|
127
|
+
expect(parsedQuotation.paraphrasedStatement?.replace(/\n$/, '')).toBe(
|
|
128
|
+
paraphrasedStatement
|
|
129
|
+
)
|
|
130
|
+
expect(parsedQuotation.authorVerification).toBe(authorVerification)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('parse organisation verification', () => {
|
|
134
|
+
let organisationVerification = `Publishing domain: rixdata.net
|
|
135
|
+
Author: Example Inc.
|
|
136
|
+
Time: Sun, 04 Sep 2022 14:48:50 GMT
|
|
137
|
+
Format version: 4
|
|
138
|
+
Statement content:
|
|
139
|
+
Type: Organisation verification
|
|
140
|
+
Description: We verified the following information about an organisation.
|
|
141
|
+
Name: Walmart Inc.
|
|
142
|
+
Country: United States of America
|
|
143
|
+
Legal entity: corporation
|
|
144
|
+
Owner of the domain: walmart.com
|
|
145
|
+
Province or state: Arkansas
|
|
146
|
+
City: Bentonville
|
|
147
|
+
`
|
|
148
|
+
const parsedStatement = parseStatement({
|
|
149
|
+
statement: organisationVerification,
|
|
150
|
+
})
|
|
151
|
+
const parsedOVerification = parseOrganisationVerification(
|
|
152
|
+
parsedStatement.content
|
|
153
|
+
)
|
|
154
|
+
const name = parsedOVerification.name
|
|
155
|
+
expect(name).toBe('Walmart Inc.')
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('organisation verification build & parse function compatibility: input=parse(build(input))', () => {
|
|
159
|
+
const [
|
|
160
|
+
name,
|
|
161
|
+
englishName,
|
|
162
|
+
city,
|
|
163
|
+
domain,
|
|
164
|
+
foreignDomain,
|
|
165
|
+
serialNumber,
|
|
166
|
+
reliabilityPolicy,
|
|
167
|
+
pictureHash,
|
|
168
|
+
] = Array.from({ length: 8 }, randomUnicodeString)
|
|
169
|
+
const country = 'Germany'
|
|
170
|
+
const province = 'Bayern'
|
|
171
|
+
const legalForm = 'corporation'
|
|
172
|
+
const employeeCount = '100-1000'
|
|
173
|
+
const confidence = 0.8
|
|
174
|
+
const verificationContent = buildOrganisationVerificationContent({
|
|
175
|
+
name,
|
|
176
|
+
englishName,
|
|
177
|
+
country,
|
|
178
|
+
city,
|
|
179
|
+
province,
|
|
180
|
+
legalForm,
|
|
181
|
+
domain,
|
|
182
|
+
pictureHash,
|
|
183
|
+
foreignDomain,
|
|
184
|
+
serialNumber,
|
|
185
|
+
confidence,
|
|
186
|
+
reliabilityPolicy,
|
|
187
|
+
employeeCount,
|
|
188
|
+
})
|
|
189
|
+
const parsedVerification =
|
|
190
|
+
parseOrganisationVerification(verificationContent)
|
|
191
|
+
expect(parsedVerification.name).toBe(name)
|
|
192
|
+
expect(parsedVerification.englishName).toBe(englishName)
|
|
193
|
+
expect(parsedVerification.country).toBe(country)
|
|
194
|
+
expect(parsedVerification.city).toBe(city)
|
|
195
|
+
expect(parsedVerification.province).toBe(province)
|
|
196
|
+
expect(parsedVerification.legalForm).toBe(legalForm)
|
|
197
|
+
expect(parsedVerification.domain).toBe(domain)
|
|
198
|
+
expect(parsedVerification.foreignDomain).toBe(foreignDomain)
|
|
199
|
+
expect(parsedVerification.serialNumber).toBe(serialNumber)
|
|
200
|
+
expect(parsedVerification.confidence).toBe(confidence)
|
|
201
|
+
expect(parsedVerification.pictureHash).toBe(pictureHash)
|
|
202
|
+
expect(parsedVerification.reliabilityPolicy).toBe(reliabilityPolicy)
|
|
203
|
+
expect(parsedVerification.employeeCount).toBe(employeeCount)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
test('parse person verification', () => {
|
|
207
|
+
let personVerification = `Publishing domain: rixdata.net
|
|
208
|
+
Author: Example Inc.
|
|
209
|
+
Time: Sun, 04 Sep 2022 14:48:50 GMT
|
|
210
|
+
Format version: 4
|
|
211
|
+
Statement content:
|
|
212
|
+
Type: Person verification
|
|
213
|
+
Description: We verified the following information about a person.
|
|
214
|
+
Name: Barack Hossein Obama II
|
|
215
|
+
Date of birth: 4 Aug 1961
|
|
216
|
+
City of birth: Honolulu
|
|
217
|
+
Country of birth: United States of America
|
|
218
|
+
Owner of the domain: barackobama.com
|
|
219
|
+
`
|
|
220
|
+
const parsedStatement = parseStatement({ statement: personVerification })
|
|
221
|
+
const parsedPVerification = parsePersonVerification(parsedStatement.content)
|
|
222
|
+
const name = parsedPVerification.name
|
|
223
|
+
expect(name).toBe('Barack Hossein Obama II')
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
test('person verification build & parse function compatibility: input=parse(build(input))', () => {
|
|
227
|
+
const [
|
|
228
|
+
name,
|
|
229
|
+
ownDomain,
|
|
230
|
+
foreignDomain,
|
|
231
|
+
jobTitle,
|
|
232
|
+
employer,
|
|
233
|
+
verificationMethod,
|
|
234
|
+
picture,
|
|
235
|
+
reliabilityPolicy,
|
|
236
|
+
] = Array.from({ length: 12 }, randomUnicodeString)
|
|
237
|
+
const countryOfBirth = 'Germany'
|
|
238
|
+
const cityOfBirth = 'Berlin'
|
|
239
|
+
const confidence = Math.random()
|
|
240
|
+
const dateOfBirth = new Date(0)
|
|
241
|
+
const personVerificationContent = buildPersonVerificationContent({
|
|
242
|
+
name,
|
|
243
|
+
countryOfBirth,
|
|
244
|
+
cityOfBirth,
|
|
245
|
+
ownDomain,
|
|
246
|
+
foreignDomain,
|
|
247
|
+
dateOfBirth,
|
|
248
|
+
jobTitle,
|
|
249
|
+
employer,
|
|
250
|
+
verificationMethod,
|
|
251
|
+
confidence,
|
|
252
|
+
picture,
|
|
253
|
+
reliabilityPolicy,
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
const parsedVerification = parsePersonVerification(
|
|
257
|
+
personVerificationContent
|
|
258
|
+
)
|
|
259
|
+
expect(parsedVerification.name).toBe(name)
|
|
260
|
+
expect(parsedVerification.ownDomain).toBe(ownDomain)
|
|
261
|
+
expect(parsedVerification.foreignDomain).toBe(foreignDomain)
|
|
262
|
+
expect(parsedVerification.dateOfBirth.toUTCString()).toBe(
|
|
263
|
+
dateOfBirth.toUTCString()
|
|
264
|
+
)
|
|
265
|
+
expect(parsedVerification.jobTitle).toBe(jobTitle)
|
|
266
|
+
expect(parsedVerification.employer).toBe(employer)
|
|
267
|
+
expect(parsedVerification.verificationMethod).toBe(verificationMethod)
|
|
268
|
+
expect(parsedVerification.confidence).toBe(confidence)
|
|
269
|
+
expect(parsedVerification.picture).toBe(picture)
|
|
270
|
+
expect(parsedVerification.reliabilityPolicy).toBe(reliabilityPolicy)
|
|
271
|
+
expect(parsedVerification.countryOfBirth).toBe(countryOfBirth)
|
|
272
|
+
expect(parsedVerification.cityOfBirth).toBe(cityOfBirth)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
test('parse rating', () => {
|
|
276
|
+
let rating = `Publishing domain: localhost
|
|
277
|
+
Author: chris
|
|
278
|
+
Time: Tue, 18 Apr 2023 18:20:26 GMT
|
|
279
|
+
Format version: 4
|
|
280
|
+
Statement content:
|
|
281
|
+
Type: Rating
|
|
282
|
+
Subject name: AMBOSS GmbH
|
|
283
|
+
URL that identifies the subject: amboss.com
|
|
284
|
+
Rated quality: AI safety
|
|
285
|
+
Our rating: 5/5 Stars
|
|
286
|
+
`
|
|
287
|
+
const parsedStatement = parseStatement({ statement: rating })
|
|
288
|
+
const parsedRating = parseRating(parsedStatement.content)
|
|
289
|
+
const ratingNumber = parsedRating.rating
|
|
290
|
+
expect(ratingNumber).toBe(5)
|
|
291
|
+
const subjectName = parsedRating.subjectName
|
|
292
|
+
expect(subjectName).toBe('AMBOSS GmbH')
|
|
293
|
+
const subjectReference = parsedRating.subjectReference
|
|
294
|
+
expect(subjectReference).toBe('amboss.com')
|
|
295
|
+
const quality = parsedRating.quality
|
|
296
|
+
expect(quality).toBe('AI safety')
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
test('rating build & parse function compatibility: input=parse(build(input))', () => {
|
|
300
|
+
const [subjectName, subjectReference, comment, quality] = Array.from(
|
|
301
|
+
{ length: 4 },
|
|
302
|
+
randomUnicodeString
|
|
303
|
+
)
|
|
304
|
+
const rating = Math.ceil(Math.random() * 5)
|
|
305
|
+
const ratingContent = buildRating({ subjectName, subjectReference, rating, comment, quality })
|
|
306
|
+
const parsedRating = parseRating(ratingContent)
|
|
307
|
+
expect(parsedRating.subjectName).toBe(subjectName)
|
|
308
|
+
expect(parsedRating.subjectReference).toBe(subjectReference)
|
|
309
|
+
expect(parsedRating.quality).toBe(quality)
|
|
310
|
+
expect(parsedRating.rating).toBe(rating)
|
|
311
|
+
expect(parsedRating.comment).toBe(comment)
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
test('parse poll v4', () => {
|
|
315
|
+
let poll = `Publishing domain: rixdata.net
|
|
316
|
+
Author: Example Inc.
|
|
317
|
+
Time: Thu, 17 Nov 2022 13:38:20 GMT
|
|
318
|
+
Format version: 4
|
|
319
|
+
Statement content:
|
|
320
|
+
Type: Poll
|
|
321
|
+
The poll outcome is finalized when the following nodes agree: rixdata.net
|
|
322
|
+
Voting deadline: Thu, 01 Dec 2022 13:38:26 GMT
|
|
323
|
+
Poll: Should the UK join the EU
|
|
324
|
+
Option 1: Yes
|
|
325
|
+
Option 2: No
|
|
326
|
+
Who can vote:
|
|
327
|
+
Description: All universities with a ROR ID
|
|
328
|
+
Legal form scope: corporation
|
|
329
|
+
All entities with the following property: ROR ID
|
|
330
|
+
As observed by: Rix Data NL B.V.@rixdata.net
|
|
331
|
+
Link to query defining who can vote: https://stated.rixdata.net/?search_query=%09Observed%20property:%20ROR%20ID%0A%09&domain=rixdata.net&author=Rix%20Data%20NL%20B.V.
|
|
332
|
+
`
|
|
333
|
+
const parsedStatement = parseStatement({ statement: poll })
|
|
334
|
+
const parsedPoll = parsePoll(parsedStatement.content)
|
|
335
|
+
const pollTitle = parsedPoll.poll
|
|
336
|
+
expect(pollTitle).toBe('Should the UK join the EU')
|
|
337
|
+
expect(parsedPoll.options[0]).toBe('Yes')
|
|
338
|
+
expect(parsedPoll.options[1]).toBe('No')
|
|
339
|
+
expect(parsedPoll.deadline?.toUTCString()).toBe(
|
|
340
|
+
'Thu, 01 Dec 2022 13:38:26 GMT'
|
|
341
|
+
)
|
|
342
|
+
expect(parsedPoll.scopeDescription).toBe('All universities with a ROR ID')
|
|
343
|
+
expect(parsedPoll.legalEntity).toBe('corporation')
|
|
344
|
+
expect(parsedPoll.requiredProperty).toBe('ROR ID')
|
|
345
|
+
expect(parsedPoll.requiredPropertyObserver).toBe(
|
|
346
|
+
'Rix Data NL B.V.@rixdata.net'
|
|
347
|
+
)
|
|
348
|
+
expect(parsedPoll.scopeQueryLink).toBe(
|
|
349
|
+
'https://stated.rixdata.net/?search_query=%09Observed%20property:%20ROR%20ID%0A%09&domain=rixdata.net&author=Rix%20Data%20NL%20B.V.'
|
|
350
|
+
)
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
test('poll build & parse function compatibility: input=parse(build(input))', () => {
|
|
354
|
+
const [country, city, legalEntity, judges, poll, scopeDescription] =
|
|
355
|
+
Array.from({ length: 6 }, randomUnicodeString)
|
|
356
|
+
const options = Array.from({ length: 2 }, randomUnicodeString)
|
|
357
|
+
const domainScope = ['rixdata.net']
|
|
358
|
+
const deadline = new Date('Thu, 01 Dec 2022 13:38:26 GMT')
|
|
359
|
+
const pollContent = buildPollContent({
|
|
360
|
+
country,
|
|
361
|
+
city,
|
|
362
|
+
legalEntity,
|
|
363
|
+
domainScope,
|
|
364
|
+
judges,
|
|
365
|
+
deadline,
|
|
366
|
+
poll,
|
|
367
|
+
options,
|
|
368
|
+
scopeDescription,
|
|
369
|
+
})
|
|
370
|
+
const parsedPoll = parsePoll(pollContent)
|
|
371
|
+
expect(parsedPoll.poll).toBe(poll)
|
|
372
|
+
expect(parsedPoll.country).toBe(country)
|
|
373
|
+
expect(parsedPoll.legalEntity).toBe(legalEntity)
|
|
374
|
+
expect(parsedPoll.judges).toBe(judges)
|
|
375
|
+
expect(parsedPoll.deadline?.toUTCString()).toBe(deadline.toUTCString())
|
|
376
|
+
expect(parsedPoll.options[0]).toEqual(options[0])
|
|
377
|
+
expect(parsedPoll.options[1]).toEqual(options[1])
|
|
378
|
+
})
|