Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

N21 2198 media shelf extend database for ctl metadata #5272

Merged
merged 12 commits into from
Oct 9, 2024
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Embedded, Entity, Property, Unique } from '@mikro-orm/core';

import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { EntityId } from '@shared/domain/types';
import { ToolContextType } from '../../common/enum';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { EntityId } from '@shared/domain/types';
import { MediaSourceAuthMethod } from '../enum';

export interface MediaSourceOauthConfigProps extends AuthorizableObject {
id: EntityId;

clientId: string;

clientSecret: string;

authEndpoint: string;

method: MediaSourceAuthMethod;
}

export class MediaSourceOauthConfig extends DomainObject<MediaSourceOauthConfigProps> {}
18 changes: 16 additions & 2 deletions apps/server/src/modules/user-license/domain/media-source.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { DomainObject } from '@shared/domain/domain-object';
import { AuthorizableObject, DomainObject } from '@shared/domain/domain-object';
import { MediaSourceOauthConfig } from './media-source-oauth-config';
import { MediaSourceDataFormat } from '../enum';

export interface MediaSourceProps {
export interface MediaSourceProps extends AuthorizableObject {
id: string;

name?: string;

sourceId: string;

format?: MediaSourceDataFormat;

config?: MediaSourceOauthConfig;
}

export class MediaSource extends DomainObject<MediaSourceProps> {
Expand All @@ -16,4 +22,12 @@ export class MediaSource extends DomainObject<MediaSourceProps> {
get sourceId(): string {
return this.props.sourceId;
}

get format(): MediaSourceDataFormat | undefined {
return this.props.format;
}

get config(): MediaSourceOauthConfig | undefined {
return this.props.config;
}
}
4 changes: 3 additions & 1 deletion apps/server/src/modules/user-license/entity/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export { UserLicenseType } from './user-license-type';
export { UserLicenseType } from '../enum/user-license-type';
export { MediaUserLicenseEntity, MediaUserLicenseEntityProps } from './media-user-license.entity';
export { UserLicenseEntity } from './user-license.entity';
export { MediaSourceEntity, MediaSourceEntityProps } from './media-source.entity';
export { MediaSourceDataFormat } from '../enum/media-source-data-format.enum';
export { MediaSourceAuthMethod } from '../enum/media-source-auth-method.enum';
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Embeddable, Enum, Property } from '@mikro-orm/core';
import { ObjectId } from '@mikro-orm/mongodb';
import { MediaSourceAuthMethod } from '../enum/media-source-auth-method.enum';

export interface MediaSourceConfigEmbeddableProps {
_id: ObjectId;

clientId: string;

clientSecret: string;

authEndpoint: string;

method: MediaSourceAuthMethod;
}

@Embeddable()
export class MediaSourceConfigEmbeddable {
@Property()
_id: ObjectId;

@Property()
clientId: string;

@Property()
clientSecret: string;

@Property()
authEndpoint: string;

@Enum({ nullable: false })
method: MediaSourceAuthMethod;

constructor(props: MediaSourceConfigEmbeddableProps) {
this._id = props._id;
this.clientId = props.clientId;
this.clientSecret = props.clientSecret;
this.authEndpoint = props.authEndpoint;
this.method = props.method;
}
}
26 changes: 20 additions & 6 deletions apps/server/src/modules/user-license/entity/media-source.entity.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
import { Entity, Index, Property } from '@mikro-orm/core';
import { Embedded, Entity, Index, Property } from '@mikro-orm/core';
import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { EntityId } from '@shared/domain/types';
import { MediaSourceDataFormat } from '../enum/media-source-data-format.enum';
import { MediaSourceConfigEmbeddable } from './media-source-oauth-config.embeddable';

export interface MediaSourceEntityProps {
id?: EntityId;

name?: string;

sourceId: string;

config?: MediaSourceConfigEmbeddable;

format?: MediaSourceDataFormat;
}

@Entity({ tableName: 'media-sources' })
export class MediaSourceEntity extends BaseEntityWithTimestamps {
constructor(props: MediaSourceEntityProps) {
super();
if (props.id != null) {
if (props.id) {
this.id = props.id;
}
this.name = props.name;
this.sourceId = props.sourceId;
this.name = props.name;
this.format = props.format;
this.config = props.config;
}

@Property({ nullable: true })
name?: string;

@Index()
@Property()
sourceId: string;

@Property({ nullable: true })
name?: string;

@Property({ nullable: true })
format?: MediaSourceDataFormat;

@Embedded(() => MediaSourceConfigEmbeddable, { object: true, nullable: true })
config?: MediaSourceConfigEmbeddable;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Entity, ManyToOne, Property } from '@mikro-orm/core';
import { MediaSourceEntity } from './media-source.entity';
import { UserLicenseType } from './user-license-type';
import { UserLicenseType } from '../enum/user-license-type';
import { UserLicenseEntity, UserLicenseProps } from './user-license.entity';

export interface MediaUserLicenseEntityProps extends UserLicenseProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Entity, Enum, Index, ManyToOne } from '@mikro-orm/core';
import { BaseEntityWithTimestamps } from '@shared/domain/entity/base.entity';
import { User as UserEntity } from '@shared/domain/entity/user.entity';
import { EntityId } from '@shared/domain/types';
import { UserLicenseType } from './user-license-type';
import { UserLicenseType } from '../enum/user-license-type';

export interface UserLicenseProps {
id?: EntityId;
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/modules/user-license/enum/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { UserLicenseType } from './user-license-type';
export { MediaSourceDataFormat } from './media-source-data-format.enum';
export { MediaSourceAuthMethod } from './media-source-auth-method.enum';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum MediaSourceAuthMethod {
CLIENT_CREDENTIALS = 'CLIENT_CREDENTIALS',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum MediaSourceDataFormat {
BILDUNGSLOGIN = 'BILDUNGSLOGIN',
}
13 changes: 7 additions & 6 deletions apps/server/src/modules/user-license/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
export { UserLicenseModule } from './user-license.module';
export { MediaUserLicenseService, MediaSourceService } from './service';
export { MediaUserLicense, MediaSource, MediaUserLicenseProps, MediaSourceProps, AnyUserLicense } from './domain';
export { UserLicenseType } from './entity/user-license-type';
export { AnyUserLicense, MediaSource, MediaSourceProps, MediaUserLicense, MediaUserLicenseProps } from './domain';
export { MediaSourceEntity } from './entity';
export { UserLicenseType } from './enum/user-license-type';
export { MediaSourceService, MediaUserLicenseService } from './service';
export {
mediaUserLicenseFactory,
mediaSourceFactory,
mediaSourceEntityFactory,
mediaSourceFactory,
mediaUserLicenseEntityFactory,
mediaUserLicenseFactory,
} from './testing';
export { UserLicenseModule } from './user-license.module';
3 changes: 2 additions & 1 deletion apps/server/src/modules/user-license/repo/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { MediaSourceConfigMapper } from './media-source-config.mapper';
export { MediaSourceRepo } from './media-source.repo';
export { MediaUserLicenseRepo } from './media-user-license.repo';
export { UserLicenseQuery } from './user-license-query';
export { MediaSourceRepo } from './media-source.repo';
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { setupEntities } from '@shared/testing';
import { MediaSourceOauthConfig } from '../domain/media-source-oauth-config';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';
import { mediaSourceConfigEmbeddableFactory } from '../testing/media-source-config.embeddable.factory';
import { mediaSourceConfigFactory } from '../testing/media-source-config.factory';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

describe('MediaSourceConfigMapper', () => {
describe('mapToDo', () => {
describe('when entity is passed', () => {
const setup = async () => {
await setupEntities();

const entity = mediaSourceConfigEmbeddableFactory.build();
const expected = new MediaSourceOauthConfig({
id: entity._id.toHexString(),
clientId: entity.clientId,
clientSecret: entity.clientSecret,
authEndpoint: entity.authEndpoint,
method: entity.method,
});

return { entity, expected };
};

it('should return an instance of config', async () => {
const { entity } = await setup();

const result = MediaSourceConfigMapper.mapToDo(entity);

expect(result).toBeInstanceOf(MediaSourceOauthConfig);
});

it('should return a do with all properties', async () => {
const { entity, expected } = await setup();

const result = MediaSourceConfigMapper.mapToDo(entity);

expect(result).toEqual(expected);
});
});
});

describe('mapToEntity', () => {
describe('when config do is passed', () => {
const setup = async () => {
await setupEntities();

const configDo = mediaSourceConfigFactory.build();
const expected = new MediaSourceConfigEmbeddable({
_id: new ObjectId(configDo.id),
clientId: configDo.getProps().clientId,
clientSecret: configDo.getProps().clientSecret,
authEndpoint: configDo.getProps().authEndpoint,
method: configDo.getProps().method,
});

return { configDo, expected };
};

it('should return an instance of config embeddable', async () => {
const { configDo } = await setup();

const result = MediaSourceConfigMapper.mapToEntity(configDo);

expect(result).toBeInstanceOf(MediaSourceConfigEmbeddable);
});

it('should return an embeddable with all properties', async () => {
const { configDo, expected } = await setup();

const result = MediaSourceConfigMapper.mapToEntity(configDo);

expect(result).toEqual(expected);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { MediaSourceOauthConfig } from '../domain/media-source-oauth-config';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';

export class MediaSourceConfigMapper {
static mapToEntity(config: MediaSourceOauthConfig): MediaSourceConfigEmbeddable {
const configProps = config.getProps();

const configEmbeddable = new MediaSourceConfigEmbeddable({ ...configProps, _id: new ObjectId(configProps.id) });

return configEmbeddable;
}

static mapToDo(embeddable: MediaSourceConfigEmbeddable): MediaSourceOauthConfig {
const config = new MediaSourceOauthConfig({
id: embeddable._id.toHexString(),
clientId: embeddable.clientId,
clientSecret: embeddable.clientSecret,
method: embeddable.method,
authEndpoint: embeddable.authEndpoint,
});

return config;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { EntityData } from '@mikro-orm/core';
import { MediaSource } from '../domain';
import { MediaSourceEntity } from '../entity';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

export class MediaSourceMapper {
public static mapToEntityProperties(entityDO: MediaSource): EntityData<MediaSourceEntity> {
const entityProps: EntityData<MediaSourceEntity> = {
name: entityDO.name,
sourceId: entityDO.sourceId,
config: entityDO.config ? MediaSourceConfigMapper.mapToEntity(entityDO.config) : undefined,
format: entityDO.format,
};

return entityProps;
Expand All @@ -17,6 +20,8 @@ export class MediaSourceMapper {
id: entity.id,
name: entity.name,
sourceId: entity.sourceId,
config: entity.config ? MediaSourceConfigMapper.mapToDo(entity.config) : undefined,
format: entity.format,
});

return domainObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { MediaSource } from '../domain';
import { MediaSourceEntity } from '../entity';
import { mediaSourceEntityFactory, mediaSourceFactory } from '../testing';
import { MediaSourceRepo } from './media-source.repo';
import { MediaSourceConfigEmbeddable } from '../entity/media-source-oauth-config.embeddable';
import { mediaSourceConfigEmbeddableFactory } from '../testing/media-source-config.embeddable.factory';
import { MediaSourceConfigMapper } from './media-source-config.mapper';

describe(MediaSourceRepo.name, () => {
let module: TestingModule;
Expand Down Expand Up @@ -33,19 +36,22 @@ describe(MediaSourceRepo.name, () => {
describe('findBySourceId', () => {
describe('when a media source exists', () => {
const setup = async () => {
const mediaSource: MediaSourceEntity = mediaSourceEntityFactory.build();
const config: MediaSourceConfigEmbeddable = mediaSourceConfigEmbeddableFactory.build();

const mediaSource: MediaSourceEntity = mediaSourceEntityFactory.build({ config });

await em.persistAndFlush([mediaSource]);

em.clear();

return {
mediaSource,
config,
};
};

it('should return user licenses for user', async () => {
const { mediaSource } = await setup();
const { mediaSource, config } = await setup();

const result = await repo.findBySourceId(mediaSource.sourceId);

Expand All @@ -54,6 +60,8 @@ describe(MediaSourceRepo.name, () => {
id: mediaSource.id,
name: mediaSource.name,
sourceId: mediaSource.sourceId,
format: mediaSource.format,
config: MediaSourceConfigMapper.mapToDo(config),
})
);
});
Expand Down
Loading
Loading