Skip to content

Commit 2352cf7

Browse files
committed
add e2e for encryption
1 parent 45cfdbc commit 2352cf7

File tree

8 files changed

+184
-76
lines changed

8 files changed

+184
-76
lines changed

tests/e2e/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ NOTIFICATION_UPDATE_URL=https://s3.amazonaws.com/redisinsight.test/public/tests/
55
NOTIFICATION_SYNC_INTERVAL=30000
66
RI_FEATURES_CONFIG_URL=http://static-server:5551/remote/features-config.json
77
RI_FEATURES_CONFIG_SYNC_INTERVAL=50000
8+
RI_ENCRYPTION_KEY=process.env.E2E_RI_ENCRYPTION_KEY
Lines changed: 99 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,113 @@
1-
import { workingDirectory } from '../helpers/conf';
21
import * as sqlite3 from 'sqlite3';
2+
import { workingDirectory } from '../helpers/conf';
33

44
const dbPath = `${workingDirectory}/redisinsight.db`;
55

6-
/**
7-
* Update table column value into local DB
8-
* @param tableName The name of table in DB
9-
* @param columnName The name of column in table
10-
* @param value Value to update in table
11-
*/
12-
export async function updateColumnValueInDBTable(tableName: string, columnName: string, value: number | string): Promise<void> {
13-
const db = new sqlite3.Database(dbPath);
14-
const query = `UPDATE ${tableName} SET ${columnName} = ${value}`;
6+
export class DatabaseScripts {
7+
/**
8+
* Find the row index in a table based on a condition in another column
9+
* @param dbTableParameters The sqlite database table parameters
10+
* @returns The index of the row matching the condition
11+
*/
12+
static async getRowIndexFromTableInDB(dbTableParameters: DbTableParameters): Promise<number | null> {
13+
const db = new sqlite3.Database(dbPath);
14+
const query = `SELECT rowid FROM ${dbTableParameters.tableName} WHERE ${dbTableParameters.conditionColumnName} = ?`;
1515

16-
return new Promise<void>((resolve, reject) => {
17-
db.run(query, (err: { message: string }) => {
18-
if (err) {
19-
reject(new Error(`Error during changing ${columnName} column value: ${err.message}`));
20-
} else {
21-
db.close();
22-
resolve();
23-
}
16+
return new Promise<number | null>((resolve, reject) => {
17+
db.get(query, [dbTableParameters.conditionColumnValue], (err: { message: string }, row: any) => {
18+
if (err) {
19+
reject(new Error(`Error during finding row index: ${err.message}`));
20+
}
21+
else {
22+
db.close();
23+
resolve(row ? row.rowid : null); // Return the rowid if a row matches the condition
24+
}
25+
});
2426
});
25-
});
26-
}
27-
28-
/**
29-
* Get Column value from table in local Database
30-
* @param tableName The name of table in DB
31-
* @param columnName The name of column in table
32-
*/
33-
export async function getColumnValueFromTableInDB(tableName: string, columnName: string): Promise<any> {
34-
const db = new sqlite3.Database(dbPath);
35-
const query = `SELECT ${columnName} FROM ${tableName}`;
27+
}
28+
/**
29+
* Update table column value into local DB for a specific row
30+
* @param dbTableParameters The sqlite database table parameters
31+
*/
32+
static async updateColumnValueInDBTable(dbTableParameters: DbTableParameters): Promise<void> {
33+
const rowIndex = await this.getRowIndexFromTableInDB(dbTableParameters);
34+
const db = new sqlite3.Database(dbPath);
35+
const query = `UPDATE ${dbTableParameters.tableName} SET ${dbTableParameters.columnName} = ? WHERE rowid = ?`;
3636

37-
return new Promise<void>((resolve, reject) => {
38-
db.get(query, (err: { message: string }, row: any) => {
39-
if (err) {
40-
reject(new Error(`Error during getting ${columnName} column value: ${err.message}`));
41-
} else {
42-
const columnValue = row[columnName];
43-
db.close();
44-
resolve(columnValue);
45-
}
37+
return new Promise<void>((resolve, reject) => {
38+
db.run(query, [dbTableParameters.rowValue, rowIndex], (err: { message: string }) => {
39+
if (err) {
40+
reject(new Error(`Error during changing ${dbTableParameters.columnName} column value: ${err.message}`));
41+
}
42+
else {
43+
db.close();
44+
resolve();
45+
}
46+
});
4647
});
47-
});
48-
}
48+
}
4949

50-
/**
51-
* Delete all rows from table in local DB
52-
* @param tableName The name of table in DB
53-
*/
54-
export async function deleteRowsFromTableInDB(tableName: string): Promise<void> {
55-
const db = new sqlite3.Database(dbPath);
56-
const query = `DELETE FROM ${tableName}`;
50+
/**
51+
* Get Column value from table in local Database
52+
* @param dbTableParameters The sqlite database table parameters
53+
*/
54+
static async getColumnValueFromTableInDB(dbTableParameters: DbTableParameters): Promise<any> {
55+
const rowIndex = await DatabaseScripts.getRowIndexFromTableInDB(dbTableParameters);
56+
if (rowIndex !== null) {
57+
const db = new sqlite3.Database(dbPath);
58+
const query = `SELECT ${dbTableParameters.columnName} FROM ${dbTableParameters.tableName} WHERE rowid = ?`;
59+
60+
return new Promise<void>((resolve, reject) => {
61+
db.get(query, [rowIndex], (err: { message: string }, row: any) => {
62+
if (err) {
63+
reject(new Error(`Error during getting ${dbTableParameters.columnName} column value: ${err.message}`));
64+
}
65+
else {
66+
const columnValue = row[dbTableParameters.columnName!];
67+
db.close();
68+
resolve(columnValue);
69+
}
70+
});
71+
});
72+
}
73+
throw new Error(`No matching row found for the given condition in ${dbTableParameters.tableName}`);
5774

58-
return new Promise<void>((resolve, reject) => {
75+
}
5976

77+
/**
78+
* Delete all rows from table in local DB
79+
* @param dbTableParameters The sqlite database table parameters
80+
*/
81+
static async deleteRowsFromTableInDB(dbTableParameters: DbTableParameters): Promise<void> {
82+
const db = new sqlite3.Database(dbPath);
83+
const query = `DELETE FROM ${dbTableParameters.tableName}`;
6084

61-
db.run(query, (err: { message: string }) => {
62-
if (err) {
63-
reject(new Error(`Error during ${tableName} table rows deletion: ${err.message}`));
64-
} else {
65-
db.close();
66-
resolve();
67-
}
85+
return new Promise<void>((resolve, reject) => {
86+
87+
db.run(query, (err: { message: string }) => {
88+
if (err) {
89+
reject(new Error(`Error during ${dbTableParameters.tableName} table rows deletion: ${err.message}`));
90+
}
91+
else {
92+
db.close();
93+
resolve();
94+
}
95+
});
6896
});
69-
});
97+
}
7098
}
99+
/**
100+
* Add new database parameters
101+
* @param tableName The name of table in DB
102+
* @param columnName The name of column in table
103+
* @param rowValue Value to update in table
104+
* @param conditionColumnName The name of the column to search
105+
* @param conditionColumnValue The value to match in the column
106+
*/
107+
export type DbTableParameters = {
108+
tableName: string,
109+
columnName?: string,
110+
rowValue?: string | number,
111+
conditionColumnName?: string,
112+
conditionColumnValue?: string
113+
};

tests/e2e/helpers/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { DatabaseScripts, DbTableParameters } from './database-scripts';
2+
import { Common } from './common';
3+
import { DatabaseHelper } from './database';
4+
import { Telemetry } from './telemetry';
5+
6+
export {
7+
DatabaseScripts,
8+
DbTableParameters,
9+
Common,
10+
DatabaseHelper,
11+
Telemetry
12+
};

tests/e2e/helpers/insights.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
import * as fs from 'fs-extra';
21
import * as path from 'path';
2+
import * as fs from 'fs-extra';
33
import { BasePage } from '../pageObjects';
4-
import { deleteRowsFromTableInDB, updateColumnValueInDBTable } from './database-scripts';
54
import { syncFeaturesApi } from './api/api-info';
5+
import { DatabaseScripts, DbTableParameters } from './database-scripts';
66

77
const basePage = new BasePage();
8+
const dbTableParams: DbTableParameters = {
9+
tableName: 'features_config',
10+
columnName: 'controlNumber',
11+
conditionColumnName: 'id',
12+
conditionColumnValue: '1'
13+
};
814

915
/**
1016
* Update features-config file for static server
@@ -21,7 +27,7 @@ export async function modifyFeaturesConfigJson(filePath: string): Promise<void>
2127
fs.writeFileSync(targetFilePath, fs.readFileSync(filePath));
2228
resolve();
2329
}
24-
catch (err) {
30+
catch (err: any) {
2531
reject(new Error(`Error updating remote config file: ${err.message}`));
2632
}
2733
});
@@ -32,10 +38,8 @@ export async function modifyFeaturesConfigJson(filePath: string): Promise<void>
3238
* @param controlNumber Control number to update
3339
*/
3440
export async function updateControlNumber(controlNumber: number): Promise<void> {
35-
const featuresConfigTable = 'features_config';
36-
3741
await syncFeaturesApi();
38-
await updateColumnValueInDBTable(featuresConfigTable, 'controlNumber', controlNumber);
42+
await DatabaseScripts.updateColumnValueInDBTable({ ...dbTableParams, rowValue: controlNumber });
3943
await syncFeaturesApi();
4044
await basePage.reloadPage();
4145
}
@@ -44,10 +48,9 @@ export async function updateControlNumber(controlNumber: number): Promise<void>
4448
* Refresh test data for features sync
4549
*/
4650
export async function refreshFeaturesTestData(): Promise<void> {
47-
const featuresConfigTable = 'features_config';
4851
const defaultConfigPath = path.join('.', 'test-data', 'features-configs', 'insights-default-remote.json');
4952

5053
await modifyFeaturesConfigJson(defaultConfigPath);
51-
await deleteRowsFromTableInDB(featuresConfigTable);
54+
await DatabaseScripts.deleteRowsFromTableInDB(dbTableParams);
5255
await syncFeaturesApi();
5356
}

tests/e2e/tests/electron/regression/database/cloud-sso.e2e.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@ import { rte } from '../../../../helpers/constants';
44
import { DatabaseHelper } from '../../../../helpers/database';
55
import { commonUrl } from '../../../../helpers/conf';
66
import { DatabaseAPIRequests } from '../../../../helpers/api/api-database';
7-
import { deleteRowsFromTableInDB } from '../../../../helpers/database-scripts';
7+
import { DatabaseScripts } from '../../../../helpers/database-scripts';
88
import { modifyFeaturesConfigJson, updateControlNumber } from '../../../../helpers/insights';
99

1010
const myRedisDatabasePage = new MyRedisDatabasePage();
1111
const databaseHelper = new DatabaseHelper();
1212
const databaseAPIRequests = new DatabaseAPIRequests();
1313
const welcomePage = new WelcomePage();
1414

15-
const featuresConfigTable = 'features_config';
1615
const pathes = {
1716
defaultRemote: path.join('.', 'test-data', 'features-configs', 'insights-default-remote.json'),
1817
dockerConfig: path.join('.', 'test-data', 'features-configs', 'sso-docker-build.json'),
@@ -32,7 +31,7 @@ fixture `Cloud SSO`
3231
// Update remote config .json to default
3332
await modifyFeaturesConfigJson(pathes.defaultRemote);
3433
// Clear features config table
35-
await deleteRowsFromTableInDB(featuresConfigTable);
34+
await DatabaseScripts.deleteRowsFromTableInDB({ tableName: 'features_config' });
3635
});
3736
test('Verify that user can see SSO feature if it is enabled in feature config', async t => {
3837
// Update remote config .json to config with buildType filter excluding current app build

tests/e2e/tests/electron/regression/insights/feature-flag.e2e.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import { rte } from '../../../../helpers/constants';
44
import { DatabaseHelper } from '../../../../helpers/database';
55
import { commonUrl, ossStandaloneV5Config } from '../../../../helpers/conf';
66
import { DatabaseAPIRequests } from '../../../../helpers/api/api-database';
7-
import { deleteRowsFromTableInDB } from '../../../../helpers/database-scripts';
7+
import { DatabaseScripts } from '../../../../helpers/database-scripts';
88
import { modifyFeaturesConfigJson, updateControlNumber } from '../../../../helpers/insights';
99

1010
const browserPage = new BrowserPage();
1111
const databaseHelper = new DatabaseHelper();
1212
const databaseAPIRequests = new DatabaseAPIRequests();
1313

14-
const featuresConfigTable = 'features_config';
1514
const pathes = {
1615
defaultRemote: path.join('.', 'test-data', 'features-configs', 'insights-default-remote.json'),
1716
dockerConfig: path.join('.', 'test-data', 'features-configs', 'insights-docker-build.json'),
@@ -29,7 +28,7 @@ fixture `Feature flag`
2928
// Update remote config .json to default
3029
await modifyFeaturesConfigJson(pathes.defaultRemote);
3130
// Clear features config table
32-
await deleteRowsFromTableInDB(featuresConfigTable);
31+
await DatabaseScripts.deleteRowsFromTableInDB({ tableName: 'features_config' });
3332
});
3433
test('Verify that Insights panel can be displayed for Electron app according to filters', async t => {
3534
// Update remote config .json to config with buildType filter excluding current app build
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { rte } from '../../../../helpers/constants';
2+
import { MyRedisDatabasePage } from '../../../../pageObjects';
3+
import {
4+
commonUrl,
5+
ossStandaloneConfig
6+
} from '../../../../helpers/conf';
7+
import { DatabaseHelper } from '../../../../helpers/database';
8+
import { DatabaseAPIRequests } from '../../../../helpers/api/api-database';
9+
import { DatabaseScripts, DbTableParameters } from '../../../../helpers/database-scripts';
10+
11+
const myRedisDatabasePage = new MyRedisDatabasePage();
12+
const databaseHelper = new DatabaseHelper();
13+
const databaseAPIRequests = new DatabaseAPIRequests();
14+
15+
const dbTableParams: DbTableParameters = {
16+
tableName: 'database_instance',
17+
columnName: 'caCertId',
18+
rowValue: 'invalid',
19+
conditionColumnName: 'name',
20+
conditionColumnValue: ossStandaloneConfig.databaseName
21+
};
22+
23+
fixture `Encryption`
24+
.meta({ type: 'critical_path', rte: rte.none })
25+
.page(commonUrl)
26+
.beforeEach(async() => {
27+
await databaseHelper.acceptLicenseTerms();
28+
await databaseAPIRequests.addNewStandaloneDatabaseApi(ossStandaloneConfig);
29+
await myRedisDatabasePage.reloadPage();
30+
})
31+
.afterEach(async() => {
32+
await databaseHelper.deleteDatabase(ossStandaloneConfig.databaseName);
33+
});
34+
test('Verify that data encrypted using KEY', async t => {
35+
const decryptionError = 'Unable to decrypt data';
36+
// Connect to DB
37+
await myRedisDatabasePage.clickOnDBByName(ossStandaloneConfig.databaseName);
38+
await t.click(myRedisDatabasePage.NavigationPanel.myRedisDBButton);
39+
40+
await DatabaseScripts.updateColumnValueInDBTable(dbTableParams);
41+
// Verify that Encription by KEY applied for connection if RI_ENCRYPTION_KEY variable exists
42+
await t.expect(await DatabaseScripts.getColumnValueFromTableInDB({ ...dbTableParams, columnName: 'encryption' })).eql('KEY', 'Encription is not applied by Key');
43+
await databaseHelper.clickOnEditDatabaseByName(ossStandaloneConfig.databaseName);
44+
await t.expect(myRedisDatabasePage.Toast.toastError.textContent).contains(decryptionError, 'Invalid encrypted field is decrypted');
45+
});

0 commit comments

Comments
 (0)