Skip to content

Commit 68ce2c6

Browse files
committed
Improved MetadataHttp, added unit tests
1 parent cddeff4 commit 68ce2c6

File tree

2 files changed

+251
-63
lines changed

2 files changed

+251
-63
lines changed

src/infrastructure/MetadataHttp.ts

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { from as observableFrom, Observable, throwError } from 'rxjs';
18-
import { catchError, map } from 'rxjs/operators';
17+
import { Observable } from 'rxjs';
1918
import { MetadataDTO, MetadataRoutesApi } from 'symbol-openapi-typescript-node-client';
2019
import { Convert } from '../core/format/Convert';
2120
import { Address } from '../model/account/Address';
@@ -43,8 +42,7 @@ export class MetadataHttp extends Http implements MetadataRepository {
4342

4443
/**
4544
* Constructor
46-
* @param url
47-
* @param networkType
45+
* @param url the url.
4846
*/
4947
constructor(url: string) {
5048
super(url);
@@ -59,15 +57,12 @@ export class MetadataHttp extends Http implements MetadataRepository {
5957
* @returns Observable<Metadata[]>
6058
*/
6159
public getAccountMetadata(address: Address, queryParams?: QueryParams): Observable<Metadata[]> {
62-
return observableFrom(
60+
return this.call(
6361
this.metadataRoutesApi.getAccountMetadata(address.plain(),
64-
this.queryParams(queryParams).pageSize,
65-
this.queryParams(queryParams).id,
66-
this.queryParams(queryParams).ordering)).pipe(
67-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
68-
return this.buildMetadata(metadataEntry);
69-
})),
70-
catchError((error) => throwError(this.errorHandling(error))),
62+
this.queryParams(queryParams).pageSize,
63+
this.queryParams(queryParams).id,
64+
this.queryParams(queryParams).ordering),
65+
(body) => body.metadataEntries.map((metadataEntry) => this.buildMetadata(metadataEntry))
7166
);
7267
}
7368

@@ -78,12 +73,9 @@ export class MetadataHttp extends Http implements MetadataRepository {
7873
* @returns Observable<Metadata[]>
7974
*/
8075
getAccountMetadataByKey(address: Address, key: string): Observable<Metadata[]> {
81-
return observableFrom(
82-
this.metadataRoutesApi.getAccountMetadataByKey(address.plain(), key)).pipe(
83-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
84-
return this.buildMetadata(metadataEntry);
85-
})),
86-
catchError((error) => throwError(this.errorHandling(error))),
76+
return this.call(
77+
this.metadataRoutesApi.getAccountMetadataByKey(address.plain(), key),
78+
(body) => body.metadataEntries.map((metadataEntry) => this.buildMetadata(metadataEntry))
8779
);
8880
}
8981

@@ -95,10 +87,9 @@ export class MetadataHttp extends Http implements MetadataRepository {
9587
* @returns Observable<Metadata>
9688
*/
9789
getAccountMetadataByKeyAndSender(address: Address, key: string, publicKey: string): Observable<Metadata> {
98-
return observableFrom(
99-
this.metadataRoutesApi.getAccountMetadataByKeyAndSender(address.plain(), key, publicKey)).pipe(
100-
map(({body}) => this.buildMetadata(body)),
101-
catchError((error) => throwError(this.errorHandling(error))),
90+
return this.call(
91+
this.metadataRoutesApi.getAccountMetadataByKeyAndSender(address.plain(), key, publicKey),
92+
(body) => this.buildMetadata(body)
10293
);
10394
}
10495

@@ -109,15 +100,12 @@ export class MetadataHttp extends Http implements MetadataRepository {
109100
* @returns Observable<Metadata[]>
110101
*/
111102
getMosaicMetadata(mosaicId: MosaicId, queryParams?: QueryParams): Observable<Metadata[]> {
112-
return observableFrom(
103+
return this.call(
113104
this.metadataRoutesApi.getMosaicMetadata(mosaicId.toHex(),
114-
this.queryParams(queryParams).pageSize,
115-
this.queryParams(queryParams).id,
116-
this.queryParams(queryParams).ordering)).pipe(
117-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
118-
return this.buildMetadata(metadataEntry);
119-
})),
120-
catchError((error) => throwError(this.errorHandling(error))),
105+
this.queryParams(queryParams).pageSize,
106+
this.queryParams(queryParams).id,
107+
this.queryParams(queryParams).ordering),
108+
(body) => body.metadataEntries.map((metadataEntry) => this.buildMetadata(metadataEntry))
121109
);
122110
}
123111

