Skip to content

Commit

Permalink
feat(coscrad): support multilingual text for notes (#404)
Browse files Browse the repository at this point in the history
* feat(coscrad): support multilingual text for notes

* Refactor based on PR (#404)
  • Loading branch information
aaron-plahn authored Jun 19, 2023
1 parent 5bc8dcf commit b811484
Show file tree
Hide file tree
Showing 40 changed files with 1,638 additions and 207 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,45 @@ exports[`command payload schemas Command payload schema should match the snapsho
},
},
},
"languageCode": {
"complexDataType": "ENUM",
"description": "the language in which you are writing the note",
"enumLabel": "language code",
"enumName": "LanguageCode",
"isArray": false,
"isOptional": false,
"label": "language",
"labelsAndValues": [
{
"label": "Chilcotin",
"value": "clc",
},
{
"label": "Haida",
"value": "hai",
},
{
"label": "English",
"value": "eng",
},
{
"label": "French",
"value": "fra",
},
{
"label": "Chinook",
"value": "chn",
},
{
"label": "Zapotec",
"value": "zap",
},
{
"label": "Spanish",
"value": "spa",
},
],
},
"resourceCompositeIdentifier": {
"complexDataType": "NESTED_TYPE",
"description": "system-wide unique identifier for the resource about which we are making a note",
Expand Down Expand Up @@ -1818,6 +1857,45 @@ exports[`command payload schemas Command payload schema should match the snapsho
],
"unionName": "EDGE_CONNECTION_CONTEXT_UNION",
},
"languageCode": {
"complexDataType": "ENUM",
"description": "the language in which you are writing the note",
"enumLabel": "language code",
"enumName": "LanguageCode",
"isArray": false,
"isOptional": false,
"label": "language",
"labelsAndValues": [
{
"label": "Chilcotin",
"value": "clc",
},
{
"label": "Haida",
"value": "hai",
},
{
"label": "English",
"value": "eng",
},
{
"label": "French",
"value": "fra",
},
{
"label": "Chinook",
"value": "chn",
},
{
"label": "Zapotec",
"value": "zap",
},
{
"label": "Spanish",
"value": "spa",
},
],
},
"text": {
"coscradDataType": "NON_EMPTY_STRING",
"description": "text for the note",
Expand Down
14 changes: 12 additions & 2 deletions apps/api/src/domain/common/entities/multilingual-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import {
TypeDecoratorOptions,
} from '@coscrad/data-types';
import { InternalError } from '../../../lib/errors/InternalError';
import { DeepPartial } from '../../../types/DeepPartial';
import { Maybe } from '../../../lib/types/maybe';
import { NotFound } from '../../../lib/types/not-found';
import { DTO } from '../../../types/DTO';
import { DeepPartial } from '../../../types/DeepPartial';
import { ResultOrError } from '../../../types/ResultOrError';
import { Valid } from '../../domainModelValidators/Valid';
import BaseDomainModel from '../../models/BaseDomainModel';
import { DuplicateLanguageInMultilingualTextError } from '../../models/audio-item/errors/duplicate-language-in-multilingual-text.error';
import { MultilingualTextHasNoOriginalError } from '../../models/audio-item/errors/multilingual-text-has-no-original.error';
import { MultipleOriginalsInMultilingualTextError } from '../../models/audio-item/errors/multiple-originals-in-multilingual-text.error';
import BaseDomainModel from '../../models/BaseDomainModel';
import { isNull, isUndefined } from '../../utilities/validation/is-null-or-undefined';

export { MultilingualTextItemRole };
Expand Down Expand Up @@ -133,6 +135,14 @@ export class MultilingualText extends BaseDomainModel implements IMultilingualTe
return this.items.map(({ text, languageCode }) => `{${languageCode}}: ${text}`).join('\n');
}

in(languageCode: LanguageCode): Maybe<MultilingualTextItem> {
return this.items.find((item) => item.languageCode === languageCode) || NotFound;
}

getOriginalTextItem(): MultilingualTextItem {
return this.items.find(({ role }) => role === MultilingualTextItemRole.original).clone();
}

append(item: MultilingualTextItem): MultilingualText {
return this.clone({
// avoid shared references
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { LanguageCode } from '@coscrad/api-interfaces';
import { DTO } from '../../../../../../types/DTO';
import buildInvariantValidationErrorFactoryFunction from '../../../../../__tests__/utilities/buildInvariantValidationErrorFactoryFunction';
import { buildMultilingualTextWithSingleItem } from '../../../../../common/build-multilingual-text-with-single-item';
import { dummyUuid } from '../../../../../models/__tests__/utilities/dummyUuid';
import {
EdgeConnection,
Expand Down Expand Up @@ -64,7 +66,7 @@ const validBookSelfConnection = new EdgeConnection({
type: AggregateType.note,
connectionType: EdgeConnectionType.self,
id: '12345',
note: 'This is an awesome note',
note: buildMultilingualTextWithSingleItem('This is an awesome note', LanguageCode.English),
members: [buildValidBookEdgeConnectionMemberDto(EdgeConnectionMemberRole.self)],
});

Expand All @@ -76,7 +78,7 @@ const validBookToTranscribedAudioDualConnection = new EdgeConnection({
buildValidTranscribedAudioConnectionMemberDto(EdgeConnectionMemberRole.to),
],
id: dummyUuid,
note: 'These are both about bears',
note: buildMultilingualTextWithSingleItem('These are both about bears', LanguageCode.English),
}).toDTO();

const validBookBibliographicReferenceMemberWithIdentityContext: DTO<
Expand Down Expand Up @@ -151,7 +153,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
id: dummyUuid,

members: [],
note: 'This is the note',
note: buildMultilingualTextWithSingleItem(
'This is the note',
LanguageCode.English
),
},
expectedError: buildTopLevelError(dummyUuid, [
new InvalidNumberOfMembersInEdgeConnectionError(EdgeConnectionType.self, 0),
Expand Down Expand Up @@ -225,7 +230,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
EdgeConnectionMemberRole.from
),
],
note: 'This is the note',
note: buildMultilingualTextWithSingleItem(
'This is the note',
LanguageCode.English
),
},
expectedError: buildTopLevelError(dummyUuid, [
new InvalidEdgeConnectionMemberRolesError(EdgeConnectionType.dual, [
Expand Down Expand Up @@ -346,7 +354,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
type: AggregateType.note,
connectionType: EdgeConnectionType.dual,
id: dummyUuid,
note: 'I do not get how identity context works!',
note: buildMultilingualTextWithSingleItem(
'I do not get how identity context works!',
LanguageCode.English
),
members: [
{
compositeIdentifier: {
Expand All @@ -370,7 +381,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
type: AggregateType.note,
connectionType: EdgeConnectionType.dual,
id: dummyUuid,
note: 'my from member should be a bibliographic reference, but it is not!',
note: buildMultilingualTextWithSingleItem(
'my from member should be a bibliographic reference, but it is not!',
LanguageCode.English
),
members: [
{
role: EdgeConnectionMemberRole.from,
Expand Down Expand Up @@ -403,7 +417,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
type: AggregateType.note,
connectionType: EdgeConnectionType.dual,
id: dummyUuid,
note: 'This book reference is having an identity crisis. Thinks it is a term.',
note: buildMultilingualTextWithSingleItem(
'This book reference is having an identity crisis. Thinks it is a term.',
LanguageCode.English
),
members: [
validBookBibliographicReferenceMemberWithIdentityContext,
{
Expand Down Expand Up @@ -440,7 +457,10 @@ export default (): EdgeConnectionValidatorTestCase[] => [
type: AggregateType.note,
connectionType: EdgeConnectionType.self,
id: dummyUuid,
note: 'This self member is having an identity crisis!',
note: buildMultilingualTextWithSingleItem(
'This self member is having an identity crisis!',
LanguageCode.English
),
members: [
{
role: EdgeConnectionMemberRole.self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,99 @@ exports[`Coscrad Data Schemas for aggregate root domain models the COSCRAD data
},
},
"note": {
"coscradDataType": "NON_EMPTY_STRING",
"complexDataType": "NESTED_TYPE",
"description": "text summary of why this connection is relevant",
"isArray": false,
"isOptional": false,
"label": "note text",
"schema": {
"items": {
"complexDataType": "NESTED_TYPE",
"description": "one item for each provided language",
"isArray": true,
"isOptional": false,
"label": "items",
"schema": {
"languageCode": {
"complexDataType": "ENUM",
"description": "an official identifier of the language",
"enumLabel": "Language_Code",
"enumName": "LangaugeCode",
"isArray": false,
"isOptional": false,
"label": "language code",
"labelsAndValues": [
{
"label": "Chilcotin",
"value": "clc",
},
{
"label": "Haida",
"value": "hai",
},
{
"label": "English",
"value": "eng",
},
{
"label": "French",
"value": "fra",
},
{
"label": "Chinook",
"value": "chn",
},
{
"label": "Zapotec",
"value": "zap",
},
{
"label": "Spanish",
"value": "spa",
},
],
},
"role": {
"complexDataType": "ENUM",
"description": "role of this text in the translation process",
"enumLabel": "text item role",
"enumName": "Multilingual Text Item Role",
"isArray": false,
"isOptional": false,
"label": "text item role",
"labelsAndValues": [
{
"label": "original",
"value": "original",
},
{
"label": "glossed to",
"value": "glossed to",
},
{
"label": "prompt",
"value": "prompt",
},
{
"label": "free translation",
"value": "free translation",
},
{
"label": "literal translation",
"value": "literal translation",
},
],
},
"text": {
"coscradDataType": "NON_EMPTY_STRING",
"description": "plain text in the given language",
"isArray": false,
"isOptional": false,
"label": "text",
},
},
},
},
},
}
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { EdgeConnectionMemberRole, EdgeConnectionType } from '@coscrad/api-interfaces';
import {
EdgeConnectionMemberRole,
EdgeConnectionType,
MultilingualTextItemRole,
} from '@coscrad/api-interfaces';
import { CommandHandler, ICommand } from '@coscrad/commands';
import { Inject } from '@nestjs/common';
import { InternalError } from '../../../../../lib/errors/InternalError';
import { isNotFound } from '../../../../../lib/types/not-found';
import { REPOSITORY_PROVIDER_TOKEN } from '../../../../../persistence/constants/persistenceConstants';
import { DTO } from '../../../../../types/DTO';
import { ResultOrError } from '../../../../../types/ResultOrError';
import { MultilingualText } from '../../../../common/entities/multilingual-text';
import { Valid } from '../../../../domainModelValidators/Valid';
import buildAggregateFactory from '../../../../factories/buildAggregateFactory';
import { IIdManager } from '../../../../interfaces/id-manager.interface';
Expand Down Expand Up @@ -46,6 +51,7 @@ export class ConnectResourcesWithNoteCommandHandler extends BaseCreateCommandHan
fromMemberCompositeIdentifier,
fromMemberContext,
text,
languageCode,
}: ConnectResourcesWithNote): ResultOrError<EdgeConnection> {
/**
* TODO[https://www.pivotaltracker.com/story/show/185394721]
Expand All @@ -56,7 +62,15 @@ export class ConnectResourcesWithNoteCommandHandler extends BaseCreateCommandHan
id,
connectionType: EdgeConnectionType.dual,
// TODO [https://www.pivotaltracker.com/story/show/185394771] make this Multilingual Text
note: text,
note: new MultilingualText({
items: [
{
text,
languageCode,
role: MultilingualTextItemRole.original,
},
],
}),
members: [
{
role: EdgeConnectionMemberRole.to,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LanguageCode } from '@coscrad/api-interfaces';
import { CommandHandlerService } from '@coscrad/commands';
import { INestApplication } from '@nestjs/common';
import { isDeepStrictEqual } from 'util';
Expand Down Expand Up @@ -73,6 +74,7 @@ const buildValidPayload = (id: AggregateId) => ({
fromMemberCompositeIdentifier: existingBook.getCompositeIdentifier(),
fromMemberContext: new GeneralContext(),
text: 'this is how these resources are connected',
languageCode: LanguageCode.English,
});

const buidlValidFsa = (id: AggregateId) => ({
Expand Down Expand Up @@ -254,7 +256,10 @@ describe(commandType, () => {

const newConnection = newEdgeConnectionSearchResult as EdgeConnection;

expect(newConnection.note).toBe(text);
const textForNewConnection =
newConnection.note.getOriginalTextItem().text;

expect(textForNewConnection).toBe(text);

assertEventRecordPersisted(
newConnection,
Expand Down
Loading

0 comments on commit b811484

Please sign in to comment.