mirror of
https://github.com/wassname/talk.git
synced 2026-07-13 17:45:56 +08:00
added migration, migration tests 🎉
This commit is contained in:
@@ -17,7 +17,7 @@ module.exports = {
|
||||
}}
|
||||
]);
|
||||
|
||||
// If no comments were found, nothing needes to be done!
|
||||
// If no comments were found, nothing needs to be done!
|
||||
if (comments.length <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
const UserModel = require('../models/user');
|
||||
const merge = require('lodash/merge');
|
||||
|
||||
const getUserBatch = async () => {
|
||||
let query = {
|
||||
status: {
|
||||
$in: [
|
||||
'ACTIVE',
|
||||
'BANNED',
|
||||
'PENDING',
|
||||
'APPROVED'
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
// Find all the users that need migrating.
|
||||
return UserModel.collection.find(query);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
async up() {
|
||||
|
||||
const created_at = Date.now();
|
||||
|
||||
// Create a new batch operation.
|
||||
let bulk = UserModel.collection.initializeUnorderedBulkOp();
|
||||
|
||||
// Get the first batch of users.
|
||||
let cursor = await getUserBatch();
|
||||
|
||||
while (await cursor.hasNext()) {
|
||||
const user = await cursor.next();
|
||||
|
||||
const {id, status, canEditName, suspension, disabled} = user;
|
||||
|
||||
let update = {
|
||||
$unset: {
|
||||
canEditName: '',
|
||||
suspension: '',
|
||||
disabled: '',
|
||||
},
|
||||
$set: {
|
||||
status: {
|
||||
|
||||
// The username status is specific to each case.
|
||||
username: {
|
||||
history: []
|
||||
},
|
||||
|
||||
// The user is not banned by default.
|
||||
banned: {
|
||||
status: false,
|
||||
history: []
|
||||
},
|
||||
|
||||
// The user is not suspended by default.
|
||||
suspension: {
|
||||
until: null,
|
||||
history: []
|
||||
},
|
||||
},
|
||||
updated_at: created_at
|
||||
},
|
||||
};
|
||||
|
||||
if (disabled) {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
banned: {
|
||||
status: true,
|
||||
history: [{
|
||||
status: true,
|
||||
created_at
|
||||
}]
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If the user has an "until" property of their suspension, then we need
|
||||
// to reflect that in the new status object.
|
||||
if (suspension && suspension.until !== null) {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
suspension: {
|
||||
until: suspension.until,
|
||||
history: [{
|
||||
until: suspension.until,
|
||||
created_at,
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case 'ACTIVE':
|
||||
if (canEditName) {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
username: {
|
||||
status: 'UNSET',
|
||||
history: [{
|
||||
status: 'UNSET',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
username: {
|
||||
status: 'SET',
|
||||
history: [{
|
||||
status: 'SET',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'BANNED':
|
||||
if (canEditName) {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
username: {
|
||||
status: 'REJECTED',
|
||||
history: [{
|
||||
status: 'REJECTED',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
banned: {
|
||||
status: true,
|
||||
history: [{
|
||||
status: true,
|
||||
created_at
|
||||
}]
|
||||
},
|
||||
username: {
|
||||
status: 'SET',
|
||||
history: [{
|
||||
status: 'SET',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'PENDING':
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
username: {
|
||||
status: 'CHANGED',
|
||||
history: [{
|
||||
status: 'CHANGED',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'APPROVED':
|
||||
update = merge(update, {
|
||||
$set: {
|
||||
status: {
|
||||
username: {
|
||||
status: 'APPROVED',
|
||||
history: [{
|
||||
status: 'APPROVED',
|
||||
created_at
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new Error(`${status} is an invalid status`);
|
||||
}
|
||||
|
||||
bulk.find({id}).updateOne(update);
|
||||
}
|
||||
|
||||
// Execute the bulk update operation.
|
||||
await bulk.execute();
|
||||
}
|
||||
};
|
||||
|
||||
+4
-1
@@ -33,7 +33,7 @@
|
||||
},
|
||||
"talk": {
|
||||
"migration": {
|
||||
"minVersion": 1507322128
|
||||
"minVersion": 1510174676
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
@@ -228,5 +228,8 @@
|
||||
"post-checkout": [],
|
||||
"post-merge": []
|
||||
}
|
||||
},
|
||||
"release": {
|
||||
"analyzeCommits": "simple-commit-message"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
const migration = require('../../../migrations/1510174676_user_status');
|
||||
const UserModel = require('../../../models/user');
|
||||
|
||||
const chai = require('chai');
|
||||
chai.use(require('chai-datetime'));
|
||||
const {expect} = chai;
|
||||
|
||||
describe('migration.1510174676_user_status', () => {
|
||||
describe('active user', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
canEditName: false
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('status', 'ACTIVE');
|
||||
expect(user).to.have.property('canEditName', false);
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('username');
|
||||
expect(user.status.username).to.have.property('status', 'SET');
|
||||
expect(user.status.username.history).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('social user', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
canEditName: true
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('status', 'ACTIVE');
|
||||
expect(user).to.have.property('canEditName', true);
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('username');
|
||||
expect(user.status.username).to.have.property('status', 'UNSET');
|
||||
expect(user.status.username.history).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('rejected username', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'BANNED',
|
||||
canEditName: true
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('BANNED');
|
||||
expect(user.canEditName).to.equal(true);
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('banned');
|
||||
expect(user.status.banned).to.have.property('status', false);
|
||||
expect(user.status.username).to.have.property('status', 'REJECTED');
|
||||
expect(user.status.username.history).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('approved username', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'APPROVED',
|
||||
canEditName: false
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('APPROVED');
|
||||
expect(user.canEditName).to.equal(false);
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('banned');
|
||||
expect(user.status.banned).to.have.property('status', false);
|
||||
expect(user.status.username).to.have.property('status', 'APPROVED');
|
||||
expect(user.status.username.history).to.have.length(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('suspended user', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'ACTIVE',
|
||||
suspension: {
|
||||
until: new Date()
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('suspension');
|
||||
expect(user.suspension).to.have.property('until');
|
||||
expect(user.suspension.until).to.not.be.null;
|
||||
|
||||
const until = user.suspension.until;
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('suspension');
|
||||
expect(user.status.suspension).to.have.property('until');
|
||||
expect(user.status.suspension.until).to.not.be.null;
|
||||
expect(user.status.suspension.until).to.be.withinTime(new Date(until.getTime() - 1000), new Date(until.getTime() + 1000));
|
||||
});
|
||||
});
|
||||
|
||||
describe('banned user', () => {
|
||||
beforeEach(async () => {
|
||||
await UserModel.collection.insert({
|
||||
id: '123',
|
||||
username: 'Kirk',
|
||||
lowercaseUsername: 'kirk',
|
||||
status: 'BANNED',
|
||||
canEditName: false
|
||||
});
|
||||
});
|
||||
|
||||
it('completes the migration', async () => {
|
||||
|
||||
let user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.equal('BANNED');
|
||||
|
||||
// Perform the migration.
|
||||
await migration.up();
|
||||
|
||||
user = await UserModel.collection.findOne({id: '123'});
|
||||
|
||||
// Check that it was correct.
|
||||
expect(user).to.have.property('status');
|
||||
expect(user.status).to.have.property('banned');
|
||||
expect(user.status.banned).to.have.property('status', true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user