-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(south): create backend endpoint and repository for generic south…
… connector
- Loading branch information
1 parent
18fde83
commit c95f95f
Showing
18 changed files
with
911 additions
and
192 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* DTO for South connectors | ||
*/ | ||
export interface SouthConnectorDTO { | ||
id: string; | ||
name: string; | ||
type: string; | ||
description: string; | ||
enabled: boolean; | ||
settings: object; | ||
} | ||
|
||
/** | ||
* Command DTO for South connector | ||
*/ | ||
export interface SouthConnectorCommandDTO { | ||
name: string; | ||
type: string; | ||
description: string; | ||
enabled: boolean; | ||
settings: object; | ||
} | ||
|
||
/** | ||
* DTO used for South scan (a point/query/regexp and its settings linked to a scan mode) | ||
*/ | ||
export interface SouthScanDTO { | ||
id: string; | ||
name: string; | ||
southId: string; | ||
settings: object; | ||
scanModeId: string; | ||
} | ||
|
||
/** | ||
* Command DTO used for South scan (a point/query/folder and its settings linked to a scan mode) | ||
*/ | ||
export interface SouthScanCommandDTO { | ||
southId: string; | ||
name: string; | ||
settings: object; | ||
scanModeId: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import SqliteDatabaseMock from "../tests/__mocks__/database.mock"; | ||
import { generateRandomId } from "./utils"; | ||
import { | ||
SouthConnectorCommandDTO, | ||
SouthConnectorDTO, | ||
} from "../model/south-connector.model"; | ||
import SouthConnectorRepository from "./south-connector.repository"; | ||
|
||
jest.mock("../tests/__mocks__/database.mock"); | ||
jest.mock("./utils", () => ({ | ||
generateRandomId: jest.fn(() => "123456"), | ||
})); | ||
|
||
let database; | ||
let repository: SouthConnectorRepository; | ||
describe("South connector repository", () => { | ||
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
database = new SqliteDatabaseMock(); | ||
repository = new SouthConnectorRepository(database); | ||
}); | ||
|
||
it("should properly init south connector table", () => { | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"CREATE TABLE IF NOT EXISTS south_connector (id TEXT PRIMARY KEY, name TEXT, type TEXT, description TEXT, " + | ||
"enabled INTEGER, settings TEXT);" | ||
); | ||
expect(database.run).toHaveBeenCalledTimes(1); | ||
}); | ||
|
||
it("should properly get south connectors", () => { | ||
const expectedValue: Array<SouthConnectorDTO> = [ | ||
{ | ||
id: "id1", | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: {}, | ||
}, | ||
{ | ||
id: "id2", | ||
name: "south2", | ||
type: "SouthConnector", | ||
description: "My second south connector", | ||
enabled: true, | ||
settings: {}, | ||
}, | ||
]; | ||
database.all.mockReturnValueOnce([ | ||
{ | ||
id: "id1", | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: JSON.stringify({}), | ||
}, | ||
{ | ||
id: "id2", | ||
name: "south2", | ||
type: "SouthConnector", | ||
description: "My second south connector", | ||
enabled: true, | ||
settings: JSON.stringify({}), | ||
}, | ||
]); | ||
const southConnectors = repository.getSouthConnectors(); | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"SELECT id, name, type, description, enabled, settings FROM south_connector;" | ||
); | ||
expect(southConnectors).toEqual(expectedValue); | ||
}); | ||
|
||
it("should properly get a south connector", () => { | ||
const expectedValue: SouthConnectorDTO = { | ||
id: "id1", | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: {}, | ||
}; | ||
database.get.mockReturnValueOnce({ | ||
id: "id1", | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: JSON.stringify({}), | ||
}); | ||
const southConnector = repository.getSouthConnector("id1"); | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"SELECT id, name, type, description, enabled, settings FROM south_connector WHERE id = ?;" | ||
); | ||
expect(database.get).toHaveBeenCalledWith("id1"); | ||
expect(southConnector).toEqual(expectedValue); | ||
}); | ||
|
||
it("should create a south connector", () => { | ||
const command: SouthConnectorCommandDTO = { | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: {}, | ||
}; | ||
repository.createSouthConnector(command); | ||
expect(generateRandomId).toHaveBeenCalledWith(6); | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"INSERT INTO south_connector (id, name, type, description, enabled, settings) VALUES (?, ?, ?, ?, ?, ?);" | ||
); | ||
expect(database.run).toHaveBeenCalledWith( | ||
"123456", | ||
command.name, | ||
command.type, | ||
command.description, | ||
+command.enabled, | ||
JSON.stringify(command.settings) | ||
); | ||
|
||
expect(database.prepare).toHaveBeenCalledWith( | ||
"SELECT id, name, type, description, enabled, settings FROM south_connector WHERE ROWID = ?;" | ||
); | ||
}); | ||
|
||
it("should update a south connector", () => { | ||
const command: SouthConnectorCommandDTO = { | ||
name: "south1", | ||
type: "SouthConnector", | ||
description: "My south connector", | ||
enabled: true, | ||
settings: {}, | ||
}; | ||
repository.updateSouthConnector("id1", command); | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"UPDATE south_connector SET name = ?, description = ?, enabled = ?, settings = ? WHERE id = ?;" | ||
); | ||
expect(database.run).toHaveBeenCalledWith( | ||
command.name, | ||
command.description, | ||
+command.enabled, | ||
JSON.stringify(command.settings), | ||
"id1" | ||
); | ||
}); | ||
|
||
it("should delete a south connector", () => { | ||
repository.deleteSouthConnector("id1"); | ||
expect(database.prepare).toHaveBeenCalledWith( | ||
"DELETE FROM south_connector WHERE id = ?;" | ||
); | ||
expect(database.run).toHaveBeenCalledWith("id1"); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { generateRandomId } from "./utils"; | ||
import { | ||
SouthConnectorCommandDTO, | ||
SouthConnectorDTO, | ||
} from "../model/south-connector.model"; | ||
|
||
export const SOUTH_CONNECTOR_TABLE = "south_connector"; | ||
|
||
/** | ||
* Repository used for South connectors (Data sources) | ||
*/ | ||
export default class SouthConnectorRepository { | ||
private readonly database; | ||
constructor(database) { | ||
this.database = database; | ||
const query = | ||
`CREATE TABLE IF NOT EXISTS ${SOUTH_CONNECTOR_TABLE} (id TEXT PRIMARY KEY, name TEXT, type TEXT, description TEXT, ` + | ||
`enabled INTEGER, settings TEXT);`; | ||
this.database.prepare(query).run(); | ||
} | ||
|
||
/** | ||
* Retrieve all South connectors | ||
*/ | ||
getSouthConnectors(): Array<SouthConnectorDTO> { | ||
const query = `SELECT id, name, type, description, enabled, settings FROM ${SOUTH_CONNECTOR_TABLE};`; | ||
return this.database | ||
.prepare(query) | ||
.all() | ||
.map((result) => ({ | ||
id: result.id, | ||
name: result.name, | ||
type: result.type, | ||
description: result.description, | ||
enabled: result.enabled, | ||
settings: JSON.parse(result.settings), | ||
})); | ||
} | ||
|
||
/** | ||
* Retrieve a South connector by its ID | ||
*/ | ||
getSouthConnector(id: string): SouthConnectorDTO { | ||
const query = `SELECT id, name, type, description, enabled, settings FROM ${SOUTH_CONNECTOR_TABLE} WHERE id = ?;`; | ||
const result = this.database.prepare(query).get(id); | ||
return { | ||
id: result.id, | ||
name: result.name, | ||
type: result.type, | ||
description: result.description, | ||
enabled: result.enabled, | ||
settings: JSON.parse(result.settings), | ||
}; | ||
} | ||
|
||
/** | ||
* Create a South connector with a random generated ID | ||
*/ | ||
createSouthConnector(command: SouthConnectorCommandDTO): SouthConnectorDTO { | ||
const id = generateRandomId(6); | ||
const insertQuery = | ||
`INSERT INTO ${SOUTH_CONNECTOR_TABLE} (id, name, type, description, enabled, settings) ` + | ||
`VALUES (?, ?, ?, ?, ?, ?);`; | ||
const insertResult = this.database | ||
.prepare(insertQuery) | ||
.run( | ||
id, | ||
command.name, | ||
command.type, | ||
command.description, | ||
+command.enabled, | ||
JSON.stringify(command.settings) | ||
); | ||
|
||
const query = `SELECT id, name, type, description, enabled, settings FROM ${SOUTH_CONNECTOR_TABLE} WHERE ROWID = ?;`; | ||
const result = this.database | ||
.prepare(query) | ||
.get(insertResult.lastInsertRowid); | ||
return { | ||
id: result.id, | ||
name: result.name, | ||
type: result.type, | ||
description: result.description, | ||
enabled: result.enabled, | ||
settings: JSON.parse(result.settings), | ||
}; | ||
} | ||
|
||
/** | ||
* Update a South connector by its ID | ||
*/ | ||
updateSouthConnector(id: string, command: SouthConnectorCommandDTO): void { | ||
const query = `UPDATE ${SOUTH_CONNECTOR_TABLE} SET name = ?, description = ?, enabled = ?, settings = ? WHERE id = ?;`; | ||
return this.database | ||
.prepare(query) | ||
.run( | ||
command.name, | ||
command.description, | ||
+command.enabled, | ||
JSON.stringify(command.settings), | ||
id | ||
); | ||
} | ||
|
||
/** | ||
* Delete a South Connector by its ID | ||
*/ | ||
deleteSouthConnector(id: string): void { | ||
const query = `DELETE FROM ${SOUTH_CONNECTOR_TABLE} WHERE id = ?;`; | ||
return this.database.prepare(query).run(id); | ||
} | ||
} |
Oops, something went wrong.