-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
repository.acceptance.ts
122 lines (101 loc) · 3.33 KB
/
repository.acceptance.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright IBM Corp. 2019. All Rights Reserved.
// Node module: @loopback/repository
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import {expect} from '@loopback/testlab';
import {DataSource} from 'loopback-datasource-juggler';
import {AnyObject, DefaultCrudRepository, Entity, model, property} from '../..';
import {Product} from '../fixtures/models/product.model';
import {ProductRepository} from '../fixtures/repositories/product.repository';
// This test shows the recommended way how to use @loopback/repository
// together with existing connectors when building LoopBack applications
describe('Repository in Thinking in LoopBack', () => {
let repo: ProductRepository;
beforeEach(givenProductRepository);
it('counts models in empty database', async () => {
expect(await repo.count()).to.deepEqual({count: 0});
});
it('creates a new model', async () => {
const p: Product = await repo.create({name: 'Ink Pen', slug: 'pen'});
expect(p).instanceof(Product);
expect.exists(p.id);
});
it('can save a model', async () => {
const p = await repo.create({slug: 'pencil'});
p.name = 'Red Pencil';
await repo.save(p);
await repo.findById(p.id);
expect(p).to.have.properties({
slug: 'pencil',
name: 'Red Pencil',
});
});
it('rejects extra model properties (defaults to strict mode)', async () => {
await expect(
repo.create({name: 'custom', extra: 'additional-data'} as AnyObject),
).to.be.rejectedWith(/extra.*not defined/);
});
it('allows models to allow additional properties', async () => {
// TODO(bajtos) Add syntactic sugar to allow the following usage:
// @model({strict: false})
@model({settings: {strict: false}})
class Flexible extends Entity {
@property({id: true})
id: number;
}
const flexibleRepo = new DefaultCrudRepository<
Flexible,
typeof Flexible.prototype.id
>(Flexible, new DataSource({connector: 'memory'}));
const created = await flexibleRepo.create({
extra: 'additional data',
} as AnyObject);
const stored = await flexibleRepo.findById(created.id);
expect(stored).to.containDeep({extra: 'additional data'});
});
it('allows models to allow nested model properties', async () => {
@model()
class Role extends Entity {
@property()
name: string;
}
@model()
class Address extends Entity {
@property()
street: string;
}
@model()
class User extends Entity {
@property({
type: 'number',
id: true,
})
id: number;
@property({type: 'string'})
name: string;
@property.array(Role)
roles: Role[];
@property()
address: Address;
}
const userRepo = new DefaultCrudRepository<User, typeof User.prototype.id>(
User,
new DataSource({connector: 'memory'}),
);
const user = {
id: 1,
name: 'foo',
roles: [{name: 'admin'}, {name: 'user'}],
address: {street: 'backstreet'},
};
const created = await userRepo.create(user);
const stored = await userRepo.findById(created.id);
expect(stored).to.containDeep(user);
});
function givenProductRepository() {
const db = new DataSource({
connector: 'memory',
});
repo = new ProductRepository(db);
}
});