Skip to content

Commit 26336ac

Browse files
committed
Add tests
1 parent a151deb commit 26336ac

File tree

3 files changed

+207
-7
lines changed

3 files changed

+207
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Copyright IBM Corp. 2019,2020. All Rights Reserved.
2+
// Node module: loopback4-example-shopping
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
import {Client, expect, sinon} from '@loopback/testlab';
7+
import {Suite} from 'mocha';
8+
import {SciLogDbApplication} from '../..';
9+
import {clearDatabase, createUserToken, setupApplication} from './test-helper';
10+
import {BasesnippetRepository} from '../../repositories';
11+
import fs from 'fs';
12+
import {Basesnippet, Location, Logbook, Paragraph} from '../../models';
13+
import {CreateFunctionalAccountsObserver} from '../../observers';
14+
15+
class TestFunctionalAccountsApp extends SciLogDbApplication {
16+
locations = ['location1', 'location2'];
17+
idsLocation: Record<string, string>;
18+
19+
constructor() {
20+
super(SciLogDbApplication);
21+
this.idsLocation = {};
22+
}
23+
24+
async createLocationSnippets(location: string) {
25+
const locationId = await this.createLogbook(location, {
26+
snippetType: 'location',
27+
location: location,
28+
});
29+
const acls = await this.computeAcls();
30+
const snippetId = await this.createLogbook(location, {
31+
snippetType: 'logbook',
32+
location: locationId,
33+
...acls,
34+
});
35+
await this.createLogbook(location, {
36+
snippetType: 'paragraph',
37+
parentId: snippetId,
38+
...acls,
39+
});
40+
}
41+
42+
private async computeAcls() {
43+
const basesnippetRepo = await this.getRepository(BasesnippetRepository);
44+
const acls = basesnippetRepo.acls.reduce(
45+
(currentValue: Record<string, ['acl']>, previousValue: string) => (
46+
(currentValue[previousValue] = ['acl']), currentValue
47+
),
48+
{},
49+
);
50+
return acls;
51+
}
52+
53+
private async createLogbook(
54+
location: string,
55+
snippetArgs: Partial<Location | Logbook | Paragraph>,
56+
) {
57+
const basesnippetRepo = await this.getRepository(BasesnippetRepository);
58+
59+
const snippet = await basesnippetRepo.create(
60+
{
61+
...snippetArgs,
62+
},
63+
{currentUser: {roles: ['admin']}},
64+
);
65+
this.idsLocation[snippet.id] = location;
66+
return snippet.id;
67+
}
68+
69+
async migrateSchema() {
70+
for (const location of this.locations) {
71+
await this.createLocationSnippets(location);
72+
}
73+
}
74+
}
75+
76+
describe('CreateFunctionalAccountsObserver', function (this: Suite) {
77+
this.timeout(5000);
78+
let app: TestFunctionalAccountsApp;
79+
let client: Client;
80+
const filePath = './functionalAccounts.json';
81+
let token: string;
82+
const sandbox = sinon.createSandbox();
83+
84+
function backupsFunctionalAccountsFile() {
85+
const functionalAccounts = fs.readFileSync(filePath, 'utf8');
86+
fs.writeFileSync(
87+
`${filePath}.bk`,
88+
JSON.stringify(JSON.parse(functionalAccounts), null, 2),
89+
'utf8',
90+
);
91+
}
92+
93+
function createFunctionalAccountsFile() {
94+
backupsFunctionalAccountsFile();
95+
const functionalAccounts = [
96+
{
97+
username: 'account1',
98+
firstName: 'account1',
99+
lastName: 'account1',
100+
password: 'account1@account1',
101+
email: 'account1@account1',
102+
roles: ['admin', 'any-authenticated-user'],
103+
location: 'location1',
104+
},
105+
{
106+
username: 'account2',
107+
firstName: 'account2',
108+
lastName: 'account2',
109+
password: 'account2@account2',
110+
email: 'account2@account2',
111+
roles: ['p123', 'any-authenticated-user'],
112+
unxGroup: 'unxGroup2',
113+
location: 'location2',
114+
},
115+
];
116+
fs.writeFileSync(
117+
filePath,
118+
JSON.stringify(functionalAccounts, null, 2),
119+
'utf8',
120+
);
121+
}
122+
123+
before('setupApplication', async () => {
124+
createFunctionalAccountsFile();
125+
({app, client} = await setupApplication<TestFunctionalAccountsApp>(
126+
{databaseSeeding: true},
127+
TestFunctionalAccountsApp,
128+
));
129+
token = await createUserToken(app, client, ['admin']);
130+
});
131+
132+
after(async () => {
133+
fs.copyFileSync(`${filePath}.bk`, filePath);
134+
fs.unlinkSync(`${filePath}.bk`);
135+
await clearDatabase(app);
136+
if (app != null) await app.stop();
137+
});
138+
139+
afterEach(() => {
140+
sandbox.restore();
141+
});
142+
143+
it('addAclsToExistingSnippetsFromAccount', async () => {
144+
await client
145+
.get('/basesnippets')
146+
.set('Authorization', 'Bearer ' + token)
147+
.expect(200)
148+
.then(result => {
149+
result.body.forEach((snippet: Basesnippet) => {
150+
if (
151+
snippet.snippetType === 'location' &&
152+
app.idsLocation[snippet.id] === 'location1'
153+
)
154+
expect(snippet.updateACL).to.eql(undefined);
155+
else if (
156+
snippet.snippetType === 'location' &&
157+
app.idsLocation[snippet.id] === 'location2'
158+
)
159+
expect(snippet.updateACL).to.eql(['unxGroup2']);
160+
else if (app.idsLocation[snippet.id] === 'location1') {
161+
expect(snippet.createACL).to.eql(['acl']);
162+
expect(snippet.readACL).to.eql(['acl']);
163+
expect(snippet.shareACL).to.eql(['acl']);
164+
expect(snippet.updateACL).to.eql(['acl']);
165+
expect(snippet.deleteACL).to.eql(['acl']);
166+
expect(snippet.adminACL).to.eql(['acl']);
167+
} else if (app.idsLocation[snippet.id] === 'location2') {
168+
expect(snippet.createACL).to.eql(['acl', 'unxGroup2']);
169+
expect(snippet.readACL).to.eql(['acl', 'unxGroup2']);
170+
expect(snippet.shareACL).to.eql(['acl', 'unxGroup2']);
171+
expect(snippet.updateACL).to.eql(['acl', 'unxGroup2']);
172+
expect(snippet.deleteACL).to.eql(['acl', 'unxGroup2']);
173+
expect(snippet.adminACL).to.eql(['acl', 'unxGroup2']);
174+
}
175+
});
176+
});
177+
});
178+
179+
it('migrateUnxGroup', async () => {
180+
const createFunctionalAccountsObserver: CreateFunctionalAccountsObserver =
181+
await app.get('lifeCycleObservers.CreateFunctionalAccountsObserver');
182+
const addAclsToExistingSnippetsFromAccountSpy = sandbox.spy(
183+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
184+
createFunctionalAccountsObserver as any,
185+
'addAclsToExistingSnippetsFromAccount',
186+
);
187+
await createFunctionalAccountsObserver.migrateUnxGroup();
188+
expect(addAclsToExistingSnippetsFromAccountSpy.callCount).to.eql(1);
189+
expect(addAclsToExistingSnippetsFromAccountSpy.args[0][0]).to.match({
190+
username: 'account2',
191+
firstName: 'account2',
192+
lastName: 'account2',
193+
email: 'account2@account2',
194+
unxGroup: 'unxGroup2',
195+
location: 'location2',
196+
});
197+
});
198+
});

