Skip to content

Commit

Permalink
[BE][SSO] Migrate to Knex DELETE dashboard/users endpoints (#1490)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aredhel269 authored Oct 10, 2024
1 parent ec6ec7c commit a8e042b
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 42 deletions.
14 changes: 11 additions & 3 deletions services/sso/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@ All notable changes to this project will be documented in this file.

# Changelog

## [1.41.0] - 2024-07-25
## [1.42.0] - 2024-10-07

### Added
### Changed

- Migrated `DELETE /dashboard/users` endpoint to Knex.
- Replaced `client.query` with Knex methods (`whereIn`, `update`, `select`).
- Updated related tests to use Knex.

## [1.41.0] - 2024-10-02

### Changed

- Update delete endpoint. Migrate to Knex.

## [1.40.0] - 2024-07-25
## [1.40.0] - 2024-09-23

### Added

Expand Down
2 changes: 1 addition & 1 deletion services/sso/openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
info:
version: 1.39.0
version: 1.42.0
title: IT Academy SSO Service
description: This is an SSO service that is used across all ITA services.
openapi: 3.0.0
Expand Down
2 changes: 1 addition & 1 deletion services/sso/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sso-service",
"version": "1.41.0",
"version": "1.42.0",
"description": "",
"directories": {
"test": "test"
Expand Down
34 changes: 17 additions & 17 deletions services/sso/src/__tests__/dashboard/users/batchDelete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { expect, it, describe, beforeEach, afterEach } from 'vitest'
import { pathRoot } from '../../../routes/routes'
import { server, testUserData } from '../../globalSetup'
import { client } from '../../../db/client'
import db from '../../../db/knexClient'

const route = `${pathRoot.v1.dashboard.users}`
let authAdminToken = ''
Expand All @@ -19,33 +20,32 @@ beforeEach(async () => {
})

afterEach(async () => {
await client.query(
'UPDATE "user" SET deleted_at = null WHERE id IN ( $1, $2 )',
[userToDeleteId, userToBeBlockedId]
)
await db('user')
.update('deleted_at', null)
.whereIn('id', [userToDeleteId, userToBeBlockedId])
})

describe('Testing dashboard delete endpoint', () => {
it('should succeed deleting a user with a logged-in admin user', async () => {
let deletedAt = await client.query(
'SELECT deleted_at FROM "user" WHERE id IN ( $1, $2 )',
[userToDeleteId, userToBeBlockedId]
)
expect(deletedAt.rows[0].deleted_at).toBe(null)
expect(deletedAt.rows[1].deleted_at).toBe(null)
let deletedAt = await db('user')
.select('deleted_at')
.whereIn('id', [userToDeleteId, userToBeBlockedId])
expect(deletedAt[0].deleted_at).toBe(null)
expect(deletedAt[1].deleted_at).toBe(null)

const ids = [userToDeleteId, userToBeBlockedId]
const response = await supertest(server)
.delete(`${route}/`)
.set('Cookie', [authAdminToken])
.send({ ids })
expect(response.status).toBe(204)
deletedAt = await client.query(
'SELECT deleted_at FROM "user" WHERE id IN ( $1, $2 )',
[userToDeleteId, userToBeBlockedId]
)
expect(deletedAt.rows[0].deleted_at).toContain(Date)
expect(deletedAt.rows[1].deleted_at).toContain(Date)
deletedAt = await db('user')
.select('deleted_at')
.whereIn('id', [userToDeleteId, userToBeBlockedId])

expect(deletedAt[0]).toContain(Date)
expect(deletedAt[1]).toContain(Date)
})

it('should return 404 if no ids are provided', async () => {
const ids = []
const response = await supertest(server)
Expand Down
35 changes: 16 additions & 19 deletions services/sso/src/controllers/dashboard/users/batchDelete.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
import { Context, Middleware } from 'koa'
import { NotFoundError } from '../../../utils/errors'
import { client } from '../../../db/client'
import db from '../../../db/knexClient'

export const dashboardBatchDelete: Middleware = async (ctx: Context) => {
const { ids } = ctx.request.body
if (ids.length === 0) {
if (!Array.isArray(ids) || ids.length === 0) {
throw new NotFoundError('No user found')
}
const verifyQuery = `
SELECT id, deleted_at FROM "user" WHERE id = ANY($1::text[]);
`
const verifyResult = await client.query(verifyQuery, [ids])
const existingIds = verifyResult.rows.map((row) => row.id)

const verifyResult = await db('user')
.select('id', 'deleted_at')
.whereIn('id', ids)

const existingIds = verifyResult.map((row) => row.id)

if (existingIds.length === 0) {
throw new NotFoundError('No user found')
}

const toBeDeletedUser: string[] = []
verifyResult.rows.forEach((row) => {
if (row.deleted_at === null) {
toBeDeletedUser.push(row.id)
}
})
const toBeDeletedUser: string[] = verifyResult
.filter((row) => row.deleted_at === null)
.map((row) => row.id)

if (toBeDeletedUser.length > 0) {
const deleteQuery = `
UPDATE "user"
SET deleted_at = CURRENT_TIMESTAMP
WHERE id = ANY($1::text[])
`
await client.query(deleteQuery, [toBeDeletedUser])
await db('user')
.whereIn('id', toBeDeletedUser)
.update({ deleted_at: db.fn.now() })
}

ctx.status = 204
}
2 changes: 1 addition & 1 deletion services/sso/src/openapi/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const openapiFilename = 'openapi.yaml'

export const generatorConfig = {
info: {
version: '1.39.0',
version: '1.42.0',
title: 'IT Academy SSO Service',
description: 'This is an SSO service that is used across all ITA services.',
},
Expand Down

0 comments on commit a8e042b

Please sign in to comment.