diff --git a/config/.env.dev b/config/.env.dev index a05489e..ffd481e 100644 --- a/config/.env.dev +++ b/config/.env.dev @@ -5,6 +5,8 @@ RESOURCE_SECRET=[CHANGE_IT] JWT_CLIENT_TOKEN_EXP_TIME=5m JWT_ADMIN_TOKEN_RENEW_INTERVAL=10m MAX_STRATEGY_OPERATION=100 +REGEX_MAX_TIMEOUT=3000 +REGEX_MAX_BLACLIST=50 HISTORY_ACTIVATED=true METRICS_ACTIVATED=true METRICS_MAX_PAGE=50 @@ -12,5 +14,5 @@ GOOGLE_SKIP_AUTH=true ### Switcher Management SWITCHERAPI_URL=http://10.0.0.2:3000 -SM_IP=10.0.0.2 +SM_IP=http://10.0.0.2 #SWITCHERSLACKAPP_URL=[SWITCHER_SLACK_APP_ENDPOINT]/slack/install \ No newline at end of file diff --git a/package.json b/package.json index 3d4dbba..0f9206a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "switcher-api", - "version": "1.2.7", + "version": "1.2.8", "description": "Feature Flag/Toggle API", "main": "start.js", "author": { @@ -40,7 +40,7 @@ "jsonwebtoken": "^9.0.0", "moment": "^2.29.4", "mongodb": "^5.3.0", - "mongoose": "^7.0.4", + "mongoose": "^7.0.5", "pino": "^8.11.0", "pino-pretty": "^10.0.0", "swagger-ui-express": "^4.6.2", diff --git a/sonar-project.properties b/sonar-project.properties index f3bb8ac..716e751 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectKey=switcherapi_switcher-api sonar.projectName=switcher-api sonar.organization=switcherapi -sonar.projectVersion=1.2.7 +sonar.projectVersion=1.2.8 sonar.links.homepage=https://github.com/switcherapi/switcher-api sonar.testExecutionReportPaths=test-report.xml diff --git a/src/api-docs/swagger-info.js b/src/api-docs/swagger-info.js index 87ec0a3..607f60a 100644 --- a/src/api-docs/swagger-info.js +++ b/src/api-docs/swagger-info.js @@ -1,6 +1,6 @@ export default { title: 'Switcher API', - version: 'v1.2.7', + version: 'v1.2.8', description: 'Switcher API is a Feature Flag API focused on toggling features over different environments and applications.', contact: { name: 'Roger Floriano (petruki)', diff --git a/src/helpers/index.js b/src/helpers/index.js index 92309a0..922b1a6 100644 --- a/src/helpers/index.js +++ b/src/helpers/index.js @@ -56,8 +56,7 @@ export function formatInput(input, if (options.autoUnderscore) { regexStr = /^[a-zA-Z0-9_\- ]*$/; } else { - // eslint-disable-next-line no-useless-escape - regexStr = options.allowSpace ? /^[a-zA-Z0-9_\- ]*$/ : /^[a-zA-Z0-9_\-]*$/; + regexStr = options.allowSpace ? /^[a-zA-Z0-9_\- ]*$/ : /^[a-zA-Z0-9_-]*$/; } if (!input.match(regexStr)) { diff --git a/src/services/team.js b/src/services/team.js index 9b81f80..d757710 100644 --- a/src/services/team.js +++ b/src/services/team.js @@ -174,7 +174,7 @@ export async function removeTeamMember(member, id, admin) { throw new NotFoundError(`Member '${adminMember.name}' does not belong to '${team.name}'`); } - adminMember.teams.splice(indexTeam); + adminMember.teams.splice(indexTeam, 1); indexTeam = team.members.indexOf(team._id); team.members.splice(indexTeam, 1); diff --git a/tests/fixtures/db_api.js b/tests/fixtures/db_api.js index afeee34..a59f2b2 100644 --- a/tests/fixtures/db_api.js +++ b/tests/fixtures/db_api.js @@ -38,6 +38,26 @@ export const adminAccount = { active: true }; +export const memberAccountId = new mongoose.Types.ObjectId(); +export const memberAccountToken = jwt.sign({ _id: memberAccountId }, process.env.JWT_SECRET); +export const memberAccount = { + _id: memberAccountId, + name: 'Member', + email: 'member@mail.com', + password: 'asdasdasdasd', + active: true +}; + +export const memberAccount2Id = new mongoose.Types.ObjectId(); +export const memberAccount2Token = jwt.sign({ _id: memberAccount2Id }, process.env.JWT_SECRET); +export const memberAccount2 = { + _id: memberAccount2Id, + name: 'Member 2', + email: 'member2@mail.com', + password: 'asdasdasdasd', + active: true +}; + export const domainId = new mongoose.Types.ObjectId(); export const domainDocument = { _id: domainId, @@ -228,6 +248,12 @@ export const setupDatabase = async () => { adminAccount.token = Admin.extractTokenPart(adminAccountToken); await new Admin(adminAccount).save(); + memberAccount.token = Admin.extractTokenPart(memberAccountToken); + await new Admin(memberAccount).save(); + + memberAccount2.token = Admin.extractTokenPart(memberAccount2Token); + await new Admin(memberAccount2).save(); + await new Environment(environment1).save(); await new Environment(environment2).save(); await new Environment(environment3).save(); diff --git a/tests/team.test.js b/tests/team.test.js index bca800e..2539998 100644 --- a/tests/team.test.js +++ b/tests/team.test.js @@ -17,7 +17,11 @@ import { adminMasterAccount, teamInviteNoTeam, adminAccountToken, - adminAccount + memberAccountId, + teamId, + memberAccount2, + memberAccount2Token, + memberAccount2Id } from './fixtures/db_api'; afterAll(async () => { @@ -38,7 +42,7 @@ describe('Insertion tests', () => { }).expect(201); // DB validation - document created - const team = await Team.findById(response.body._id).lean(); + const team = await Team.findById(response.body._id).exec(); expect(team).not.toBeNull(); // Response validation @@ -64,7 +68,7 @@ describe('Insertion tests', () => { }).expect(201); // DB validation - document created - const team = await Team.findById(response.body._id).lean(); + const team = await Team.findById(response.body._id).exec(); expect(team).not.toBeNull(); expect(team.permissions.length).toEqual(2); }); @@ -187,7 +191,7 @@ describe('Updating tests', () => { }).expect(200); // DB validation - document updated - const team = await Team.findById(team1Id).lean(); + const team = await Team.findById(team1Id).exec(); expect(team.active).toBe(false); }); @@ -241,7 +245,7 @@ describe('Deletion tests', () => { }).expect(200); // DB validation - let admin = await Admin.findById(adminAccountId); + let admin = await Admin.findById(adminAccountId).exec(); expect(admin.teams.includes(teamId)).toEqual(true); await request(app) @@ -250,10 +254,10 @@ describe('Deletion tests', () => { .send().expect(200); // DB validation - document deleted - const team = await Team.findById(teamId).lean(); + const team = await Team.findById(teamId).exec(); expect(team).toBeNull(); - admin = await Admin.findById(adminAccountId); + admin = await Admin.findById(adminAccountId).exec(); expect(admin.teams.includes(teamId)).toEqual(false); }); @@ -284,7 +288,7 @@ describe('Updating team members tests', () => { }).expect(200); // DB validation - const admin = await Admin.findById(adminAccountId).lean(); + const admin = await Admin.findById(adminAccountId).exec(); expect(admin.teams[0]).toEqual(team1._id); }); @@ -297,7 +301,7 @@ describe('Updating team members tests', () => { }).expect(201); // DB validation - let teamInvite = await TeamInvite.findById(response.body._id).lean(); + let teamInvite = await TeamInvite.findById(response.body._id).exec(); expect(teamInvite).not.toBeNull(); response = await request(app) @@ -518,53 +522,75 @@ describe('Updating team members tests', () => { }); test('TEAM_SUITE - Should remove a team member', async () => { + // Given + // Member added to [Team] await request(app) - .patch('/team/member/remove/' + team1Id) + .patch('/team/member/add/' + teamId) .set('Authorization', `Bearer ${adminMasterAccountToken}`) .send({ - member: adminAccountId + member: memberAccountId + }).expect(200); + + // Member added to [Team 1] + await request(app) + .patch('/team/member/add/' + team1Id) + .set('Authorization', `Bearer ${adminMasterAccountToken}`) + .send({ + member: memberAccountId + }).expect(200); + + // That + let admin = await Admin.findById(memberAccountId).exec(); + expect(admin.teams.length).toEqual(2); + + // Test - remove from [Team] + await request(app) + .patch('/team/member/remove/' + teamId) + .set('Authorization', `Bearer ${adminMasterAccountToken}`) + .send({ + member: memberAccountId }).expect(200); // DB validation - const admin = await Admin.findById(adminAccountId).lean(); - expect(admin.teams.length).toBe(0); + admin = await Admin.findById(memberAccountId).exec(); + expect(admin.teams[0]._id).toEqual(team1Id); + expect(admin.teams.length).toEqual(1); }); test('TEAM_SUITE - Should remove a team member when account is deleted', async() => { - // given - // member invited + // Given + // Member invited let response = await request(app) .post('/team/member/invite/' + team1Id) .set('Authorization', `Bearer ${adminMasterAccountToken}`) .send({ - email: adminAccount.email + email: memberAccount2.email }).expect(201); - let teamInvite = await TeamInvite.findById(response.body._id).lean(); + let teamInvite = await TeamInvite.findById(response.body._id).exec(); - // given - // invite accepted + // Invite accepted await request(app) .post('/team/member/invite/accept/' + teamInvite._id) - .set('Authorization', `Bearer ${adminAccountToken}`) + .set('Authorization', `Bearer ${memberAccount2Token}`) .send().expect(200); - // test + // That // Team has a new member - let team = await Team.findById(team1Id); - expect(team.members.length).toBe(1); + let team = await Team.findById(team1Id).exec(); + expect(team.members).toEqual(expect.arrayContaining([memberAccount2Id])); - // given - // account being deleted + // Test + // Account being deleted await request(app) .delete('/admin/me') - .set('Authorization', `Bearer ${adminAccountToken}`) + .set('Authorization', `Bearer ${memberAccount2Token}`) .send() .expect(200); - // test - team = await Team.findById(team1Id); - expect(team.members.length).toBe(0); + // That + team = await Team.findById(team1Id).exec(); + expect(team.members).not.toEqual(expect.arrayContaining([memberAccount2Id])); }); });