Skip to content

Commit

Permalink
Merge pull request #14 from fagbokforlaget/EP-3907-update-erudio-client
Browse files Browse the repository at this point in the history
EP-3907-update-erudio-client
  • Loading branch information
espresse authored Jul 18, 2023
2 parents e983906 + a386182 commit 0fc5485
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 12 deletions.
4 changes: 3 additions & 1 deletion src/content-fusion/dto/content-node-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export enum TypeEnum {
export class Contents {
readonly namespace: string;
readonly schemaId: string;
readonly content: Record<string, unknown>;
readonly content: Record<string, unknown> & {
learningPath?: { id: string; type: string };
};
readonly type: TypeEnum;
readonly createdAt: string;
readonly updatedAt: string;
Expand Down
35 changes: 27 additions & 8 deletions src/erudio-client.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { ContentFusion } from './content-fusion/content-fusion';
import { Contents } from './content-fusion/dto/content-node-dto';
import { LearningPathWithLocalizationDto } from './learning-path/dto/learning-path.dto';
import { LearningPath } from './learning-path/learnig-path';
import { LocalizationDto } from './localization/dto/localization-dto';
import { Localization } from './localization/localization';
import { StructureLink as StructureLinkDto } from './structure-link/dto/structure-link';
import { StructureLink } from './structure-link/structure-link';
import {
PaginatedNodes,
Node,
StructureNode,
Options,
PaginatedNodes,
StructureNode,
} from './structure/dto/paginated-nodes-dto';
import { Contents } from './content-fusion/dto/content-node-dto';
import { Structure } from './structure/structure';
import { ContentFusion } from './content-fusion/content-fusion';
import { TagObject } from './tag/dto/tag.dto';
import { TagService } from './tag/tag';
import { ServiceType } from './utils/service.types';
import { StructureLink as StructureLinkDto } from './structure-link/dto/structure-link';
import { StructureLink } from './structure-link/structure-link';
import { Localization } from './localization/localization';
import { LocalizationDto } from './localization/dto/localization-dto';

export class ErudioClient {
private host: string;
Expand Down Expand Up @@ -64,6 +66,7 @@ export class ErudioClient {
structureId: string,
locale?: string,
): Promise<StructureNode> => {
let learningPath: LearningPathWithLocalizationDto;
const structure: Node = await new Structure(this.host).getSingleNode(
namespace,
structureId,
Expand All @@ -75,6 +78,21 @@ export class ErudioClient {
structure.contentId,
locale,
);
if (
structure.contentType === 'learning-path' &&
structureContents.content.learningPath?.type === 'ref'
) {
try {
learningPath = await new LearningPath(this.host).getLearningPath(
structureContents.content.learningPath?.id,
locale,
);
} catch (e) {
console.log(
`Learning path not found for ${ServiceType.STRUCTURE} ${structureId} not found`,
);
}
}
}

let localization: Partial<LocalizationDto> = {};
Expand Down Expand Up @@ -118,6 +136,7 @@ export class ErudioClient {
return <StructureNode>{
...structure,
localization: localization?.content,
learningPath,
contents: structureContents,
children: nodeListWithContent,
tags: parentStructureTags?.tags || [],
Expand Down
51 changes: 51 additions & 0 deletions src/learning-path/dto/learning-path.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { TagObject } from '../../tag/dto/tag.dto';

export interface LearningPathDto {
readonly id: string;
readonly name: string;
readonly slug: string;
readonly metadata?: Metadata;
readonly forkId?: string;
readonly status: string;
readonly namespaceId?: string;
readonly learningPathElements: LearningPathElementOutputDto[];
readonly tags: TagObject[];
localizations: {
readonly locale: string;
readonly content: Record<string, unknown>;
}[];
readonly createdBy: string;
readonly createdAt: string;
readonly updatedAt: string;
}

interface Metadata {
readonly description?: string;
readonly descriptionInstructor?: string;
readonly author?: string;
readonly coverId?: string;
readonly coverAlt?: string;
readonly coverCopyright?: string;
readonly bannerId?: string;
readonly bannerAlt?: string;
readonly bannerCopyright?: string;
readonly duration?: number;
}

class LearningPathElementOutputDto {
readonly id: string;
readonly createdAt: string;
readonly updatedAt: string;
readonly namespaceId: string;
readonly description?: string;
readonly contentId?: string;
readonly contentType?: string;
readonly condition?: Record<string, unknown>;
}

export type LearningPathWithLocalizationDto = Omit<
LearningPathDto,
'localizations'
> & {
readonly localization?: Record<string, unknown>;
};
30 changes: 30 additions & 0 deletions src/learning-path/learnig-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { HttpClientProxy } from '../utils/http-client-proxy';
import {
LearningPathDto,
LearningPathWithLocalizationDto,
} from './dto/learning-path.dto';

export class LearningPath {
private readonly baseUrl: string;

constructor(host: string) {
this.baseUrl = `http://edtech-learning-path-runner-service.${host}`;
}

public async getLearningPath(
id: string,
locale: string,
): Promise<LearningPathWithLocalizationDto> {
let localization: Record<string, unknown>;

const url = `${this.baseUrl}/learning-paths/${id}`;
const learningPath = await new HttpClientProxy().get<LearningPathDto>(url);
if (locale && learningPath?.localizations) {
localization = learningPath.localizations.find(
(l) => l.locale === locale,
)?.content;
learningPath.localizations = undefined;
}
return { ...learningPath, localization };
}
}
4 changes: 3 additions & 1 deletion src/structure/dto/paginated-nodes-dto.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TagSource } from '../../tag/dto/tag.dto';
import { Contents } from '../../content-fusion/dto/content-node-dto';
import { LearningPathWithLocalizationDto } from '../../learning-path/dto/learning-path.dto';
import { TagSource } from '../../tag/dto/tag.dto';

export class PaginatedNodes<T> {
readonly data: T[];
Expand Down Expand Up @@ -35,6 +36,7 @@ export interface Node {
readonly accessLevel: string;
readonly contents?: Contents;
readonly localization: Record<string, unknown>;
readonly learningPath?: LearningPathWithLocalizationDto;
}

export interface StructureNode extends Node {
Expand Down
7 changes: 7 additions & 0 deletions test/data/get-structure-node-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ export const content = {
},
};

export const learningPathContent = {
content: {
...content,
learningPath: { type: 'ref', id: 'b942d4de-921c-4406-abbd-464dabb7b323' },
},
};

export const structureNodeData = {
id: 'sample',
name: 'sample',
Expand Down
5 changes: 5 additions & 0 deletions test/data/get-structure-nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,8 @@ export const singleNode = {
updatedAt: 'sample',
accessLevel: 'sample',
};

export const singleLearningPathNode = {
...singleNode,
contentType: 'learning-path',
};
24 changes: 24 additions & 0 deletions test/data/learning-path-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { LearningPathDto } from '../../src/learning-path/dto/learning-path.dto';

export const learningPath: LearningPathDto = {
id: 'b942d4de-921c-4406-abbd-464dabb7b323',
name: 'name',
slug: 'slug',
status: 'status',
createdBy: 'created_by',
createdAt: 'created_at',
updatedAt: 'updated_at',
learningPathElements: [
{
id: 'id',
namespaceId: 'namespaceId',
createdAt: 'created_at',
updatedAt: 'updated_at',
},
],
tags: [],
localizations: [
{ locale: 'locale123', content: { con1: 'con1', con2: 'con2' } },
{ locale: 'locale456', content: { con3: 'con4', con5: 'con6' } },
],
};
73 changes: 71 additions & 2 deletions test/erudio-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@ import { ErudioClient } from '../src/erudio-client';
import { ServiceType } from '../src/utils/service.types';
import { structureLink } from './data/get-structure-link-data';
import { structureLocalization } from './data/get-structure-localization';
import { content, structureNodeData } from './data/get-structure-node-data';
import { nodeList, singleNode } from './data/get-structure-nodes';
import {
content,
learningPathContent,
structureNodeData,
} from './data/get-structure-node-data';
import {
nodeList,
singleLearningPathNode,
singleNode,
} from './data/get-structure-nodes';
import { structureLinkTagData, structureTagData } from './data/get-tags-data';
import { learningPath } from './data/learning-path-data';

describe('Erudio Client', () => {
let mock, ec: ErudioClient;
Expand All @@ -19,6 +28,8 @@ describe('Erudio Client', () => {
'http://edtech-structure-link-service.dev.example.com/structures/links';
const localizationService =
'http://edtech-localization-service.dev.example.com/localizations';
const learningPathService =
'http://edtech-learning-path-runner-service.dev.example.com/learning-paths';

const namespace = 'fb29c948-327f-4f56-abb5-247e4cec5a22';
const structureID = 'b942d4de-921c-4406-abbd-464dabb7b210';
Expand Down Expand Up @@ -192,5 +203,63 @@ describe('Erudio Client', () => {
);
});
});

it('Should return structure node list with learning path', async () => {
mock
.onGet(`${structureService}${namespace}/nodes/${structureID}`)
.replyOnce(200, singleLearningPathNode);
mock
.onGet(`${structureService}${namespace}/children/nodes/${structureID}`)
.replyOnce(200, nodeList);
mock
.onGet(`${contentFusionService}${childNodeID}`)
.reply(200, learningPathContent);
mock
.onGet(
`${learningPathService}/${learningPathContent.content.learningPath.id}`,
)
.reply(200, learningPath);

const allStructureData = await ec.getStructureNode(
namespace,
structureID,
'locale123',
);

expect(allStructureData.learningPath).toMatchObject({
...learningPath,
localizations: undefined,
localization: learningPath.localizations[0].content,
});
});

it('Should return structure node list with learning path and invalid locale value', async () => {
mock
.onGet(`${structureService}${namespace}/nodes/${structureID}`)
.replyOnce(200, singleLearningPathNode);
mock
.onGet(`${structureService}${namespace}/children/nodes/${structureID}`)
.replyOnce(200, nodeList);
mock
.onGet(`${contentFusionService}${childNodeID}`)
.reply(200, learningPathContent);
mock
.onGet(
`${learningPathService}/${learningPathContent.content.learningPath.id}`,
)
.reply(200, learningPath);

const allStructureData = await ec.getStructureNode(
namespace,
structureID,
'non-existing-locale',
);

expect(allStructureData.learningPath).toMatchObject({
...learningPath,
localizations: undefined,
localization: undefined,
});
});
});
});

0 comments on commit 0fc5485

Please sign in to comment.