Add some more tests.
This commit is contained in:
parent
5cd1b00dad
commit
1f405da3c3
|
@ -53,7 +53,6 @@ export async function save(
|
||||||
builderSocket?.emitDatasourceUpdate(ctx, datasource)
|
builderSocket?.emitDatasourceUpdate(ctx, datasource)
|
||||||
return table
|
return table
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw err
|
|
||||||
if (err instanceof Error) {
|
if (err instanceof Error) {
|
||||||
ctx.throw(400, err.message)
|
ctx.throw(400, err.message)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -378,6 +378,8 @@ export class GoogleSheetsIntegration implements DatasourcePlus {
|
||||||
return this.create({ sheet, row: json.body as Row })
|
return this.create({ sheet, row: json.body as Row })
|
||||||
case Operation.BULK_CREATE:
|
case Operation.BULK_CREATE:
|
||||||
return this.createBulk({ sheet, rows: json.body as Row[] })
|
return this.createBulk({ sheet, rows: json.body as Row[] })
|
||||||
|
case Operation.BULK_UPSERT:
|
||||||
|
return this.createBulk({ sheet, rows: json.body as Row[] })
|
||||||
case Operation.READ:
|
case Operation.READ:
|
||||||
return this.read({ ...json, sheet })
|
return this.read({ ...json, sheet })
|
||||||
case Operation.UPDATE:
|
case Operation.UPDATE:
|
||||||
|
@ -557,32 +559,15 @@ export class GoogleSheetsIntegration implements DatasourcePlus {
|
||||||
} else {
|
} else {
|
||||||
rows = await sheet.getRows()
|
rows = await sheet.getRows()
|
||||||
}
|
}
|
||||||
// this is a special case - need to handle the _id, it doesn't exist
|
|
||||||
// we cannot edit the returned structure from google, it does not have
|
|
||||||
// setter functions and is immutable, easier to update the filters
|
|
||||||
// to look for the _rowNumber property rather than rowNumber
|
|
||||||
if (query.filters?.equal) {
|
|
||||||
const idFilterKeys = Object.keys(query.filters.equal).filter(filter =>
|
|
||||||
filter.includes(GOOGLE_SHEETS_PRIMARY_KEY)
|
|
||||||
)
|
|
||||||
for (let idFilterKey of idFilterKeys) {
|
|
||||||
const id = query.filters.equal[idFilterKey]
|
|
||||||
delete query.filters.equal[idFilterKey]
|
|
||||||
query.filters.equal[`_${GOOGLE_SHEETS_PRIMARY_KEY}`] = id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasFilters && query.paginate) {
|
if (hasFilters && query.paginate) {
|
||||||
rows = rows.slice(offset, offset + limit)
|
rows = rows.slice(offset, offset + limit)
|
||||||
}
|
}
|
||||||
const headerValues = sheet.headerValues
|
const headerValues = sheet.headerValues
|
||||||
let response = []
|
|
||||||
for (let row of rows) {
|
|
||||||
response.push(
|
|
||||||
this.buildRowObject(headerValues, row.toObject(), row.rowNumber)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
let response = rows.map(row =>
|
||||||
|
this.buildRowObject(headerValues, row.toObject(), row.rowNumber)
|
||||||
|
)
|
||||||
response = dataFilters.runQuery(response, query.filters || {})
|
response = dataFilters.runQuery(response, query.filters || {})
|
||||||
|
|
||||||
if (query.sort) {
|
if (query.sort) {
|
||||||
|
|
|
@ -104,11 +104,73 @@ describe("Google Sheets Integration", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.only("should be able to add a new row", async () => {
|
it("should be able to add a new row", async () => {
|
||||||
await config.api.row.save(table._id!, {
|
const row = await config.api.row.save(table._id!, {
|
||||||
name: "Test Contact",
|
name: "Test Contact",
|
||||||
description: "original description",
|
description: "original description",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(row.name).toEqual("Test Contact")
|
||||||
|
expect(row.description).toEqual("original description")
|
||||||
|
|
||||||
|
expect(mock.cell("A2")).toEqual("Test Contact")
|
||||||
|
expect(mock.cell("B2")).toEqual("original description")
|
||||||
|
|
||||||
|
const row2 = await config.api.row.save(table._id!, {
|
||||||
|
name: "Test Contact 2",
|
||||||
|
description: "original description 2",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(row2.name).toEqual("Test Contact 2")
|
||||||
|
expect(row2.description).toEqual("original description 2")
|
||||||
|
|
||||||
|
// Notable that adding a new row adds it at the top, not the bottom. Not
|
||||||
|
// entirely sure if this is the intended behaviour or an incorrect
|
||||||
|
// implementation of the GoogleSheetsMock.
|
||||||
|
expect(mock.cell("A2")).toEqual("Test Contact 2")
|
||||||
|
expect(mock.cell("B2")).toEqual("original description 2")
|
||||||
|
|
||||||
|
expect(mock.cell("A3")).toEqual("Test Contact")
|
||||||
|
expect(mock.cell("B3")).toEqual("original description")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should be able to add multiple rows", async () => {
|
||||||
|
await config.api.row.bulkImport(table._id!, {
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
name: "Test Contact 1",
|
||||||
|
description: "original description 1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test Contact 2",
|
||||||
|
description: "original description 2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(mock.cell("A2")).toEqual("Test Contact 1")
|
||||||
|
expect(mock.cell("B2")).toEqual("original description 1")
|
||||||
|
expect(mock.cell("A3")).toEqual("Test Contact 2")
|
||||||
|
expect(mock.cell("B3")).toEqual("original description 2")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should be able to update a row", async () => {
|
||||||
|
const row = await config.api.row.save(table._id!, {
|
||||||
|
name: "Test Contact",
|
||||||
|
description: "original description",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(mock.cell("A2")).toEqual("Test Contact")
|
||||||
|
expect(mock.cell("B2")).toEqual("original description")
|
||||||
|
|
||||||
|
await config.api.row.save(table._id!, {
|
||||||
|
...row,
|
||||||
|
name: "Test Contact Updated",
|
||||||
|
description: "original description updated",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(mock.cell("A2")).toEqual("Test Contact Updated")
|
||||||
|
expect(mock.cell("B2")).toEqual("original description updated")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -175,6 +175,20 @@ interface AppendParams {
|
||||||
responseDateTimeRenderOption?: DateTimeRenderOption
|
responseDateTimeRenderOption?: DateTimeRenderOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchGet#query-parameters
|
||||||
|
interface BatchGetParams {
|
||||||
|
ranges: string[]
|
||||||
|
majorDimension?: Dimension
|
||||||
|
valueRenderOption?: ValueRenderOption
|
||||||
|
dateTimeRenderOption?: DateTimeRenderOption
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchGet#response-body
|
||||||
|
interface BatchGetResponse {
|
||||||
|
spreadsheetId: string
|
||||||
|
valueRanges: ValueRange[]
|
||||||
|
}
|
||||||
|
|
||||||
interface AppendRequest {
|
interface AppendRequest {
|
||||||
range: string
|
range: string
|
||||||
params: AppendParams
|
params: AppendParams
|
||||||
|
@ -268,39 +282,57 @@ export class GoogleSheetsMock {
|
||||||
}
|
}
|
||||||
|
|
||||||
private mockAPI() {
|
private mockAPI() {
|
||||||
this.get(`/v4/spreadsheets/${this.config.spreadsheetId}/`, () =>
|
const spreadsheetId = this.config.spreadsheetId
|
||||||
|
|
||||||
|
this.get(`/v4/spreadsheets/${spreadsheetId}/`, () =>
|
||||||
this.handleGetSpreadsheet()
|
this.handleGetSpreadsheet()
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
|
||||||
this.post(
|
this.post(
|
||||||
`/v4/spreadsheets/${this.config.spreadsheetId}/:batchUpdate`,
|
`/v4/spreadsheets/${spreadsheetId}/:batchUpdate`,
|
||||||
(_uri, request) => this.handleBatchUpdate(request as BatchUpdateRequest)
|
(_uri, request) => this.handleBatchUpdate(request as BatchUpdateRequest)
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update
|
||||||
this.put(
|
this.put(
|
||||||
new RegExp(`/v4/spreadsheets/${this.config.spreadsheetId}/values/.*`),
|
new RegExp(`/v4/spreadsheets/${spreadsheetId}/values/.*`),
|
||||||
(_uri, request) => this.handleValueUpdate(request as ValueRange)
|
(_uri, request) => this.handleValueUpdate(request as ValueRange)
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchGet
|
||||||
this.get(
|
this.get(
|
||||||
new RegExp(`/v4/spreadsheets/${this.config.spreadsheetId}/values/.*`),
|
new RegExp(`/v4/spreadsheets/${spreadsheetId}/values:batchGet.*`),
|
||||||
uri => {
|
uri => {
|
||||||
const range = uri.split("/").pop()
|
const url = new URL(uri, "https://sheets.googleapis.com/")
|
||||||
if (!range) {
|
const params: BatchGetParams = {
|
||||||
throw new Error("No range provided")
|
ranges: url.searchParams.getAll("ranges"),
|
||||||
|
majorDimension:
|
||||||
|
(url.searchParams.get("majorDimension") as Dimension) || "ROWS",
|
||||||
|
valueRenderOption:
|
||||||
|
(url.searchParams.get("valueRenderOption") as ValueRenderOption) ||
|
||||||
|
undefined,
|
||||||
|
dateTimeRenderOption:
|
||||||
|
(url.searchParams.get(
|
||||||
|
"dateTimeRenderOption"
|
||||||
|
) as DateTimeRenderOption) || undefined,
|
||||||
}
|
}
|
||||||
return this.getValueRange(decodeURIComponent(range))
|
return this.handleBatchGet(params as unknown as BatchGetParams)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
|
||||||
|
this.get(new RegExp(`/v4/spreadsheets/${spreadsheetId}/values/.*`), uri => {
|
||||||
|
const range = uri.split("/").pop()
|
||||||
|
if (!range) {
|
||||||
|
throw new Error("No range provided")
|
||||||
|
}
|
||||||
|
return this.getValueRange(decodeURIComponent(range))
|
||||||
|
})
|
||||||
|
|
||||||
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append
|
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append
|
||||||
this.post(
|
this.post(
|
||||||
new RegExp(
|
new RegExp(`/v4/spreadsheets/${spreadsheetId}/values/.*:append`),
|
||||||
`/v4/spreadsheets/${this.config.spreadsheetId}/values/.*:append`
|
|
||||||
),
|
|
||||||
(_uri, request) => {
|
(_uri, request) => {
|
||||||
const url = new URL(_uri, "https://sheets.googleapis.com/")
|
const url = new URL(_uri, "https://sheets.googleapis.com/")
|
||||||
const params: Record<string, any> = Object.fromEntries(
|
const params: Record<string, any> = Object.fromEntries(
|
||||||
|
@ -373,6 +405,19 @@ export class GoogleSheetsMock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleBatchGet(params: BatchGetParams): BatchGetResponse {
|
||||||
|
const { ranges, majorDimension } = params
|
||||||
|
|
||||||
|
if (majorDimension && majorDimension !== "ROWS") {
|
||||||
|
throw new Error("Only row-major updates are supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
spreadsheetId: this.spreadsheet.spreadsheetId,
|
||||||
|
valueRanges: ranges.map(range => this.getValueRange(range)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private handleBatchUpdate(
|
private handleBatchUpdate(
|
||||||
batchUpdateRequest: BatchUpdateRequest
|
batchUpdateRequest: BatchUpdateRequest
|
||||||
): BatchUpdateResponse {
|
): BatchUpdateResponse {
|
||||||
|
|
Loading…
Reference in New Issue