Skip to content

Commit

Permalink
Merge fd9813b into 6ff7df2
Browse files Browse the repository at this point in the history
  • Loading branch information
fboucquez committed Oct 26, 2020
2 parents 6ff7df2 + fd9813b commit a6b662e
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 92 deletions.
64 changes: 25 additions & 39 deletions src/infrastructure/NamespaceHttp.ts
Expand Up @@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Observable } from 'rxjs';
import { Observable, of, throwError } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { NamespaceDTO, NamespaceInfoDTO, NamespaceRoutesApi } from 'symbol-openapi-typescript-fetch-client';
import { Convert as convert, RawAddress as AddressLibrary } from '../core/format';
import { AccountNames } from '../model/account/AccountNames';
import { Address } from '../model/account/Address';
import { MosaicId } from '../model/mosaic/MosaicId';
Expand Down Expand Up @@ -168,24 +167,18 @@ export class NamespaceHttp extends Http implements NamespaceRepository {
* @returns Observable<MosaicId | null>
*/
public getLinkedMosaicId(namespaceId: NamespaceId): Observable<MosaicId> {
return this.networkTypeObservable.pipe(
mergeMap(() =>
this.call(this.namespaceRoutesApi.getNamespace(namespaceId.toHex()), (body) => {
const namespaceInfoDTO = body;
if (namespaceInfoDTO.namespace === undefined) {
// forward catapult-rest error
throw namespaceInfoDTO;
return this.getNamespace(namespaceId).pipe(
mergeMap((info) => {
if (info.depth === 1) {
if (info.alias.type === AliasType.Mosaic && info.alias.mosaicId) {
return of(info.alias.mosaicId);
}
if (
namespaceInfoDTO.namespace.alias.type.valueOf() === AliasType.None ||
namespaceInfoDTO.namespace.alias.type.valueOf() !== AliasType.Mosaic ||
!namespaceInfoDTO.namespace.alias.mosaicId
) {
throw new Error(`No mosaicId is linked to namespace '${namespaceInfoDTO.namespace.level0}'`);
}
return new MosaicId(namespaceInfoDTO.namespace.alias.mosaicId);
}),
),
return throwError(
new Error(`Invalid alias type ${info.alias.type} when resolving mosaic alias for namespace ` + namespaceId.toHex()),
);
}
return this.getLinkedMosaicId(info.levels[0]);
}),
);
}

Expand All @@ -195,27 +188,20 @@ export class NamespaceHttp extends Http implements NamespaceRepository {
* @returns Observable<Address>
*/
public getLinkedAddress(namespaceId: NamespaceId): Observable<Address> {
return this.networkTypeObservable.pipe(
mergeMap(() =>
this.call(this.namespaceRoutesApi.getNamespace(namespaceId.toHex()), (body) => {
const namespaceInfoDTO = body;
if (namespaceInfoDTO.namespace === undefined) {
// forward catapult-rest error
throw namespaceInfoDTO;
}
if (
namespaceInfoDTO.namespace.alias.type.valueOf() === AliasType.None ||
namespaceInfoDTO.namespace.alias.type.valueOf() !== AliasType.Address ||
!namespaceInfoDTO.namespace.alias.address
) {
throw new Error(`No address is linked to namespace '${namespaceInfoDTO.namespace.level0}'`);
return this.getNamespace(namespaceId).pipe(
mergeMap((info) => {
if (info.depth === 1) {
if (info.alias.type === AliasType.Address && info.alias.address) {
return of(info.alias.address);
}

const addressDecoded = namespaceInfoDTO.namespace.alias.address;
const address = AddressLibrary.addressToString(convert.hexToUint8(addressDecoded));
return Address.createFromRawAddress(address);
}),
),
return throwError(
new Error(
`Invalid alias type ${info.alias.type} when resolving address alias for namespace ` + namespaceId.toHex(),
),
);
}
return this.getLinkedAddress(info.levels[0]);
}),
);
}

Expand Down
8 changes: 4 additions & 4 deletions src/infrastructure/NamespaceRepository.ts
Expand Up @@ -64,14 +64,14 @@ export interface NamespaceRepository extends Searcher<NamespaceInfo, NamespaceSe
/**
* Gets the MosaicId from a MosaicAlias
* @param namespaceId - the namespaceId of the namespace
* @returns Observable<MosaicId | null>
* @returns Observable<MosaicId>
*/
getLinkedMosaicId(namespaceId: NamespaceId): Observable<MosaicId | null>;
getLinkedMosaicId(namespaceId: NamespaceId): Observable<MosaicId>;

/**
* Gets the Address from a AddressAlias
* @param namespaceId - the namespaceId of the namespace
* @returnsObservable<Address | null>
* @returnsObservable<Address>
*/
getLinkedAddress(namespaceId: NamespaceId): Observable<Address | null>;
getLinkedAddress(namespaceId: NamespaceId): Observable<Address>;
}
3 changes: 2 additions & 1 deletion src/model/namespace/Alias.ts
Expand Up @@ -15,6 +15,7 @@
*/
import { Address } from '../account/Address';
import { MosaicId } from '../mosaic/MosaicId';
import { AliasType } from './AliasType';

/**
* Abtract class for Aliases
Expand All @@ -36,7 +37,7 @@ export abstract class Alias {
* - 1 : Mosaic id alias
* - 2 : Address alias
*/
public readonly type: number,
public readonly type: AliasType,

/**
* The alias address
Expand Down
109 changes: 61 additions & 48 deletions test/infrastructure/NamespaceHttp.spec.ts
Expand Up @@ -18,17 +18,15 @@ import * as http from 'http';
import {
AccountNamesDTO,
AccountsNamesDTO,
AliasDTO,
AliasTypeEnum,
MosaicNamesDTO,
MosaicsNamesDTO,
NamespaceDTO,
NamespaceInfoDTO,
NamespaceMetaDTO,
NamespaceNameDTO,
NamespacePage,
NamespaceRoutesApi,
Pagination,
NamespacePage,
} from 'symbol-openapi-typescript-fetch-client';
import { deepEqual, instance, mock, reset, when } from 'ts-mockito';
import { DtoMapping } from '../../src/core/utils/DtoMapping';
Expand All @@ -48,45 +46,47 @@ describe('NamespaceHttp', () => {
const address = publicAccount.address;
const mosaicId = new MosaicId('941299B2B7E1291C');
const namespaceId = new NamespaceId('testnamespace');
const namespaceMetaDto = {} as NamespaceMetaDTO;
namespaceMetaDto.active = true;
namespaceMetaDto.id = '1';
namespaceMetaDto.index = 0;

const namespaceDto = {} as NamespaceDTO;
const aliasDtoAddress = {} as AliasDTO;
aliasDtoAddress.address = address.encoded();
aliasDtoAddress.type = AliasTypeEnum.NUMBER_2;

namespaceDto.alias = aliasDtoAddress;
namespaceDto.depth = 1;
namespaceDto.endHeight = '12';
namespaceDto.level0 = namespaceId.toHex();
namespaceDto.ownerAddress = address.encoded();
namespaceDto.parentId = namespaceId.toHex();
namespaceDto.registrationType = 0;
namespaceDto.startHeight = '10';

const namespaceInfoDto = {} as NamespaceInfoDTO;
namespaceInfoDto.meta = namespaceMetaDto;
namespaceInfoDto.namespace = namespaceDto;

const aliasDtoMosaic = {} as AliasDTO;
aliasDtoMosaic.mosaicId = mosaicId.toHex();
aliasDtoMosaic.type = AliasTypeEnum.NUMBER_1;
const namespaceDtoMosaic = {} as NamespaceDTO;
namespaceDtoMosaic.alias = aliasDtoMosaic;
namespaceDtoMosaic.depth = 1;
namespaceDtoMosaic.endHeight = '12';
namespaceDtoMosaic.level0 = namespaceId.toHex();
namespaceDtoMosaic.ownerAddress = address.encoded();
namespaceDtoMosaic.parentId = namespaceId.toHex();
namespaceDtoMosaic.registrationType = 0;
namespaceDtoMosaic.startHeight = '10';

const namespaceInfoDtoMosaic = {} as NamespaceInfoDTO;
namespaceInfoDtoMosaic.meta = namespaceMetaDto;
namespaceInfoDtoMosaic.namespace = namespaceDtoMosaic;
const namespaceIdAlias = new NamespaceId('aliasofalias');

const namespaceDtoAddress: NamespaceDTO = {
alias: { address: address.encoded(), type: AliasTypeEnum.NUMBER_2 },
depth: 1,
endHeight: '12',
level0: namespaceId.toHex(),
ownerAddress: address.encoded(),
parentId: namespaceId.toHex(),
registrationType: 0,
startHeight: '10',
};

const namespaceInfoDtoAddress: NamespaceInfoDTO = { id: '', meta: { active: true, id: '1', index: 0 }, namespace: namespaceDtoAddress };

const namespaceDtoMosaic: NamespaceDTO = {
alias: { mosaicId: mosaicId.toHex(), type: AliasTypeEnum.NUMBER_1 },
depth: 1,
endHeight: '12',
level0: namespaceId.toHex(),
ownerAddress: address.encoded(),
parentId: namespaceId.toHex(),
registrationType: 0,
startHeight: '10',
};

const namespaceInfoDtoMosaic = { id: '', meta: { active: true, id: '1', index: 0 }, namespace: namespaceDtoMosaic };

const namespaceDtoAlias: NamespaceDTO = {
alias: { type: AliasTypeEnum.NUMBER_0 },
depth: 2,
endHeight: '12',
level0: namespaceId.toHex(),
level1: namespaceIdAlias.toHex(),
ownerAddress: address.encoded(),
parentId: namespaceId.toHex(),
registrationType: 0,
startHeight: '10',
};

const namespaceInfoDtoAlias = { id: '', meta: { active: true, id: '1', index: 0 }, namespace: namespaceDtoAlias };

const url = 'http://someHost';
const response: http.IncomingMessage = mock();
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('NamespaceHttp', () => {
});

it('getNamespace', async () => {
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDto));
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAddress));
const namespace = await namespaceRepository.getNamespace(namespaceId).toPromise();
assertNamespaceInfo(namespace);
});
Expand Down Expand Up @@ -175,10 +175,16 @@ describe('NamespaceHttp', () => {
});

it('getLinkedAddress', async () => {
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDto));
const namespaces = await namespaceRepository.getLinkedAddress(namespaceId).toPromise();
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAddress));
const resolvedAddress = await namespaceRepository.getLinkedAddress(namespaceId).toPromise();
expect(resolvedAddress?.plain()).to.be.equal(address.plain());
});

expect(namespaces?.plain()).to.be.equal(address.plain());
it('getLinkedAddress multilevel', async () => {
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAddress));
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceIdAlias.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAlias));
const resolvedAddress = await namespaceRepository.getLinkedAddress(namespaceIdAlias).toPromise();
expect(resolvedAddress?.plain()).to.be.equal(address.plain());
});

it('getLinkedMosaicId', async () => {
Expand All @@ -188,8 +194,15 @@ describe('NamespaceHttp', () => {
expect(namespaces?.toHex()).to.be.equal(mosaicId.toHex());
});

it('getLinkedMosaicId multilevel', async () => {
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoMosaic));
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceIdAlias.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAlias));
const resolvedMosaicId = await namespaceRepository.getLinkedMosaicId(namespaceIdAlias).toPromise();
expect(resolvedMosaicId?.toHex()).to.be.equal(mosaicId.toHex());
});

it('getLinkedMosaicId - Error', async () => {
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDto));
when(namespaceRoutesApi.getNamespace(deepEqual(namespaceId.toHex()))).thenReturn(Promise.resolve(namespaceInfoDtoAddress));
await namespaceRepository
.getLinkedMosaicId(namespaceId)
.toPromise()
Expand All @@ -210,7 +223,7 @@ describe('NamespaceHttp', () => {
pagination.pageSize = 1;

const body = {} as NamespacePage;
body.data = [namespaceInfoDto];
body.data = [namespaceInfoDtoAddress];
body.pagination = pagination;
when(
namespaceRoutesApi.searchNamespaces(
Expand Down

0 comments on commit a6b662e

Please sign in to comment.