Skip to content

Commit

Permalink
Merge pull request #331 from AppQuality/add-custom-roles
Browse files Browse the repository at this point in the history
Add custom roles
  • Loading branch information
d-beezee authored May 23, 2024
2 parents 419cd29 + c4c0ab4 commit 4d4ea52
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 28 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"@appquality/tryber-database": "^0.39.0",
"@appquality/tryber-database": "^0.40.0",
"@appquality/wp-auth": "^1.0.7",
"@googlemaps/google-maps-services-js": "^3.3.7",
"@sendgrid/mail": "^7.6.0",
Expand Down
25 changes: 25 additions & 0 deletions src/reference/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4044,9 +4044,34 @@ paths:
type: integer
name:
type: string
customRoles:
type: array
x-stoplight:
id: 2d3889y7ey2kq
items:
x-stoplight:
id: 9co5gffc2hn6i
type: object
properties:
roleId:
type: integer
x-stoplight:
id: zd1kwwa615imc
userIds:
type: array
x-stoplight:
id: ytdjdr4x7fwp5
items:
x-stoplight:
id: n1rh2j7oemn08
type: integer
required:
- roleId
- userIds
required:
- id
- name
- customRoles
examples:
Example 1:
value:
Expand Down
125 changes: 109 additions & 16 deletions src/routes/campaignTypes/_get/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ import request from "supertest";

