1 | 'use strict';
|
2 |
|
3 | var chai = chai || require('chai');
|
4 | var bitcore = require('..');
|
5 | var expect = chai.expect;
|
6 | var Networks = bitcore.Networks;
|
7 | var should = chai.should();
|
8 | var URI = bitcore.URI;
|
9 |
|
10 | describe('URI', function() {
|
11 |
|
12 |
|
13 |
|
14 | it('parses uri strings correctly (test vector)', function() {
|
15 | var uri;
|
16 |
|
17 | URI.parse.bind(URI, 'badURI').should.throw(TypeError);
|
18 |
|
19 | uri = URI.parse('bitcoin:');
|
20 | expect(uri.address).to.be.equal(undefined);
|
21 | expect(uri.amount).to.be.equal(undefined);
|
22 | expect(uri.otherParam).to.be.equal(undefined);
|
23 |
|
24 | uri = URI.parse('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
25 | uri.address.should.equal('1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
26 | expect(uri.amount).to.be.equal(undefined);
|
27 | expect(uri.otherParam).to.be.equal(undefined);
|
28 |
|
29 | uri = URI.parse('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=123.22');
|
30 | uri.address.should.equal('1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
31 | uri.amount.should.equal('123.22');
|
32 | expect(uri.otherParam).to.be.equal(undefined);
|
33 |
|
34 | uri = URI.parse('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=123.22' +
|
35 | '&other-param=something&req-extra=param');
|
36 | uri.address.should.equal('1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
37 | uri.amount.should.equal('123.22');
|
38 | uri['other-param'].should.equal('something');
|
39 | uri['req-extra'].should.equal('param');
|
40 | });
|
41 |
|
42 |
|
43 | it('URIs can be validated statically (test vector)', function() {
|
44 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj').should.equal(true);
|
45 | URI.isValid('bitcoin:mkYY5NRvikVBY1EPtaq9fAFgquesdjqECw').should.equal(true);
|
46 |
|
47 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2')
|
48 | .should.equal(true);
|
49 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2&other=param')
|
50 | .should.equal(true);
|
51 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2&req-other=param',
|
52 | ['req-other']).should.equal(true);
|
53 | URI.isValid('bitcoin:mmrqEBJxUCf42vdb3oozZtyz5mKr3Vb2Em?amount=0.1&' +
|
54 | 'r=https%3A%2F%2Ftest.bitpay.com%2Fi%2F6DKgf8cnJC388irbXk5hHu').should.equal(true);
|
55 |
|
56 | URI.isValid('bitcoin:').should.equal(false);
|
57 | URI.isValid('bitcoin:badUri').should.equal(false);
|
58 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfk?amount=bad').should.equal(false);
|
59 | URI.isValid('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfk?amount=1.2&req-other=param')
|
60 | .should.equal(false);
|
61 | URI.isValid('bitcoin:?r=https%3A%2F%2Ftest.bitpay.com%2Fi%2F6DKgf8cnJC388irbXk5hHu')
|
62 | .should.equal(false);
|
63 | });
|
64 |
|
65 | it('fails on creation with no params', function() {
|
66 | (function(){
|
67 | return new URI();
|
68 | }).should.throw(TypeError);
|
69 | });
|
70 |
|
71 | it('do not need new keyword', function() {
|
72 | var uri = URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
73 | uri.should.be.instanceof(URI);
|
74 | });
|
75 |
|
76 | describe('instantiation from bitcoin uri', function() {
|
77 |
|
78 | var uri;
|
79 |
|
80 | it('parses address', function() {
|
81 | uri = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
82 | uri.address.should.be.instanceof(bitcore.Address);
|
83 | uri.network.should.equal(Networks.livenet);
|
84 | });
|
85 |
|
86 | it('parses amount', function() {
|
87 | uri = URI.fromString('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=123.22');
|
88 | uri.address.toString().should.equal('1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
89 | uri.amount.should.equal(12322000000);
|
90 | expect(uri.otherParam).to.be.equal(undefined);
|
91 | });
|
92 |
|
93 | it('parses a testnet address', function() {
|
94 | uri = new URI('bitcoin:mkYY5NRvikVBY1EPtaq9fAFgquesdjqECw');
|
95 | uri.address.should.be.instanceof(bitcore.Address);
|
96 | uri.network.should.equal(Networks.testnet);
|
97 | });
|
98 |
|
99 | it('stores unknown parameters as "extras"', function() {
|
100 | uri = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2&other=param');
|
101 | uri.address.should.be.instanceof(bitcore.Address);
|
102 | expect(uri.other).to.be.equal(undefined);
|
103 | uri.extras.other.should.equal('param');
|
104 | });
|
105 |
|
106 | it('throws error when a required feature is not supported', function() {
|
107 | (function() {
|
108 | return new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2&other=param&req-required=param');
|
109 | }).should.throw(Error);
|
110 | });
|
111 |
|
112 | it('has no false negative when checking supported features', function() {
|
113 | uri = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.2&other=param&' +
|
114 | 'req-required=param', ['req-required']);
|
115 | uri.address.should.be.instanceof(bitcore.Address);
|
116 | uri.amount.should.equal(120000000);
|
117 | uri.extras.other.should.equal('param');
|
118 | uri.extras['req-required'].should.equal('param');
|
119 | });
|
120 | });
|
121 |
|
122 |
|
123 | it('should create instance from object', function() {
|
124 |
|
125 | var uri;
|
126 |
|
127 | uri = new URI({
|
128 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj'
|
129 | });
|
130 | uri.address.should.be.instanceof(bitcore.Address);
|
131 | uri.network.should.equal(Networks.livenet);
|
132 |
|
133 | uri = new URI({
|
134 | address: 'mkYY5NRvikVBY1EPtaq9fAFgquesdjqECw'
|
135 | });
|
136 | uri.address.should.be.instanceof(bitcore.Address);
|
137 | uri.network.should.equal(Networks.testnet);
|
138 |
|
139 | uri = new URI({
|
140 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
141 | amount: 120000000,
|
142 | other: 'param'
|
143 | });
|
144 | uri.address.should.be.instanceof(bitcore.Address);
|
145 | uri.amount.should.equal(120000000);
|
146 | expect(uri.other).to.be.equal(undefined);
|
147 | uri.extras.other.should.equal('param');
|
148 |
|
149 | (function() {
|
150 | return new URI({
|
151 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
152 | 'req-required': 'param'
|
153 | });
|
154 | }).should.throw(Error);
|
155 |
|
156 | uri = new URI({
|
157 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
158 | amount: 120000000,
|
159 | other: 'param',
|
160 | 'req-required': 'param'
|
161 | }, ['req-required']);
|
162 | uri.address.should.be.instanceof(bitcore.Address);
|
163 | uri.amount.should.equal(120000000);
|
164 | uri.extras.other.should.equal('param');
|
165 | uri.extras['req-required'].should.equal('param');
|
166 | });
|
167 |
|
168 | it('should support double slash scheme', function() {
|
169 | var uri = new URI('bitcoin://1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
170 | uri.address.toString().should.equal('1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
171 | });
|
172 |
|
173 | it('should input/output String', function() {
|
174 | var str = 'bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?' +
|
175 | 'message=Donation%20for%20project%20xyz&label=myLabel&other=xD';
|
176 | URI.fromString(str).toString().should.equal(str);
|
177 | });
|
178 |
|
179 | it('should input/output JSON', function() {
|
180 | var json = JSON.stringify({
|
181 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
182 | message: 'Donation for project xyz',
|
183 | label: 'myLabel',
|
184 | other: 'xD'
|
185 | });
|
186 | JSON.stringify(URI.fromObject(JSON.parse(json))).should.equal(json);
|
187 | });
|
188 |
|
189 | it('should support numeric amounts', function() {
|
190 | var uri = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=12.10001');
|
191 | expect(uri.amount).to.be.equal(1210001000);
|
192 | });
|
193 |
|
194 | it('should support extra arguments', function() {
|
195 | var uri = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?' +
|
196 | 'message=Donation%20for%20project%20xyz&label=myLabel&other=xD');
|
197 |
|
198 | should.exist(uri.message);
|
199 | uri.message.should.equal('Donation for project xyz');
|
200 |
|
201 | should.exist(uri.label);
|
202 | uri.label.should.equal('myLabel');
|
203 |
|
204 | should.exist(uri.extras.other);
|
205 | uri.extras.other.should.equal('xD');
|
206 | });
|
207 |
|
208 | it('should generate a valid URI', function() {
|
209 | new URI({
|
210 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
211 | }).toString().should.equal(
|
212 | 'bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj'
|
213 | );
|
214 |
|
215 | new URI({
|
216 | address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
|
217 | amount: 110001000,
|
218 | message: 'Hello World',
|
219 | something: 'else'
|
220 | }).toString().should.equal(
|
221 | 'bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj?amount=1.10001&message=Hello%20World&something=else'
|
222 | );
|
223 |
|
224 | });
|
225 |
|
226 | it('should be case insensitive to protocol', function() {
|
227 | var uri1 = new URI('bItcOin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
228 | var uri2 = new URI('bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj');
|
229 |
|
230 | uri1.address.toString().should.equal(uri2.address.toString());
|
231 | });
|
232 |
|
233 | it('writes correctly the "r" parameter on string serialization', function() {
|
234 | var originalString = 'bitcoin:mmrqEBJxUCf42vdb3oozZtyz5mKr3Vb2Em?amount=0.1&' +
|
235 | 'r=https%3A%2F%2Ftest.bitpay.com%2Fi%2F6DKgf8cnJC388irbXk5hHu';
|
236 | var uri = new URI(originalString);
|
237 | uri.toString().should.equal(originalString);
|
238 | });
|
239 |
|
240 | it('displays nicely on the console (#inspect)', function() {
|
241 | var uri = 'bitcoin:1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj';
|
242 | var instance = new URI(uri);
|
243 | instance.inspect().should.equal('<URI: ' + uri + '>');
|
244 | });
|
245 |
|
246 | it('fails early when fromString isn\'t provided a string', function() {
|
247 | expect(function() {
|
248 | return URI.fromString(1);
|
249 | }).to.throw();
|
250 | });
|
251 |
|
252 | it('fails early when fromJSON isn\'t provided a valid JSON string', function() {
|
253 | expect(function() {
|
254 | return URI.fromJSON('¹');
|
255 | }).to.throw();
|
256 | });
|
257 | });
|