diff --git a/src/__mocks__/mockedDb/campaign.ts b/src/__mocks__/mockedDb/campaign.ts index 40223f1a2..ab95a2d9a 100644 --- a/src/__mocks__/mockedDb/campaign.ts +++ b/src/__mocks__/mockedDb/campaign.ts @@ -14,7 +14,7 @@ type CampaignParams = { close_date?: string; os?: string; pm_id?: number; - is_public?: 0 | 1 | 2 | 3; + is_public?: 0 | 1 | 2 | 3 | 4; page_preview_id?: number; page_manual_id?: number; status_id?: 1 | 2; diff --git a/src/features/db/class/Campaigns.ts b/src/features/db/class/Campaigns.ts index dfc70f054..f41b150bb 100644 --- a/src/features/db/class/Campaigns.ts +++ b/src/features/db/class/Campaigns.ts @@ -1,10 +1,12 @@ +import { tryber } from "@src/features/database"; +import { UserTargetChecker } from "@src/routes/users/me/campaigns/_get/UserTargetChecker"; import Database from "./Database"; import PageAccess from "./PageAccess"; type CampaignType = { id: number; title: string; - is_public: 0 | 1 | 2 | 3; + is_public: 0 | 1 | 2 | 3 | 4; page_preview_id: string; page_manual_id: string; status_id: 1 | 2; @@ -18,7 +20,7 @@ type CampaignType = { class CampaignObject { id: number; title: string; - is_public: 0 | 1 | 2 | 3; + is_public: 0 | 1 | 2 | 3 | 4; page_preview_id: string; page_manual_id: string; status_id: 1 | 2; @@ -48,12 +50,41 @@ class CampaignObject { get isSmallGroup() { return this.is_public === 3; } + get isTarget() { + return this.is_public === 4; + } get acceptedOs() { if (!this.os || this.os === "") return []; return this.os.split(",").map((e) => parseInt(e)); } + private async getTargetRules() { + const allowedLanguages = + await tryber.tables.CampaignDossierDataLanguages.do() + .select("campaign_id", "language_id") + .join( + "campaign_dossier_data", + "campaign_dossier_data.id", + "campaign_dossier_data_languages.campaign_dossier_data_id" + ) + .where("campaign_dossier_data.campaign_id", this.id); + + const allowedCountries = + await tryber.tables.CampaignDossierDataCountries.do() + .select("campaign_id", "country_code") + .join( + "campaign_dossier_data", + "campaign_dossier_data.id", + "campaign_dossier_data_countries.campaign_dossier_data_id" + ) + .where("campaign_dossier_data.campaign_id", this.id); + return { + languages: allowedLanguages.map((l) => l.language_id), + countries: allowedCountries.map((c) => c.country_code), + }; + } + public async testerHasAccess(testerId: number) { if (this.isPublic) return true; if (this.isSmallGroup) { @@ -66,6 +97,14 @@ class CampaignObject { }); return previewAccess.length > 0; } + if (this.isTarget) { + const userTargetChecker = new UserTargetChecker({ + testerId, + }); + await userTargetChecker.init(); + + return userTargetChecker.inTarget(await this.getTargetRules()); + } return false; } diff --git a/src/routes/users/me/campaigns/campaignId/forms/_get/visibility.spec.ts b/src/routes/users/me/campaigns/campaignId/forms/_get/visibility.spec.ts new file mode 100644 index 000000000..69a49be05 --- /dev/null +++ b/src/routes/users/me/campaigns/campaignId/forms/_get/visibility.spec.ts @@ -0,0 +1,206 @@ +import campaign from "@src/__mocks__/mockedDb/campaign"; +import preselectionForms from "@src/__mocks__/mockedDb/preselectionForm"; +import profile from "@src/__mocks__/mockedDb/profile"; +import app from "@src/app"; +import { tryber } from "@src/features/database"; +import request from "supertest"; + +describe("GET users/me/campaigns/:campaignId/forms - logged user", () => { + beforeAll(async () => { + profile.insert({ + sex: 1, + country: "Italy", + city: "Rome", + phone_number: "+393331234567", + }); + + await tryber.tables.WpAppqProfileHasLang.do().insert({ + profile_id: 1, + language_id: 1, + }); + }); + afterAll(async () => { + profile.clear(); + await tryber.tables.WpAppqProfileHasLang.do().delete(); + }); + + describe("logged user", () => { + beforeAll(async () => { + campaign.insert({ + id: 1, + title: "Test campaign", + is_public: 1, + status_id: 1, + start_date: new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000) + .toISOString() + .split("T")[0], + end_date: "2021-01-02", + close_date: "2021-01-03", + campaign_type_id: 1, + os: "1,2", + }); + preselectionForms.insert({ + id: 1, + campaign_id: 1, + }); + }); + + afterAll(async () => { + campaign.clear(); + preselectionForms.clear(); + }); + + it("should return 200 if logged in", async () => { + const response = await request(app) + .get(`/users/me/campaigns/1/forms`) + .set("Authorization", `Bearer tester`); + expect(response.status).toBe(200); + }); + + it("should return 403 if not logged in", async () => { + const response = await request(app).get(`/users/me/campaigns/1/forms`); + expect(response.status).toBe(403); + }); + }); + + describe("small group", () => { + beforeAll(async () => { + campaign.insert({ + id: 1, + title: "Test campaign", + is_public: 3, + status_id: 1, + start_date: new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000) + .toISOString() + .split("T")[0], + page_preview_id: 1, + end_date: "2021-01-02", + close_date: "2021-01-03", + campaign_type_id: 1, + os: "1,2", + }); + preselectionForms.insert({ + id: 1, + campaign_id: 1, + }); + await tryber.tables.WpAppqLcAccess.do().insert({ + tester_id: 1, + view_id: 1, + }); + }); + + afterAll(async () => { + campaign.clear(); + preselectionForms.clear(); + await tryber.tables.WpAppqLcAccess.do().delete(); + }); + + describe("tester in small group", () => { + beforeAll(async () => { + await tryber.tables.WpAppqLcAccess.do().insert({ + tester_id: 1, + view_id: 1, + }); + }); + + afterAll(async () => { + await tryber.tables.WpAppqLcAccess.do().delete(); + }); + it("should return 200 if in small group", async () => { + const response = await request(app) + .get(`/users/me/campaigns/1/forms`) + .set("Authorization", `Bearer tester`); + expect(response.status).toBe(200); + }); + }); + + describe("tester not in small group", () => { + it("should return 403 if not in small group", async () => { + const response = await request(app) + .get(`/users/me/campaigns/1/forms`) + .set("Authorization", `Bearer tester`); + expect(response.status).toBe(404); + }); + }); + }); + + describe("target", () => { + beforeAll(async () => { + campaign.insert({ + id: 1, + title: "Test campaign", + is_public: 4, + status_id: 1, + start_date: new Date(new Date().getTime() + 7 * 24 * 60 * 60 * 1000) + .toISOString() + .split("T")[0], + page_preview_id: 1, + end_date: "2021-01-02", + close_date: "2021-01-03", + campaign_type_id: 1, + os: "1,2", + }); + preselectionForms.insert({ + id: 1, + campaign_id: 1, + }); + await tryber.tables.CampaignDossierData.do().insert({ + id: 1, + campaign_id: 1, + created_by: 1, + updated_by: 1, + }); + }); + + afterAll(async () => { + campaign.clear(); + preselectionForms.clear(); + await tryber.tables.CampaignDossierData.do().delete(); + }); + + describe("tester in target", () => { + beforeAll(async () => { + await tryber.tables.CampaignDossierDataLanguages.do().insert({ + campaign_dossier_data_id: 1, + language_id: 1, + }); + await tryber.tables.CampaignDossierDataCountries.do().insert({ + campaign_dossier_data_id: 1, + country_code: "IT", + }); + }); + afterAll(async () => { + await tryber.tables.CampaignDossierDataLanguages.do().delete(); + await tryber.tables.CampaignDossierDataCountries.do().delete(); + }); + it("should return 200 if in target", async () => { + const response = await request(app) + .get(`/users/me/campaigns/1/forms`) + .set("Authorization", `Bearer tester`); + expect(response.status).toBe(200); + }); + }); + describe("tester not in target", () => { + beforeAll(async () => { + await tryber.tables.CampaignDossierDataLanguages.do().insert({ + campaign_dossier_data_id: 1, + language_id: 19, + }); + await tryber.tables.CampaignDossierDataCountries.do().insert({ + campaign_dossier_data_id: 1, + country_code: "FR", + }); + }); + afterAll(async () => { + await tryber.tables.CampaignDossierDataLanguages.do().delete(); + await tryber.tables.CampaignDossierDataCountries.do().delete(); + }); + it("should return 403 if not in target", async () => { + const response = await request(app) + .get(`/users/me/campaigns/1/forms`) + .set("Authorization", `Bearer tester`); + expect(response.status).toBe(404); + }); + }); + }); +});