Skip to content

Commit

Permalink
Merge pull request #5 from EricFrancis12/report-custom-tokens
Browse files Browse the repository at this point in the history
add click custom tokens to report view
  • Loading branch information
EricFrancis12 authored Sep 29, 2024
2 parents 41e8644 + bf3ccf3 commit f02809c
Show file tree
Hide file tree
Showing 40 changed files with 1,017 additions and 274 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
with:
go-version: "^1.22.3"

- run: docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d
- run: docker compose -f docker-compose.yml -f docker-compose.e2e.yml up -d --build

- run: npm ci
- run: npx prisma generate
Expand Down
21 changes: 12 additions & 9 deletions api/t.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,19 @@ func T(w http.ResponseWriter, r *http.Request) {
ipInfoData = <-ipidch
}

trafficSource := <-tsch
tsTokens := trafficSource.MakeTokens(*r.URL)

publicClickId := pkg.NewPublicClickID()
dest, _ := campaign.DetermineViewDestination(pkg.DestinationOpts{
R: *r,
Ctx: ctx,
Storer: *tStorer,
SavedFlow: savedFlow,
UserAgent: userAgent,
IpInfoData: ipInfoData,
PublicClickId: publicClickId,
R: *r,
Ctx: ctx,
Storer: *tStorer,
SavedFlow: savedFlow,
UserAgent: userAgent,
IpInfoData: ipInfoData,
TrafficSourceTokens: tsTokens,
PublicClickId: publicClickId,
})