@@ -128,12 +116,9 @@ export class MetadataHttp extends Http implements MetadataRepository {
128116
* @returns Observable<Metadata[]>
129117
*/
130118
getMosaicMetadataByKey(mosaicId: MosaicId, key: string): Observable<Metadata[]> {
131-
return observableFrom(
132-
this.metadataRoutesApi.getMosaicMetadataByKey(mosaicId.toHex(), key)).pipe(
133-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
134-
return this.buildMetadata(metadataEntry);
135-
})),
136-
catchError((error) => throwError(this.errorHandling(error))),
119+
return this.call(
120+
this.metadataRoutesApi.getMosaicMetadataByKey(mosaicId.toHex(), key),
121+
(body) => body.metadataEntries.map((metadataEntry) => this.buildMetadata(metadataEntry))
137122
);
138123
}
139124

@@ -145,10 +130,8 @@ export class MetadataHttp extends Http implements MetadataRepository {
145130
* @returns Observable<Metadata>
146131
*/
147132
getMosaicMetadataByKeyAndSender(mosaicId: MosaicId, key: string, publicKey: string): Observable<Metadata> {
148-
return observableFrom(
149-
this.metadataRoutesApi.getMosaicMetadataByKeyAndSender(mosaicId.toHex(), key, publicKey)).pipe(
150-
map(({body}) => this.buildMetadata(body)),
151-
catchError((error) => throwError(this.errorHandling(error))),
133+
return this.call(
134+
this.metadataRoutesApi.getMosaicMetadataByKeyAndSender(mosaicId.toHex(), key, publicKey), this.buildMetadata
152135
);
153136
}
154137

@@ -159,15 +142,11 @@ export class MetadataHttp extends Http implements MetadataRepository {
159142
* @returns Observable<Metadata[]>
160143
*/
161144
public getNamespaceMetadata(namespaceId: NamespaceId, queryParams?: QueryParams): Observable<Metadata[]> {
162-
return observableFrom(
145+
return this.call(
163146
this.metadataRoutesApi.getNamespaceMetadata(namespaceId.toHex(),
164-
this.queryParams(queryParams).pageSize,
165-
this.queryParams(queryParams).id,
166-
this.queryParams(queryParams).ordering)).pipe(
167-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
168-
return this.buildMetadata(metadataEntry);
169-
})),
170-
catchError((error) => throwError(this.errorHandling(error))),
147+
this.queryParams(queryParams).pageSize,
148+
this.queryParams(queryParams).id,
149+
this.queryParams(queryParams).ordering), body => body.metadataEntries.map(this.buildMetadata)
171150
);
172151
}
173152

