Skip to content

Commit fa573bc

Browse files
committed
added testing for search by criteria with order
1 parent c2ccb27 commit fa573bc

File tree

11 files changed

+66
-20
lines changed

11 files changed

+66
-20
lines changed

src/Contexts/Backoffice/Courses/infrastructure/config/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,32 @@ const backofficeConfig = convict({
1313
format: String,
1414
env: 'ELASTIC_URL',
1515
default: 'http://localhost:9200'
16+
},
17+
indexName: 'backofficecourses',
18+
config: {
19+
settings: {
20+
index: {
21+
number_of_replicas: 0 // for local development
22+
}
23+
},
24+
mappings: {
25+
properties: {
26+
id: {
27+
type: 'keyword',
28+
index: true
29+
},
30+
name: {
31+
type: 'text',
32+
index: true,
33+
fielddata: true
34+
},
35+
duration: {
36+
type: 'text',
37+
index: true,
38+
fielddata: true
39+
}
40+
}
41+
}
1642
}
1743
}
1844
});
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import config from '../config';
21
import ElasticConfig from '../../../../Shared/infrastructure/persistence/elasticsearch/ElasticConfig';
2+
import config from '../config';
33

44
export class BackofficeElasticConfigFactory {
55
static createConfig(): ElasticConfig {
66
return {
7-
url: config.get('elastic.url')
7+
url: config.get('elastic.url'),
8+
indexName: config.get('elastic.indexName'),
9+
indexConfig: config.get('elastic.config')
810
};
911
}
1012
}

src/Contexts/Backoffice/Courses/infrastructure/persistence/ElasticBackofficeCourseRepository.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ import { Criteria } from '../../../../Shared/domain/criteria/Criteria';
22
import { ElasticRepository } from '../../../../Shared/infrastructure/persistence/elasticsearch/ElasticRepository';
33
import { BackofficeCourse } from '../../domain/BackofficeCourse';
44
import { BackofficeCourseRepository } from '../../domain/BackofficeCourseRepository';
5+
import config from '../config';
56

