Skip to content

Commit 85f89ba

Browse files
committed
test: strengthen project packaging assertions
1 parent 69714c7 commit 85f89ba

2 files changed

Lines changed: 47 additions & 26 deletions

File tree

‎packages/backend-core/src/security/tests/encryption.spec.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { tmpdir } from "os"
1313
import { join } from "path"
1414

1515
describe("encryption", () => {
16-
it("should throw an error if API encryption key is not set", () => {
16+
it("uses the JWT secret as the default API encryption key", () => {
1717
const jwt = getSecret(SecretOption.API)
1818
expect(jwt).toBe(env.JWT_SECRET?.export().toString())
1919
})

‎packages/server/src/api/routes/tests/project.spec.ts‎

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ import {
1616
isWebhookTrigger,
1717
OAuth2CredentialsMethod,
1818
OAuth2GrantType,
19+
PASSWORD_REPLACEMENT,
1920
RestAuthType,
2021
SourceName,
2122
ToolExecutionPrincipal,
2223
type Automation,
24+
type Datasource,
2325
type EmailTrigger,
2426
type EmailTriggerInputs,
2527
type Project,
2628
type ProjectPackageDependencyIndex,
29+
type Query,
2730
type Webhook,
2831
} from "@budibase/types"
2932
import { Header, helpers } from "@budibase/shared-core"
@@ -571,10 +574,6 @@ describe("/projects", () => {
571574
...basicDatasource().datasource,
572575
projectIds,
573576
})
574-
const query = await config.api.query.save({
575-
...basicQuery(datasource._id!),
576-
projectIds,
577-
})
578577

579578
await config.api.project.delete(project._id, project._rev)
580579

@@ -589,14 +588,12 @@ describe("/projects", () => {
589588
const fetchedAgent = agents.find(existing => existing._id === agent._id)
590589
const fetchedTable = await config.api.table.get(table._id!)
591590
const fetchedDatasource = await config.api.datasource.get(datasource._id!)
592-
const fetchedQuery = await config.api.query.get(query._id!)
593591

594592
expect(fetchedWorkspaceApp.projectIds).toEqual(expectedProjectIds)
595593
expect(fetchedAutomation.projectIds).toEqual(expectedProjectIds)
596594
expect(fetchedAgent?.projectIds).toEqual(expectedProjectIds)
597595
expect(fetchedTable.projectIds).toEqual(expectedProjectIds)
598596
expect(fetchedDatasource.projectIds).toEqual(expectedProjectIds)
599-
expect(fetchedQuery.projectIds).toBeUndefined()
600597
})
601598
})
602599

@@ -853,14 +850,26 @@ describe("/projects", () => {
853850
})
854851
})
855852