sci-log-db/src/__tests__/acceptance/test-helper.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {BasesnippetRepository, TaskRepository} from '../../repositories';
1313
import {FileRepository} from '../../repositories/file.repository';
1414
import {JobRepository} from '../../repositories/job.repository';
1515

16-
export interface AppWithClient {
17-
app: SciLogDbApplication;
16+
export interface AppWithClient<T> {
17+
app: T;
1818
client: Client;
1919
}
2020

@@ -46,16 +46,17 @@ export const oidcOptions = {
4646
postLogoutRedirectUri: 'aRedirectUrl',
4747
};
4848

49-
export async function setupApplication(
49+
export async function setupApplication<T extends SciLogDbApplication>(
5050
options: ApplicationConfig = {},
51-
): Promise<AppWithClient> {
52-
const app = new SciLogDbApplication({
51+
appClass = SciLogDbApplication,
52+
): Promise<AppWithClient<T>> {
53+
const app = new appClass({
5354
rest: givenHttpServerConfig(),
54-
databaseSeeding: false,
5555
...options,
56-
});
56+
}) as T;
5757
await app.boot();
5858
app.dataSource(testdb);
59+
if (!options.dirtyDb) await clearDatabase(app);
5960
await app.start();
6061
const client = createRestAppClient(app);
6162
return {app, client};

sci-log-db/src/__tests__/testdb.datasource.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export const testdb: juggler.DataSource = new juggler.DataSource({
1111
database: 'testdb',
1212
useNewUrlParser: true,
1313
useUnifiedTopology: true,
14+
allowExtendedOperators: true,
1415
});

0 commit comments

Comments
 (0)