anch := make(chan pkg.AffiliateNetwork)
Expand All @@ -93,7 +97,6 @@ func T(w http.ResponseWriter, r *http.Request) {
if !visitorNeedsIpInfoData {
ipInfoData = <-ipidch
}
trafficSource := <-tsch
affiliateNetwork := <-anch

// Save click to db
Expand All @@ -106,7 +109,7 @@ func T(w http.ResponseWriter, r *http.Request) {
ClickTime: getClicktime(dest, timestamp),
ViewOutputURL: dest.URL,
ClickOutputURL: getClickOutputURL(dest),
Tokens: trafficSource.MakeTokens(*r.URL),
Tokens: tsTokens,
IP: r.RemoteAddr,
Isp: ipInfoData.Org,
UserAgent: r.UserAgent(),
Expand Down
4 changes: 4 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export default defineConfig({
setupNodeEvents(on, config) {
// implement node event listeners here
},
specPattern: [
"cypress/e2e/redirects.cy.ts",
"cypress/e2e/dashboard.cy.ts",
],
},
env: {
// Non-sensitive env vars hard-coded here. Example:
Expand Down
29 changes: 29 additions & 0 deletions cypress/e2e/dashboard.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import seedData, { returnFirstOrThrow } from "../../prisma/seedData";
import { Env } from "../../src/lib/types";

describe("Testing dashboard functionality", () => {
it("logs in successfully and traverses dashboard functionality", () => {
cy.visit("http://localhost:3000");
cy.url().should("eq", "http://localhost:3000/login");

cy.get("[data-cy='username-input']").type(Cypress.env(Env.ROOT_USERNAME));
cy.get("[data-cy='password-input']").type(Cypress.env(Env.ROOT_PASSWORD));
cy.get("[data-cy='submit-button']").click();

cy.wait(1000 * 10);

cy.url().should("eq", "http://localhost:3000/dashboard");

const { name } = returnFirstOrThrow(seedData.campaignSeeds, "Campaign seed");
cy.get(`[data-cy='${name}']`).click();
cy.get("[data-cy='report-button']").click();

cy.wait(1000 * 10);

const { customTokens } = returnFirstOrThrow(seedData.trafficSourceSeeds, "Traffic Source seed");
for (const token of customTokens) {
cy.get("[data-cy='select-chain-link-index-0']").select(token.queryParam);
cy.wait(1000);
}
});
});
49 changes: 45 additions & 4 deletions cypress/e2e/redirects.cy.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { campaignSeedData, landingPageSeedData, offerSeedData } from "../../prisma/seedData";
import { makeCampaignUrl, makeClickUrl, makePostbackUrl } from "../../src/lib/utils";
import { ECookieName, Env } from "../../src/lib/types";
import { ECustomTokenParam, returnAtIndexOrThrow, returnFirstOrThrow, testUserAgent, testZoneId } from "../../prisma/seedData";
import seedData from "../../prisma/seedData";
const { campaignSeeds, landingPageSeeds, offerSeeds, trafficSourceSeeds } = seedData;

describe("Testing campaign redirects", () => {
const { publicId } = returnFirstOrThrow(campaignSeeds, "Campaign seed");
const { customTokens } = returnFirstOrThrow(trafficSourceSeeds, "Traffic Source seed");

it("redirects to the correct URLs", () => {
// Campaign URL
cy.visit(makeCampaignUrl("http:", "localhost", "3001", campaignSeedData.publicId, []));
cy.url().should("eq", landingPageSeedData.url);
cy.visit(makeCampaignUrl("http:", "localhost", "3001", publicId, []));

const { url } = returnFirstOrThrow(landingPageSeeds, "Landing Page seed");
cy.url().should("eq", url);

cy.getCookie(ECookieName.CLICK_PUBLIC_ID, { domain: "localhost" })
.then(cookie => {
Expand All @@ -18,7 +25,9 @@ describe("Testing campaign redirects", () => {

// Click URL
cy.visit(makeClickUrl("http:", "localhost", "3001"));
cy.url().should("eq", offerSeedData.url);

const { url } = returnFirstOrThrow(offerSeeds, "Offer seed");
cy.url().should("eq", url);

//Postback URL
cy.request(makePostbackUrl("http:", "localhost", "3001", pid || ""))
Expand All @@ -38,4 +47,36 @@ describe("Testing campaign redirects", () => {
cy.visit(makeClickUrl("http:", "localhost", "3001"));
cy.url().should("eq", Cypress.env(Env.CATCH_ALL_REDIRECT_URL));
});

it("redirects to the correct rule route per user agent header", () => {
cy.visit(
makeCampaignUrl("http:", "localhost", "3001", publicId, []),
{
headers: {
"User-Agent": testUserAgent,
},
},
);

const { url } = returnAtIndexOrThrow(offerSeeds, 1, "Offer seed");
cy.url().should("eq", url);
});

it("redirects to the correct rule route per custom traffic source token", () => {
const tokens = [
{
queryParam: ECustomTokenParam.ZONE_ID,
value: testZoneId,
},
{
queryParam: ECustomTokenParam.BANNER_ID,
value: "",
},
];

cy.visit(makeCampaignUrl("http:", "localhost", "3001", publicId, tokens));

const { url } = returnAtIndexOrThrow(offerSeeds, 2, "Offer seed");
cy.url().should("eq", url);
});
});
3 changes: 3 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ services:
build:
context: ./
dockerfile: ./Dockerfile
environment:
- "POSTGRES_URL=postgresql://postgres:mysecretpassword@postgres:5432/mydb?schema=public"
- "REDIS_URL=redis://redis:6379"
ports:
- "3000:3000"
depends_on:
Expand Down
23 changes: 12 additions & 11 deletions pkg/campaign.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func (s *Storer) GetCampaignByPublicId(ctx context.Context, publicId string) (Ca
return c, nil
}

func (c *Campaign) SelectViewRoute(r http.Request, userAgent useragent.UserAgent, ipInfoData IPInfoData) Route {
return selectViewRoute(c.FlowMainRoute, c.FlowRuleRoutes, r, userAgent, ipInfoData)
func (c *Campaign) SelectViewRoute(r http.Request, userAgent useragent.UserAgent, ipInfoData IPInfoData, tokens []Token) Route {
return selectViewRoute(c.FlowMainRoute, c.FlowRuleRoutes, r, userAgent, ipInfoData, tokens)
}

// Checks if the click triggered any rule routes, and if not returns the main route
Expand All @@ -99,13 +99,14 @@ func (c *Campaign) SelectOfferID(ids []int) (int, error) {
}

type DestinationOpts struct {
R http.Request
Ctx context.Context
Storer Storer
SavedFlow SavedFlow
UserAgent useragent.UserAgent
IpInfoData IPInfoData
PublicClickId string
R http.Request
Ctx context.Context
Storer Storer
SavedFlow SavedFlow
UserAgent useragent.UserAgent
IpInfoData IPInfoData
TrafficSourceTokens []Token
PublicClickId string
}

func (do *DestinationOpts) TokenMatcherMap() URLTokenMatcherMap {
Expand Down Expand Up @@ -138,9 +139,9 @@ func (c *Campaign) DetermineViewDestination(opts DestinationOpts) (Destination,
} else if c.FlowType == db.FlowTypeBuiltIn || c.FlowType == db.FlowTypeSaved {
route := Route{}
if c.FlowType == db.FlowTypeBuiltIn {
route = c.SelectViewRoute(opts.R, opts.UserAgent, opts.IpInfoData)
route = c.SelectViewRoute(opts.R, opts.UserAgent, opts.IpInfoData, opts.TrafficSourceTokens)
} else {
route = opts.SavedFlow.SelectViewRoute(opts.R, opts.UserAgent, opts.IpInfoData)
route = opts.SavedFlow.SelectViewRoute(opts.R, opts.UserAgent, opts.IpInfoData, opts.TrafficSourceTokens)
}

path, err := route.WeightedSelectPath()
Expand Down
Loading

0 comments on commit f02809c

Please sign in to comment.