Skip to content

Commit

Permalink
Fix unique constraint on reviews by author and targetUserId (#1038)
Browse files Browse the repository at this point in the history
* add mongo migrations to remove unique index

* add author_1_targetUserId_1 index migration

* fix dotenv config in migrate config

* add migration test

* refactor migrate scripts

* remove migrate:create script

* add migrate:create script
  • Loading branch information
luiqor authored Dec 11, 2024
1 parent f73d300 commit 5be76e7
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 6 deletions.
9 changes: 7 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
roots: ['<rootDir>/src/test'],
moduleNameMapper: {
'^~/(.*)$': '<rootDir>/src/$1'
'^~/(.*)$': '<rootDir>/src/$1',
'@root/(.*)': '<rootDir>/$1'
},
verbose: true,
testEnvironment: 'node',
Expand All @@ -27,6 +28,10 @@ module.exports = {
coverageReporters: ['html', 'lcov'],
coverageDirectory: '<rootDir>/src/test/coverage',
testTimeout: 12000,
testMatch: ['<rootDir>/src/test/integration/**/*.spec.js', '<rootDir>/src/test/unit/**/*.spec.js'],
testMatch: [
'<rootDir>/src/test/integration/**/*.spec.js',
'<rootDir>/src/test/unit/**/*.spec.js',
'<rootDir>/src/test/migrations/*.spec.js'
],
testResultsProcessor: 'jest-sonar-reporter'
}
22 changes: 22 additions & 0 deletions migrate-mongo-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require('dotenv').config({
path: process.env.NODE_ENV === 'test' ? '.env.test.local' : '.env.local'
})
require('dotenv').config()

const config = {
mongodb: {
url: process.env.MONGODB_URL,
options: {
useNewUrlParser: true,
useUnifiedTopology: true
}
},

migrationsDir: 'migrations',
changelogCollectionName: 'changelog',
migrationFileExtension: '.js',
useFileHash: false,
moduleSystem: 'commonjs'
}

module.exports = config
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const collectionName = 'reviews'

const indexName = 'author_1_targetUserId_1'

module.exports = {
async up(db) {
await db.collection(collectionName).dropIndex(indexName)
},

async down(db) {
await db.collection(collectionName).createIndex({ author: 1, targetUserId: 1 }, { unique: true })
}
}
166 changes: 164 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
"scripts": {
"test": "jest --maxWorkers=1",
"start": "nodemon src/app.js --legacy-watch",
"migrate:up": "migrate-mongo up",
"migrate:rollback": "migrate-mongo down",
"migrate:create": "migrate-mongo create",
"lint": "eslint . --fix",
"prepare": "husky install",
"pre-commit": "lint-staged"
Expand Down Expand Up @@ -36,6 +39,7 @@
"googleapis": "^105.0.0",
"iconv-lite": "^0.6.3",
"jsonwebtoken": "^8.5.1",
"migrate-mongo": "^11.0.0",
"module-alias": "^2.2.2",
"mongodb": "^4.2.2",
"mongoose": "^6.1.2",
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.

sonar.sources=.
sonar.exclusions=**/src/test/**/*.js, node_modules/**, jest.config.js, swagger-settings.js, docs/**, src/emails/**
sonar.exclusions=**/src/test/**/*.js, node_modules/**, jest.config.js, swagger-settings.js, docs/**, src/emails/**, migrate-mongo-config.js
sonar.language=js


Expand Down
2 changes: 1 addition & 1 deletion src/models/review.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const reviewSchema = new Schema(
}
)

reviewSchema.index({ author: 1, targetUserId: 1 }, { unique: true })
reviewSchema.index({ author: 1, targetUserId: 1, offer: 1 }, { unique: true })

reviewSchema.statics.calcAverageRatings = async function (targetUserId, targetUserRole) {
const stats = await this.aggregate([
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { MongoClient } = require('mongodb')

const { up, down } = require('@root/migrations/20241203085442-remove-unique-author-target-user-index')

require('~/initialization/envSetup')
const {
config: { MONGODB_URL }
} = require('~/configs/config')

const collectionName = 'reviews'
const indexName = 'author_1_targetUserId_1'

const url = MONGODB_URL.slice(0, MONGODB_URL.lastIndexOf('/'))
const databaseName = MONGODB_URL.slice(MONGODB_URL.lastIndexOf('/') + 1)

describe('20241203085442-remove-unique-author-target-user-index', () => {
let client, database

beforeAll(() => {
client = new MongoClient(url)
database = client.db(databaseName)
})

afterAll(() => {
client.close()
})

test('should create the unique index on migrate down', async () => {
await down(database)
const indexes = await database.collection(collectionName).indexes()
const indexNames = indexes.map((index) => index.name)
expect(indexNames).toContain(indexName)
})

test('should remove the unique index on migrate up', async () => {
await up(database)
const indexes = await database.collection(collectionName).indexes()
const indexNames = indexes.map((index) => index.name)
expect(indexNames).not.toContain(indexName)
})
})

0 comments on commit 5be76e7

Please sign in to comment.