@@ -178,12 +157,9 @@ export class MetadataHttp extends Http implements MetadataRepository {
178157
* @returns Observable<Metadata[]>
179158
*/
180159
public getNamespaceMetadataByKey(namespaceId: NamespaceId, key: string): Observable<Metadata[]> {
181-
return observableFrom(
182-
this.metadataRoutesApi.getNamespaceMetadataByKey(namespaceId.toHex(), key)).pipe(
183-
map(({body}) => body.metadataEntries.map((metadataEntry) => {
184-
return this.buildMetadata(metadataEntry);
185-
})),
186-
catchError((error) => throwError(this.errorHandling(error))),
160+
return this.call(
161+
this.metadataRoutesApi.getNamespaceMetadataByKey(namespaceId.toHex(), key),
162+
(body) => body.metadataEntries.map(this.buildMetadata)
187163
);
188164
}
189165

@@ -195,18 +171,14 @@ export class MetadataHttp extends Http implements MetadataRepository {
195171
* @returns Observable<Metadata>
196172
*/
197173
public getNamespaceMetadataByKeyAndSender(namespaceId: NamespaceId, key: string, publicKey: string): Observable<Metadata> {
198-
return observableFrom(
199-
this.metadataRoutesApi.getNamespaceMetadataByKeyAndSender(namespaceId.toHex(), key, publicKey)).pipe(
200-
map(({body}) => this.buildMetadata(body)),
201-
catchError((error) => throwError(this.errorHandling(error))),
202-
);
174+
return this.call(
175+
this.metadataRoutesApi.getNamespaceMetadataByKeyAndSender(namespaceId.toHex(), key, publicKey), this.buildMetadata);
203176
}
204177

205178
/**
206-
* Returns the mosaic metadata given a mosaic id.
207-
* @param namespaceId - Namespace identifier.
208-
* @param queryParams - Optional query parameters
209-
* @returns Observable<Metadata[]>
179+
* It maps MetadataDTO into a Metadata
180+
* @param metadata - the dto
181+
* @returns the model Metadata.
210182
*/
211183
private buildMetadata(metadata: MetadataDTO): Metadata {
212184
const metadataEntry = metadata.metadataEntry;
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
* Copyright 2020 NEM
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
import { expect } from 'chai';
17+
import * as http from 'http';
18+
import {
19+
MetadataDTO,
20+
MetadataEntriesDTO,
21+
MetadataEntryDTO,
22+
MetadataRoutesApi,
23+
MetadataTypeEnum,
24+
} from 'symbol-openapi-typescript-node-client';
25+
import { instance, mock, reset, when } from 'ts-mockito';
26+
import { DtoMapping } from '../../src/core/utils/DtoMapping';
27+
import { MetadataHttp } from '../../src/infrastructure/MetadataHttp';
28+
import { MetadataRepository } from '../../src/infrastructure/MetadataRepository';
29+
import { QueryParams } from '../../src/infrastructure/QueryParams';
30+
import { Address } from '../../src/model/account/Address';
31+
import { Metadata } from '../../src/model/metadata/Metadata';
32+
import { MetadataType } from '../../src/model/metadata/MetadataType';
33+
import { MosaicId } from '../../src/model/mosaic/MosaicId';
34+
import { NamespaceId } from '../../src/model/namespace/NamespaceId';
35+
36+
describe('MetadataHttp', () => {
37+
38+
const address = Address.createFromRawAddress('MCTVW23D2MN5VE4AQ4TZIDZENGNOZXPRPR72DYSX');
39+
const mosaicId = new MosaicId('941299B2B7E1291C');
40+
const namespaceId = new NamespaceId('some.address');
41+
42+
const metadataDTOMosaic = new MetadataDTO();
43+
metadataDTOMosaic.id = 'aaa';
44+
45+
const metadataEntryDtoMosaic = new MetadataEntryDTO();
46+
metadataEntryDtoMosaic.compositeHash = '1';
47+
metadataEntryDtoMosaic.metadataType = MetadataTypeEnum.NUMBER_1;
48+
metadataEntryDtoMosaic.scopedMetadataKey = '123451234512345A';
49+
metadataEntryDtoMosaic.senderPublicKey = 'aSenderPublicKey1';
50+
metadataEntryDtoMosaic.targetPublicKey = 'aTargetPublicKey1';
51+
metadataEntryDtoMosaic.value = 'value1';
52+
metadataEntryDtoMosaic.targetId = '941299B2B7E1291C' as any;
53+
metadataDTOMosaic.metadataEntry = metadataEntryDtoMosaic;
54+
55+
const metadataDTOAddress = new MetadataDTO();
56+
metadataDTOAddress.id = 'bbb';
57+
58+
const metadataEntryDtoAddress = new MetadataEntryDTO();
59+
metadataEntryDtoAddress.compositeHash = '2';
60+
metadataEntryDtoAddress.metadataType = MetadataTypeEnum.NUMBER_0;
61+
metadataEntryDtoAddress.scopedMetadataKey = '123451234512345B';
62+
metadataEntryDtoAddress.senderPublicKey = 'aSenderPublicKey2';
63+
metadataEntryDtoAddress.targetPublicKey = 'aTargetPublicKey2';
64+
metadataEntryDtoAddress.value = 'value1';
65+
metadataEntryDtoAddress.targetId = '941299B2B7E1291D' as any;
66+
metadataDTOAddress.metadataEntry = metadataEntryDtoAddress;
67+
68+
const metadataDTONamespace = new MetadataDTO();
69+
metadataDTONamespace.id = 'ccc';
70+
71+
const metadataEntryDtoNamespace = new MetadataEntryDTO();
72+
metadataEntryDtoNamespace.compositeHash = '3';
73+
metadataEntryDtoNamespace.metadataType = MetadataTypeEnum.NUMBER_2;
74+
metadataEntryDtoNamespace.scopedMetadataKey = '123451234512345C';
75+
metadataEntryDtoNamespace.senderPublicKey = 'aSenderPublicKey3';
76+
metadataEntryDtoNamespace.targetPublicKey = 'aTargetPublicKey3';
77+
metadataEntryDtoNamespace.value = 'value1';
78+
metadataEntryDtoNamespace.targetId = '941299B2B7E1291E' as any;
79+
metadataDTONamespace.metadataEntry = metadataEntryDtoNamespace;
80+
81+
const metadataEntriesDTO = new MetadataEntriesDTO();
82+
metadataEntriesDTO.metadataEntries = [metadataDTOMosaic, metadataDTOAddress, metadataDTONamespace];
83+
84+
const url = 'http://someHost';
85+
const response: http.IncomingMessage = mock();
86+
const metadataRoutesApi: MetadataRoutesApi = mock();
87+
const metadataRepository: MetadataRepository = DtoMapping.assign(
88+
new MetadataHttp(url), {metadataRoutesApi: instance(metadataRoutesApi)});
89+
before(() => {
90+
reset(response);
91+
reset(metadataRoutesApi);
92+
});
93+
94+
function assertMetadataInfo(metadataInfo: Metadata, dto: MetadataDTO) {
95+
expect(metadataInfo).to.be.not.null;
96+
expect(metadataInfo.id).to.be.equals(dto.id);
97+
if (metadataInfo.metadataEntry.metadataType === MetadataType.Mosaic) {
98+
expect(metadataInfo.metadataEntry.targetId!.toHex()).to.be.equals(dto.metadataEntry.targetId);
99+
}
100+
if (metadataInfo.metadataEntry.metadataType === MetadataType.Account) {
101+
expect(metadataInfo.metadataEntry.targetId).to.be.undefined;
102+
}
103+
if (metadataInfo.metadataEntry.metadataType === MetadataType.Namespace) {
104+
expect(metadataInfo.metadataEntry.targetId!.toHex()).to.be.equals(dto.metadataEntry.targetId);
105+
}
106+
expect(metadataInfo.metadataEntry.targetPublicKey).to.be.equals(dto.metadataEntry.targetPublicKey);
107+
expect(metadataInfo.metadataEntry.scopedMetadataKey.toHex()).to.be.equals(dto.metadataEntry.scopedMetadataKey);
108+
expect(metadataInfo.metadataEntry.compositeHash).to.be.equals(dto.metadataEntry.compositeHash);
109+
}
110+
111+
it('getAccountMetadata', async () => {
112+
when(metadataRoutesApi.getAccountMetadata(address.plain(), 1, 'a', '-id')).thenReturn(Promise.resolve({
113+
response,
114+
body: metadataEntriesDTO,
115+
}));
116+
const metadatas = await metadataRepository.getAccountMetadata(address, new QueryParams({
117+
pageSize: 1,
118+
id: 'a',
119+
})).toPromise();
120+
expect(metadatas.length).to.be.equals(3);
121+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
122+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
123+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
124+
});
125+
126+
it('getAccountMetadataByKey', async () => {
127+
when(metadataRoutesApi.getAccountMetadataByKey(address.plain(), 'aaa')).thenReturn(Promise.resolve({
128+
response,
129+
body: metadataEntriesDTO,
130+
}));
131+
const metadatas = await metadataRepository.getAccountMetadataByKey(address, 'aaa').toPromise();
132+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
133+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
134+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
135+
});
136+
137+
it('getAccountMetadataByKeyAndSender', async () => {
138+
when(metadataRoutesApi.getAccountMetadataByKeyAndSender(address.plain(), 'aaa', 'sender')).thenReturn(Promise.resolve({
139+
response,
140+
body: metadataDTOMosaic,
141+
}));
142+
const metadata = await metadataRepository.getAccountMetadataByKeyAndSender(address, 'aaa', 'sender').toPromise();
143+
assertMetadataInfo(metadata, metadataDTOMosaic);
144+
});
145+
146+
it('getMosaicMetadata', async () => {
147+
when(metadataRoutesApi.getMosaicMetadata(mosaicId.toHex(), 1, 'a', '-id')).thenReturn(Promise.resolve({
148+
response,
149+
body: metadataEntriesDTO,
150+
}));
151+
const metadatas = await metadataRepository.getMosaicMetadata(mosaicId, new QueryParams({
152+
pageSize: 1,
153+
id: 'a',
154+
})).toPromise();
155+
expect(metadatas.length).to.be.equals(3);
156+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
157+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
158+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
159+
});
160+
161+
it('getMosaicMetadataByKey', async () => {
162+
when(metadataRoutesApi.getMosaicMetadataByKey(mosaicId.toHex(), 'aaa')).thenReturn(Promise.resolve({
163+
response,
164+
body: metadataEntriesDTO,
165+
}));
166+
const metadatas = await metadataRepository.getMosaicMetadataByKey(mosaicId, 'aaa').toPromise();
167+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
168+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
169+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
170+
});
171+
172+
it('getMosaicMetadataByKeyAndSender', async () => {
173+
when(metadataRoutesApi.getMosaicMetadataByKeyAndSender(mosaicId.toHex(), 'aaa', 'sender')).thenReturn(Promise.resolve({
174+
response,
175+
body: metadataDTOMosaic,
176+
}));
177+
const metadata = await metadataRepository.getMosaicMetadataByKeyAndSender(mosaicId, 'aaa', 'sender').toPromise();
178+
assertMetadataInfo(metadata, metadataDTOMosaic);
179+
});
180+
181+
it('getNamespaceMetadata', async () => {
182+
when(metadataRoutesApi.getNamespaceMetadata(namespaceId.toHex(), 2, 'a', '-id')).thenReturn(Promise.resolve({
183+
response,
184+
body: metadataEntriesDTO,
185+
}));
186+
const metadatas = await metadataRepository.getNamespaceMetadata(namespaceId, new QueryParams({
187+
pageSize: 2,
188+
id: 'a',
189+
})).toPromise();
190+
expect(metadatas.length).to.be.equals(3);
191+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
192+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
193+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
194+
});
195+
196+
it('getNamespaceMetadataByKey', async () => {
197+
when(metadataRoutesApi.getNamespaceMetadataByKey(namespaceId.toHex(), 'bbb')).thenReturn(Promise.resolve({
198+
response,
199+
body: metadataEntriesDTO,
200+
}));
201+
const metadatas = await metadataRepository.getNamespaceMetadataByKey(namespaceId, 'bbb').toPromise();
202+
assertMetadataInfo(metadatas[0], metadataDTOMosaic);
203+
assertMetadataInfo(metadatas[1], metadataDTOAddress);
204+
assertMetadataInfo(metadatas[2], metadataDTONamespace);
205+
});
206+
207+
it('getNamespaceMetadataByKeyAndSender', async () => {
208+
when(metadataRoutesApi.getNamespaceMetadataByKeyAndSender(namespaceId.toHex(), 'cccc', 'sender1')).thenReturn(Promise.resolve({
209+
response,
210+
body: metadataDTOMosaic,
211+
}));
212+
const metadata = await metadataRepository.getNamespaceMetadataByKeyAndSender(namespaceId, 'cccc', 'sender1').toPromise();
213+
assertMetadataInfo(metadata, metadataDTOMosaic);
214+
});
215+
216+
});

0 commit comments

Comments
 (0)