67
export class ElasticBackofficeCourseRepository
78
extends ElasticRepository<BackofficeCourse>
89
implements BackofficeCourseRepository {
910
protected moduleName(): string {
10-
return 'backofficecourses';
11+
return config.get('elastic.indexName');
1112
}
1213

1314
async searchAll(): Promise<BackofficeCourse[]> {

src/Contexts/Shared/infrastructure/persistence/elasticsearch/ElasticClientFactory.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export class ElasticClientFactory {
1111
if (!client) {
1212
client = await ElasticClientFactory.createAndConnectClient(config);
1313

14+
await ElasticClientFactory.createIndexWithSettingsIfNotExists(client, config);
15+
1416
ElasticClientFactory.registerClient(client, contextName);
1517
}
1618

@@ -30,4 +32,15 @@ export class ElasticClientFactory {
3032
private static registerClient(client: ElasticClient, contextName: string): void {
3133
ElasticClientFactory.clients[contextName] = client;
3234
}
35+
36+
private static async createIndexWithSettingsIfNotExists(client: ElasticClient, config: ElasticConfig): Promise<void> {
37+
const { body: exist } = await client.indices.exists({ index: config.indexName });
38+
39+
if (!exist) {
40+
await client.indices.create({
41+
index: config.indexName,
42+
body: config.indexConfig
43+
});
44+
}
45+
}
3346
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
type ElasticConfig = { url: string };
1+
type ElasticConfig = { url: string; indexName: string; indexConfig: any };
22

33
export default ElasticConfig;

src/Contexts/Shared/infrastructure/persistence/elasticsearch/ElasticCriteriaConverter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class ElasticCriteriaConverter {
7373
}
7474

7575
private termsQuery(filter: Filter): QueryObject {
76-
return { type: TypeQueryEnum.TERMS, field: filter.field.value, value: filter.value.value };
76+
return { type: TypeQueryEnum.TERMS, field: filter.field.value, value: [filter.value.value] };
7777
}
7878

7979
private greaterThanQuery(filter: Filter): QueryObject {

src/Contexts/Shared/infrastructure/persistence/elasticsearch/ElasticRepository.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ export abstract class ElasticRepository<T extends AggregateRoot> {
2424
protected async searchAllInElastic(unserializer: (data: any) => T): Promise<T[]> {
2525
const body = bodybuilder().query(TypeQueryEnum.MATCH_ALL);
2626

27-
return this.searchInElasticWithSourceBuilder(unserializer, body);
27+
return this.searchInElasticWithBuilder(unserializer, body);
2828
}
2929

3030
protected async searchByCriteria(criteria: Criteria, unserializer: (data: any) => T): Promise<T[]> {
3131
const body = this.criteriaConverter.convert(criteria);
3232

33-
return this.searchInElasticWithSourceBuilder(unserializer, body);
33+
return this.searchInElasticWithBuilder(unserializer, body);
3434
}
3535

36-
private async searchInElasticWithSourceBuilder(unserializer: (data: any) => T, body: Bodybuilder): Promise<T[]> {
36+
private async searchInElasticWithBuilder(unserializer: (data: any) => T, body: Bodybuilder): Promise<T[]> {
3737
const client = await this.client();
3838

3939
try {
@@ -47,7 +47,6 @@ export abstract class ElasticRepository<T extends AggregateRoot> {
4747
if (this.isNotFoundError(e)) {
4848
return [];
4949
}
50-
5150
throw e;
5251
}
5352
}

src/apps/backoffice/backend/dependency-injection/Shared/application.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
factory:
88
class: ../../../../../Contexts/Shared/infrastructure/persistence/elasticsearch/ElasticClientFactory
99
method: 'createClient'
10-
arguments: ['mooc', '@Backoffice.courses.ElasticConfig']
10+
arguments: ['backoffice', '@Backoffice.courses.ElasticConfig']
1111

1212
Shared.QueryHandlersInformation:
1313
class: ../../../../../Contexts/Shared/infrastructure/QueryBus/QueryHandlersInformation

tests/Contexts/Backoffice/Courses/domain/BackofficeCourseCriteriaMother.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ export class BackofficeCourseCriteriaMother {
1717
const nameFilter = new Filter(filterFieldName, filterOperator, valueName);
1818
const durationFilter = new Filter(filterFieldDuration, filterOperator, valueDuration);
1919

20-
return new Criteria(new Filters([nameFilter, durationFilter]), Order.asc('name'));
20+
return new Criteria(new Filters([nameFilter, durationFilter]), Order.asc('id'));
2121
}
2222
}

tests/Contexts/Backoffice/Courses/infrastructure/BackofficeCourseRepository.test.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,18 @@ describe('BackofficeCourseRepository', () => {
3131
});
3232

3333
describe('#searchByCriteria', () => {
34-
it('should return courses using a criteria', async () => {
34+
it('should return courses using a criteria sorting by id', async () => {
3535
const courses = [
3636
BackofficeCourseMother.withNameAndDuration('DDD in Typescript', '8 days'),
3737
BackofficeCourseMother.withNameAndDuration('DDD in Golang', '3 days'),
3838
BackofficeCourseMother.random()
3939
];
40-
4140
await Promise.all(courses.map(async course => repository.save(course)));
41+
const result = await repository.matching(BackofficeCourseCriteriaMother.nameAndDurationContains('DDD', 'days'));
4242

43-
const expectedCourses = await repository.matching(
44-
BackofficeCourseCriteriaMother.nameAndDurationContains('DDD', 'days')
45-
);
46-
47-
expect(expectedCourses).toHaveLength(2);
43+
const expectedCourses = courses.slice(0, 2);
44+
expect(result).toHaveLength(2);
45+
expect(expectedCourses.sort(sort)).toEqual(result);
4846
});
4947
});
5048
});

0 commit comments

Comments
 (0)