describe("GET /campaignTypes", () => {
beforeAll(async () => {
const profile = {
email: "",
employment_id: 1,
education_id: 1,
};

await tryber.tables.WpAppqEvdProfile.do().insert([
{
...profile,
id: 10,
wp_user_id: 1,
name: "PM",
surname: "user",
},
{
...profile,
id: 20,
wp_user_id: 2,
name: "TL",
surname: "user",
},
{
...profile,
id: 30,
wp_user_id: 3,
name: "TL 2",
surname: "user",
},
]);
await tryber.tables.WpAppqCampaignType.do().insert([
{
id: 1,
Expand All @@ -13,7 +42,51 @@ describe("GET /campaignTypes", () => {
{
id: 2,
name: "Campaign Type 2",
category_id: 1,
category_id: 2,
},
{
id: 3,
name: "Campaign Type 3",
category_id: 3,
},
]);

await tryber.seeds().roles();

const category = {
tester_selection_xls: "",
manual_template_id: 1,
preview_template_id: 1,
automatic_olps: "",
automatic_user_olp_ids: "",
tester_coach_ids: "",
mailmerge_template_ids: "",
use_case_template_ids: "",
};
await tryber.tables.WpAppqCampaignCategory.do().insert([
{
...category,
id: 1,
name: "Test Category",

custom_roles: JSON.stringify({
"1": [1],
"2": [2, 3],
}),
},
{
...category,
id: 2,
name: "Other Category",
},
{
...category,
id: 3,
name: "Third Category",
custom_roles: JSON.stringify({
"1": [2],
"2": [1, 3],
}),
},
]);
});
Expand Down Expand Up @@ -47,29 +120,49 @@ describe("GET /campaignTypes", () => {
const response = await request(app)
.get("/campaignTypes")
.set("Authorization", 'Bearer tester olp {"appq_campaign":true}');
expect(response.body).toEqual([
{
id: 1,
name: "Campaign Type 1",
},
{
id: 2,
name: "Campaign Type 2",
},
]);
expect(response.body).toHaveLength(3);
expect(response.body[0]).toHaveProperty("id", 1);
expect(response.body[0]).toHaveProperty("name", "Campaign Type 1");
expect(response.body[1]).toHaveProperty("id", 2);
expect(response.body[1]).toHaveProperty("name", "Campaign Type 2");
});
it("Should answer with a list of types when user has partial access to campaign", async () => {
const response = await request(app)
.get("/campaignTypes")
.set("Authorization", 'Bearer tester olp {"appq_campaign":[1,2]}');
expect(response.body).toEqual([

expect(response.body).toHaveLength(3);
expect(response.body[0]).toHaveProperty("id", 1);
expect(response.body[0]).toHaveProperty("name", "Campaign Type 1");
expect(response.body[1]).toHaveProperty("id", 2);
expect(response.body[1]).toHaveProperty("name", "Campaign Type 2");
});

it("Should return the list of custom roles", async () => {
const response = await request(app)
.get("/campaignTypes")
.set("Authorization", 'Bearer tester olp {"appq_campaign":true}');

expect(response.body).toHaveLength(3);
expect(response.body[0]).toHaveProperty("customRoles", [
{
id: 1,
name: "Campaign Type 1",
roleId: 1,
userIds: [10],
},
{
id: 2,
name: "Campaign Type 2",
roleId: 2,
userIds: [20, 30],
},
]);
expect(response.body[1]).toHaveProperty("customRoles", []);
expect(response.body[2]).toHaveProperty("customRoles", [
{
roleId: 1,
userIds: [20],
},
{
roleId: 2,
userIds: [10, 30],
},
]);
});
Expand Down
79 changes: 76 additions & 3 deletions src/routes/campaignTypes/_get/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,86 @@ class RouteItem extends UserRoute<{
}

protected async prepare(): Promise<void> {
const types = await this.getTypes();

const result = await this.enhanceTypesWithCustomRoles(types);
return this.setSuccess(
200,
result.map((type) => ({
id: type.id,
name: type.name,
customRoles: type.customRoles,
}))
);
}

private async getTypes() {
const types = await tryber.tables.WpAppqCampaignType.do()
.select(
tryber.ref("id").withSchema("wp_appq_campaign_type"),
tryber.ref("name").withSchema("wp_appq_campaign_type")
tryber.ref("name").withSchema("wp_appq_campaign_type"),
"custom_roles"
)
.join(
"wp_appq_campaign_category",
"wp_appq_campaign_category.id",
"wp_appq_campaign_type.category_id"
)
.orderBy("name", "asc");
return this.setSuccess(200, types);
.orderBy("wp_appq_campaign_type.name", "asc");
const parsedTypes = types.map((type) => {
let parsedRoles: Record<string, any> = {};
if (type.custom_roles) {
try {
parsedRoles = JSON.parse(type.custom_roles);
} catch (error) {
console.error("Error parsing custom roles", error);
}
}
return {
...type,
custom_roles: parsedRoles,
};
});
return parsedTypes;
}

private async enhanceTypesWithCustomRoles<T>(
types: (T & {
custom_roles: Record<string, any>;
})[]
) {
const userIds = [
...new Set(
types.flatMap((type) => Object.values(type.custom_roles)).flat()
),
];

const userIdMap = (
await tryber.tables.WpAppqEvdProfile.do()
.select("wp_user_id", "id")
.whereIn("wp_user_id", userIds)
).reduce((acc, user) => {
acc[user.wp_user_id] = user.id;
return acc;
}, {} as Record<number, number>);

return types.map((type) => {
const customRoles = Object.keys(type.custom_roles).map((roleId) => {
const usertoadd = (type.custom_roles[roleId] as number[])
.map((id) => userIdMap[id])
.filter((t) => typeof t === "number");

return {
roleId: parseInt(roleId),
userIds: usertoadd,
};
});

return {
...type,
customRoles: customRoles,
};
});
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,10 @@ export interface operations {
"application/json": {
id: number;
name: string;
customRoles: {
roleId: number;
userIds: number[];
}[];
}[];
};
};
Expand Down
16 changes: 8 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
"@babel/parser" "^7.22.5"
"@babel/traverse" "^7.22.5"

"@appquality/tryber-database@^0.39.0":
version "0.39.0"
resolved "https://registry.yarnpkg.com/@appquality/tryber-database/-/tryber-database-0.39.0.tgz#b0b0e4a6c6d456f5cc7d6b9d0348e60795fac8ea"
integrity sha512-SQaETcgQml5qBhkJUJNRdk+POjQx8zRLTNPnRlR5/ZUdN6qzsrhUfmP+2mA1SHx0AIqP4Gfh2hKV1QJZj7FV/w==
"@appquality/tryber-database@^0.40.0":
version "0.40.0"
resolved "https://registry.yarnpkg.com/@appquality/tryber-database/-/tryber-database-0.40.0.tgz#c4cec8c65ca756414d29763adbd51a701dc396bb"
integrity sha512-54VpXGy8601sORtN14YBRQKcTPFxXu67zaeEhV1ycJ/SnMAZQeSEnmFqQN0G2o3jt5KX89TtMi0ndpRrOme7kg==
dependencies:
better-sqlite3 "^8.1.0"
knex "^2.5.1"
Expand Down Expand Up @@ -2296,10 +2296,10 @@ copyfiles@^2.4.1:
untildify "^4.0.0"
yargs "^16.1.0"

core-js@^3.37.0:
version "3.37.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.0.tgz#d8dde58e91d156b2547c19d8a4efd5c7f6c426bb"
integrity sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==
core-js@^3.6.5:
version "3.37.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==

core-util-is@~1.0.0:
version "1.0.2"
Expand Down

0 comments on commit 4d4ea52

Please sign in to comment.