Skip to content

Commit 607a88f

Browse files
authored
Integration tests for imodel commands (#137)
* Added most of the missing integration tests for imodel commands. * Fixed some failing tests. * Updated documentation. * Fixed test error. * Increased test timeouts. * Fixed test not waiting until timeout. * Increased test timeouts. * Updated timeouts. * Updated timeout for named-version.test.ts before() hook. * Increased timeout for before() hooks in main-cases. * Increased timeout for a before() hook in access-control-native/group.test.ts * Reverted package.json script changes. * Shortened custom test timeouts and removed the in some places.
1 parent 9c74c66 commit 607a88f

37 files changed

Lines changed: 827 additions & 78 deletions

docs/imodel/connection/auth.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# itp imodel connection auth
22

3-
Ensures the user has a valid token for long-running connection tasks. This must be called before starting a connection run.
3+
Ensures the user has a valid token for long-running connection tasks. This must be called before starting a connection run with User authenticationType.
44

55
## Options
66

docs/imodel/connection/create.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Create a storage connection that describes files from storage to synchronize wit
1818
**Type:** `string` **Required:** Yes
1919

2020
- **`--authentication-type`**
21-
The authorization workflow type.
21+
The authorization workflow type. Default value is 'User'
2222
**Type:** `string` **Required:** No
2323
**Valid Values:** `"User"`, `"Service"`
2424

docs/imodel/connection/sourcefile/update.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ Update an existing source file in a storage connection of an iModel.
1717
The source file ID to update.
1818
**Type:** `string` **Required:** Yes
1919

20+
- **`--storage-file-id`**
21+
The storage file ID to update to.
22+
**Type:** `string` **Required:** Yes
23+
2024
## Examples
2125

2226
```bash
23-
itp imodel connection sourcefile update --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb --connector-type DWG
27+
itp imodel connection sourcefile update --connection-id bf4d8b36-25d7-4b72-b38b-12c1f0325f42 --source-file-id 297c8ab9-53a3-4fe5-adf8-79b4c1a95cbb --connector-type DWG --storage-file-id b67d9839-2663-4465-a425-d1541d32e4c7
2428
```
2529

2630
## API Reference

integration-tests/access-control-native/group.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ const tests = () => describe('group', () => {
1616
let groupId: string;
1717
const groupName = "Test Group";
1818
const groupDescription = "Test Group Description";
19-
before(async () => {
19+
before(async function() {
20+
this.timeout(5 * 60 * 1000);
2021
await nativeLoginToCli();
2122

2223
const iTwinName = `cli-itwin-integration-test-${new Date().toISOString()}`;
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3+
* See LICENSE.md in the project root for license terms and full copyright notice.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { runCommand } from '@oclif/test';
7+
import { expect } from 'chai';
8+
9+
import { authInfo } from '../../../src/services/synchronizationClient/models/connection-auth';
10+
import { storageConnection } from '../../../src/services/synchronizationClient/models/storage-connection';
11+
import { createFile, createIModel, createITwin, getRootFolderId } from '../../utils/helpers';
12+
import runSuiteIfMainModule from '../../utils/run-suite-if-main-module';
13+
14+
const tests = () => describe('imodel connection auth', () => {
15+
let testITwinId: string;
16+
let testIModelId: string;
17+
let rootFolderId: string;
18+
let testFileId: string;
19+
let connectionId: string;
20+
21+
before(async () => {
22+
const testITwin = await createITwin(`cli-itwin-integration-test-${new Date().toISOString()}`, 'Thing', 'Asset');
23+
testITwinId = testITwin.id as string;
24+
const testIModel = await createIModel(`cli-imodel-integration-test-${new Date().toISOString()}`, testITwinId);
25+
testIModelId = testIModel.id;
26+
rootFolderId = await getRootFolderId(testITwinId);
27+
const testFile = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip');
28+
testFileId = testFile.id as string;
29+
const { result: createdConnection} = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId} --connector-type MSTN -n TestConnection`);
30+
expect(createdConnection).to.not.be.undefined;
31+
connectionId = createdConnection!.id!;
32+
});
33+
34+
after(async () => {
35+
const { result: connectionDeleteResult } = await runCommand(`imodel connection delete --connection-id ${connectionId}`);
36+
const { result: fileDeleteResult} = await runCommand(`storage file delete --file-id ${testFileId}`);
37+
const { result: imodelDeleteResult } = await runCommand(`imodel delete --imodel-id ${testIModelId}`);
38+
const { result: itwinDeleteResult } = await runCommand(`itwin delete --itwin-id ${testITwinId}`);
39+
40+
expect(connectionDeleteResult).to.have.property('result', 'deleted');
41+
expect(fileDeleteResult).to.have.property('result', 'deleted');
42+
expect(imodelDeleteResult).to.have.property('result', 'deleted');
43+
expect(itwinDeleteResult).to.have.property('result', 'deleted');
44+
});
45+
46+
it('should get a connection', async () => {
47+
const { result } = await runCommand<authInfo>(`imodel connection auth`);
48+
expect(result?.isUserAuthorized).to.be.equal(true);
49+
});
50+
});
51+
52+
export default tests;
53+
54+
runSuiteIfMainModule(import.meta, tests);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3+
* See LICENSE.md in the project root for license terms and full copyright notice.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import runSuiteIfMainModule from "../../utils/run-suite-if-main-module";
7+
import createTests from './create.test'
8+
import deleteTests from './delete.test'
9+
import infoTests from './info.test'
10+
import listTests from './list.test'
11+
import sourcefileTests from './sourcefile.test'
12+
import updateTests from './update.test'
13+
14+
const tests = () => describe('connection', async () => {
15+
createTests();
16+
deleteTests();
17+
infoTests();
18+
listTests();
19+
sourcefileTests();
20+
updateTests();
21+
});
22+
23+
export default tests;
24+
25+
runSuiteIfMainModule(import.meta, tests);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3+
* See LICENSE.md in the project root for license terms and full copyright notice.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { runCommand } from '@oclif/test';
7+
import { expect } from 'chai';
8+
9+
import { storageConnection } from '../../../src/services/synchronizationClient/models/storage-connection';
10+
import { createFile, createIModel, createITwin, getRootFolderId } from '../../utils/helpers';
11+
import runSuiteIfMainModule from '../../utils/run-suite-if-main-module';
12+
13+
const tests = () => describe('create', () => {
14+
let testITwinId: string;
15+
let testIModelId: string;
16+
let rootFolderId: string;
17+
let testFileId: string;
18+
19+
before(async () => {
20+
const testITwin = await createITwin(`cli-itwin-integration-test--${new Date().toISOString()}`, 'Thing', 'Asset');
21+
testITwinId = testITwin.id as string;
22+
const testIModel = await createIModel(`cli-imodel-integration-test--${new Date().toISOString()}`, testITwinId);
23+
testIModelId = testIModel.id;
24+
rootFolderId = await getRootFolderId(testITwinId);
25+
const testFile = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip');
26+
testFileId = testFile.id as string;
27+
});
28+
29+
after(async () => {
30+
const { result: fileDeleteResult} = await runCommand(`storage file delete --file-id ${testFileId}`);
31+
const { result: imodelDeleteResult } = await runCommand(`imodel delete --imodel-id ${testIModelId}`);
32+
const { result: itwinDeleteResult } = await runCommand(`itwin delete --itwin-id ${testITwinId}`);
33+
34+
expect(fileDeleteResult).to.have.property('result', 'deleted');
35+
expect(imodelDeleteResult).to.have.property('result', 'deleted');
36+
expect(itwinDeleteResult).to.have.property('result', 'deleted');
37+
});
38+
39+
it('should create a connection', async () => {
40+
const { result: createdConnection } = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId} --connector-type MSTN -n TestConnection`);
41+
42+
expect(createdConnection).to.not.be.undefined;
43+
expect(createdConnection!.id).to.not.be.undefined;
44+
expect(createdConnection!.iModelId).to.be.equal(testIModelId);
45+
expect(createdConnection!.displayName).to.be.equal('TestConnection');
46+
expect(createdConnection!.authenticationType).to.be.equal('User');
47+
48+
const { result } = await runCommand(`imodel connection delete --connection-id ${createdConnection!.id}`);
49+
expect(result).to.have.property('result', 'deleted');
50+
});
51+
});
52+
53+
export default tests;
54+
55+
runSuiteIfMainModule(import.meta, tests);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3+
* See LICENSE.md in the project root for license terms and full copyright notice.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { runCommand } from '@oclif/test';
7+
import { expect } from 'chai';
8+
9+
import { storageConnection } from '../../../src/services/synchronizationClient/models/storage-connection';
10+
import { createFile, createIModel, createITwin, getRootFolderId } from '../../utils/helpers';
11+
import runSuiteIfMainModule from '../../utils/run-suite-if-main-module';
12+
13+
const tests = () => describe('delete', () => {
14+
let testITwinId: string;
15+
let testIModelId: string;
16+
let rootFolderId: string;
17+
let testFileId: string;
18+
let connectionId: string;
19+
20+
before(async () => {
21+
const testITwin = await createITwin(`cli-itwin-integration-test--${new Date().toISOString()}`, 'Thing', 'Asset');
22+
testITwinId = testITwin.id as string;
23+
const testIModel = await createIModel(`cli-imodel-integration-test--${new Date().toISOString()}`, testITwinId);
24+
testIModelId = testIModel.id;
25+
rootFolderId = await getRootFolderId(testITwinId);
26+
const testFile = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip');
27+
testFileId = testFile.id as string;
28+
const { result: createdConnection} = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId} --connector-type MSTN -n TestConnection`);
29+
expect(createdConnection).to.not.be.undefined;
30+
connectionId = createdConnection!.id!;
31+
});
32+
33+
after(async () => {
34+
const { result: fileDeleteResult} = await runCommand(`storage file delete --file-id ${testFileId}`);
35+
const { result: imodelDeleteResult } = await runCommand(`imodel delete --imodel-id ${testIModelId}`);
36+
const { result: itwinDeleteResult } = await runCommand(`itwin delete --itwin-id ${testITwinId}`);
37+
38+
expect(fileDeleteResult).to.have.property('result', 'deleted');
39+
expect(imodelDeleteResult).to.have.property('result', 'deleted');
40+
expect(itwinDeleteResult).to.have.property('result', 'deleted');
41+
});
42+
43+
it('should delete a connection', async () => {
44+
const { result } = await runCommand(`imodel connection delete --connection-id ${connectionId}`);
45+
expect(result).to.have.property('result', 'deleted');
46+
});
47+
});
48+
49+
export default tests;
50+
51+
runSuiteIfMainModule(import.meta, tests);

integration-tests/imodel/connection.test.ts renamed to integration-tests/imodel/connection/info.test.ts

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import { runCommand } from '@oclif/test';
77
import { expect } from 'chai';
88

9-
import { createFile, createIModel, createITwin, getRootFolderId } from '../utils/helpers';
10-
import runSuiteIfMainModule from '../utils/run-suite-if-main-module';
9+
import { storageConnection } from '../../../src/services/synchronizationClient/models/storage-connection';
10+
import { createFile, createIModel, createITwin, getRootFolderId } from '../../utils/helpers';
11+
import runSuiteIfMainModule from '../../utils/run-suite-if-main-module';
1112

12-
const tests = () => describe('connection', () => {
13+
const tests = () => describe('info', () => {
1314
let testITwinId: string;
1415
let testIModelId: string;
1516
let rootFolderId: string;
@@ -24,49 +25,33 @@ const tests = () => describe('connection', () => {
2425
rootFolderId = await getRootFolderId(testITwinId);
2526
const testFile = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip');
2627
testFileId = testFile.id as string;
28+
const { result: createdConnection} = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId} --connector-type MSTN -n TestConnection`);
29+
expect(createdConnection).to.not.be.undefined;
30+
connectionId = createdConnection!.id!;
2731
});
2832

2933
after(async () => {
34+
const { result: connectionDeleteResult } = await runCommand(`imodel connection delete --connection-id ${connectionId}`);
3035
const { result: fileDeleteResult} = await runCommand(`storage file delete --file-id ${testFileId}`);
3136
const { result: imodelDeleteResult } = await runCommand(`imodel delete --imodel-id ${testIModelId}`);
3237
const { result: itwinDeleteResult } = await runCommand(`itwin delete --itwin-id ${testITwinId}`);
3338

39+
expect(connectionDeleteResult).to.have.property('result', 'deleted');
3440
expect(fileDeleteResult).to.have.property('result', 'deleted');
3541
expect(imodelDeleteResult).to.have.property('result', 'deleted');
3642
expect(itwinDeleteResult).to.have.property('result', 'deleted');
3743
});
3844

39-
it('should add a connection', async () => {
40-
const { stdout } = await runCommand(`imodel connection create -m ${testIModelId} -f ${testFileId} --connector-type MSTN -n TestConnection`);
41-
const createdConnection = JSON.parse(stdout);
42-
43-
expect(createdConnection).to.not.be.undefined;
44-
expect(createdConnection).to.have.property('id');
45-
expect(createdConnection).to.have.property('iTwinId', testITwinId);
46-
expect(createdConnection).to.have.property('iModelId', testIModelId);
47-
expect(createdConnection).to.have.property('displayName', 'TestConnection');
48-
49-
connectionId = createdConnection.id;
50-
});
51-
5245
it('should get a connection', async () => {
5346
const { stdout } = await runCommand(`imodel connection info -c ${connectionId}`);
5447
const connection = JSON.parse(stdout);
5548

56-
expect(connection).to.not.be.undefined;
5749
expect(connection).to.not.be.undefined;
5850
expect(connection).to.have.property('id');
5951
expect(connection).to.have.property('iTwinId', testITwinId);
6052
expect(connection).to.have.property('iModelId', testIModelId);
6153
expect(connection).to.have.property('displayName', 'TestConnection');
6254
});
63-
64-
it('should delete a connection', async () => {
65-
const { stdout } = await runCommand(`imodel connection delete --connection-id ${connectionId}`);
66-
const result = JSON.parse(stdout);
67-
68-
expect(result.result).to.equal('deleted')
69-
});
7055
});
7156

7257
export default tests;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3+
* See LICENSE.md in the project root for license terms and full copyright notice.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { runCommand } from '@oclif/test';
7+
import { expect } from 'chai';
8+
9+
import { storageConnection } from '../../../src/services/synchronizationClient/models/storage-connection';
10+
import { storageConnectionListResponse } from '../../../src/services/synchronizationClient/models/storage-connection-response';
11+
import { createFile, createIModel, createITwin, getRootFolderId } from '../../utils/helpers';
12+
import runSuiteIfMainModule from '../../utils/run-suite-if-main-module';
13+
14+
const tests = () => describe('list', () => {
15+
let testITwinId: string;
16+
let testIModelId: string;
17+
let rootFolderId: string;
18+
let testFileId1: string;
19+
let testFileId2: string;
20+
let connectionId1: string;
21+
let connectionId2: string;
22+
23+
before(async () => {
24+
const testITwin = await createITwin(`cli-itwin-integration-test--${new Date().toISOString()}`, 'Thing', 'Asset');
25+
testITwinId = testITwin.id as string;
26+
const testIModel = await createIModel(`cli-imodel-integration-test--${new Date().toISOString()}`, testITwinId);
27+
testIModelId = testIModel.id;
28+
rootFolderId = await getRootFolderId(testITwinId);
29+
const testFile1 = await createFile(rootFolderId, 'test.zip', 'integration-tests/test.zip');
30+
testFileId1 = testFile1.id as string;
31+
const testFile2 = await createFile(rootFolderId, 'test.csv', 'integration-tests/test.csv');
32+
testFileId2 = testFile2.id as string;
33+
const { result: createdConnection1} = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId1} --connector-type MSTN -n TestConnection`);
34+
connectionId1 = createdConnection1!.id!;
35+
const { result: createdConnection2} = await runCommand<storageConnection>(`imodel connection create -m ${testIModelId} -f ${testFileId2} --connector-type MSTN -n TestConnection`);
36+
connectionId2 = createdConnection2!.id!;
37+
});
38+
39+
after(async () => {
40+
const { result: connectionDeleteResult1 } = await runCommand(`imodel connection delete --connection-id ${connectionId1}`);
41+
const { result: connectionDeleteResult2 } = await runCommand(`imodel connection delete --connection-id ${connectionId2}`);
42+
const { result: fileDeleteResult} = await runCommand(`storage file delete --file-id ${testFileId1}`);
43+
const { result: imodelDeleteResult } = await runCommand(`imodel delete --imodel-id ${testIModelId}`);
44+
const { result: itwinDeleteResult } = await runCommand(`itwin delete --itwin-id ${testITwinId}`);
45+
46+
expect(connectionDeleteResult1).to.have.property('result', 'deleted');
47+
expect(connectionDeleteResult2).to.have.property('result', 'deleted');
48+
expect(fileDeleteResult).to.have.property('result', 'deleted');
49+
expect(imodelDeleteResult).to.have.property('result', 'deleted');
50+
expect(itwinDeleteResult).to.have.property('result', 'deleted');
51+
});
52+
53+
it('should get all connections', async () => {
54+
const { result } = await runCommand<storageConnectionListResponse>(`imodel connection list -m ${testIModelId}`);
55+
expect(result).to.not.be.undefined;
56+
expect(result!.connections.length).to.be.equal(2);
57+
});
58+
59+
it('should get 1st connection', async () => {
60+
const { result: allConnections } = await runCommand<storageConnectionListResponse>(`imodel connection list -m ${testIModelId}`);
61+
expect(allConnections).to.not.be.undefined;
62+
expect(allConnections!.connections.length).to.be.equal(2);
63+
64+
const { result: filteredConnections } = await runCommand<storageConnectionListResponse>(`imodel connection list -m ${testIModelId} --top 1`);
65+
expect(filteredConnections).to.not.be.undefined;
66+
expect(filteredConnections!.connections.length).to.be.equal(1);
67+
expect(filteredConnections!.connections[0].id).to.be.equal(allConnections!.connections[0].id);
68+
});
69+
70+
it('should not get 1st connection', async () => {
71+
const { result: allConnections } = await runCommand<storageConnectionListResponse>(`imodel connection list -m ${testIModelId}`);
72+
expect(allConnections).to.not.be.undefined;
73+
expect(allConnections!.connections.length).to.be.equal(2);
74+
75+
const { result: filteredConnections } = await runCommand<storageConnectionListResponse>(`imodel connection list -m ${testIModelId} --skip 1`);
76+
expect(filteredConnections).to.not.be.undefined;
77+
expect(filteredConnections!.connections.length).to.be.equal(1);
78+
expect(filteredConnections!.connections[0].id).to.be.equal(allConnections!.connections[1].id);
79+
});
80+
});
81+
82+
export default tests;
83+
84+
runSuiteIfMainModule(import.meta, tests);

0 commit comments

Comments
 (0)