856-
it("strips query assignments", async () => {
853+
it("clears stored query assignments when updates omit project ids", async () => {
857854
await withProjectsEnabled(async () => {
858855
const { project } = await config.api.project.create({
859856
name: "Operations",
860857
})
861-
const { query } = await createAssignedResources(project._id)
858+
const datasource = await config.createDatasource()
859+
const query = await config.api.query.save(basicQuery(datasource._id))
860+
await config.doInContext(config.getDevWorkspaceId(), async () => {
861+
const persistedQuery = await context
862+
.getWorkspaceDB()
863+
.get<Query>(query._id!)
864+
await context.getWorkspaceDB().put({
865+
...persistedQuery,
866+
projectIds: [project._id],
867+
})
868+
})
869+
870+
const persistedQuery = await config.api.query.get(query._id!)
862871

863-
const { projectIds: _queryProjectIds, ...queryUpdate } = query
872+
const { projectIds: _queryProjectIds, ...queryUpdate } = persistedQuery
864873
const updatedQuery = await config.api.query.save({
865874
...queryUpdate,
866875
name: "Ops query updated",
@@ -1104,7 +1113,7 @@ describe("/projects", () => {
11041113
},
11051114
},
11061115
])(
1107-
"sanitises email credentials and remaps $name after import",
1116+
"sanitises email credentials and restores portable settings for $name",
11081117
async ({ credentials, includeDatasource }) => {
11091118
await withProjectsEnabled(async () => {
11101119
const project = await createAssignedProject()
@@ -1303,7 +1312,7 @@ describe("/projects", () => {
13031312
const exportedDatasource = JSON.parse(
13041313
files.get(`docs/datasource/${datasource._id}.json`)!.toString()
13051314
)
1306-
expect(exportedDatasource.config.password).not.toContain("super-secret")
1315+
expect(exportedDatasource.config.password).toBe(PASSWORD_REPLACEMENT)
13071316

13081317
const exportedQuery = JSON.parse(
13091318
files.get(`docs/query/${query._id}.json`)!.toString()
@@ -1384,19 +1393,16 @@ describe("/projects", () => {
13841393
) as ProjectPackageDependencyIndex
13851394
expect(dependencyIndex.rootProjectId).toBe(project._id)
13861395
expect(
1387-
dependencyIndex.directMembers.map(resource => resource.id)
1396+
dependencyIndex.directMembers.map(resource => resource.id).sort()
13881397
).toEqual(
1389-
expect.arrayContaining([
1398+
[
13901399
datasource._id,
13911400
table._id,
13921401
automation._id,
13931402
agent._id,
13941403
workspaceApp._id,
1395-
])
1404+
].sort()
13961405
)
1397-
expect(
1398-
dependencyIndex.directMembers.map(resource => resource.id)
1399-
).not.toContain(query._id)
14001406
expect(
14011407
dependencyIndex.resources[datasource._id!]!.dependencies.map(
14021408
resource => resource.id
@@ -1801,6 +1807,9 @@ describe("/projects", () => {
18011807
await config.withHeaders(
18021808
{ [Header.WORKSPACE_ID]: destinationWorkspaceId },
18031809
async () => {
1810+
const tableIds = [table._id!]
1811+
const viewIds = [view.id]
1812+
const rowActionIds = [rowAction.id]
18041813
for (let importIndex = 0; importIndex < 2; importIndex++) {
18051814
const imported = await config.api.project.import(body)
18061815
const importedTableId = imported.resources.table![0]
@@ -1815,7 +1824,6 @@ describe("/projects", () => {
18151824
)!
18161825

18171826
expect(resolvedView.tableId).toBe(importedTableId)
1818-
expect(importedView.id).not.toBe(view.id)
18191827
expect(importedScreen.props._children![1].table).toMatchObject({
18201828
id: importedView.id,
18211829
tableId: importedTableId,
@@ -1833,7 +1841,6 @@ describe("/projects", () => {
18331841
automationId: imported.resources.automation![0],
18341842
allowedSources: [importedTableId, importedView.id],
18351843
})
1836-
expect(importedAction.id).not.toBe(rowAction.id)
18371844
expect(Object.keys(importedRowActions.actions)).toEqual([
18381845
importedAction.id,
18391846
])
@@ -1848,7 +1855,13 @@ describe("/projects", () => {
18481855
}
18491856
expect(triggerInputs.tableId).toBe(imported.resources.table?.[0])
18501857
expect(triggerInputs.rowActionId).toBe(importedAction.id)
1858+
tableIds.push(importedTableId)
1859+
viewIds.push(importedView.id)
1860+
rowActionIds.push(importedAction.id)
18511861
}
1862+
expect(new Set(tableIds).size).toBe(3)
1863+
expect(new Set(viewIds).size).toBe(3)
1864+
expect(new Set(rowActionIds).size).toBe(3)
18521865
}
18531866
)
18541867
})
@@ -2116,11 +2129,15 @@ describe("/projects", () => {
21162129
imported.project._id,
21172130
])
21182131

2119-
const importedDatasource = await config.api.datasource.get(
2120-
imported.resources.datasource?.[0]!
2132+
const importedDatasource = await config.doInContext(
2133+
destinationWorkspace.appId,
2134+
() =>
2135+
context
2136+
.getWorkspaceDB()
2137+
.get<Datasource>(imported.resources.datasource![0])
21212138
)
21222139
expect(importedDatasource.projectIds).toEqual([imported.project._id])
2123-
expect(importedDatasource.config?.password).not.toBe("super-secret")
2140+
expect(importedDatasource.config?.password).toBe(PASSWORD_REPLACEMENT)
21242141

21252142
const { agents } = await config.api.agent.fetch()
21262143
const importedAgent = agents.find(
@@ -2726,15 +2743,19 @@ describe("/projects", () => {
27262743
)
27272744

27282745
const imported = await config.api.project.import(packageBuffer)
2729-
const importedDatasource = await config.api.datasource.get(
2730-
imported.resources.datasource?.[0]!
2746+
const importedDatasource = await config.doInContext(
2747+
config.getDevWorkspaceId(),
2748+
() =>
2749+
context
2750+
.getWorkspaceDB()
2751+
.get<Datasource>(imported.resources.datasource![0])
27312752
)
27322753
const { agents } = await config.api.agent.fetch()
27332754
const importedAgent = agents.find(
27342755
agent => agent._id === imported.resources.agent?.[0]
27352756
)
27362757

2737-
expect(importedDatasource.config?.password).not.toBe("crafted-secret")
2758+
expect(importedDatasource.config?.password).toBe(PASSWORD_REPLACEMENT)
27382759
expect(importedAgent?.live).toBe(false)
27392760
expect(importedAgent?.publishedAt).toBeUndefined()
27402761
expect(importedAgent?.slackIntegration).toEqual({

0 commit comments

Comments
 (0)