Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion config/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ 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
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "switcher-api",
"version": "1.2.7",
"version": "1.2.8",
"description": "Feature Flag/Toggle API",
"main": "start.js",
"author": {
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/api-docs/swagger-info.js
Original file line number Diff line number Diff line change
@@ -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)',
Expand Down
3 changes: 1 addition & 2 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 1 addition & 1 deletion src/services/team.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
26 changes: 26 additions & 0 deletions tests/fixtures/db_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down
84 changes: 55 additions & 29 deletions tests/team.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import {
adminMasterAccount,
teamInviteNoTeam,
adminAccountToken,
adminAccount
memberAccountId,
teamId,
memberAccount2,
memberAccount2Token,
memberAccount2Id
} from './fixtures/db_api';

afterAll(async () => {
Expand All @@ -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
Expand All @@ -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);
});
Expand Down Expand Up @@ -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);
});

Expand Down Expand Up @@ -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)
Expand All @@ -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);
});

Expand Down Expand Up @@ -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);
});

Expand All @@ -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)
Expand Down Expand Up @@ -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]));
});
});

Expand Down