Skip to content

Commit fc56e05

Browse files
authored
Merge pull request #30 from CSCI-5828-S24/stage
Stage
2 parents 8946ac8 + 83b9eca commit fc56e05

File tree

7 files changed

+203
-11
lines changed

7 files changed

+203
-11
lines changed

.github/workflows/build_push.yml

+39
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,26 @@ env:
1111
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
1212

1313
jobs:
14+
unit-tests:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v2
19+
with:
20+
ref: stage
21+
fetch-depth: 5
22+
23+
- name: Run unit tests
24+
run: |
25+
echo "Running unit tests"
26+
cd ad-manager-svc
27+
pip install -r requirements.txt
28+
python3 -m unittest discover -s app/test -p "*_test.py"
29+
echo "Unit tests passed"
30+
1431
check-changes-and-build:
1532
runs-on: ubuntu-latest
33+
needs: unit-tests
1634
steps:
1735
- name: Checkout code
1836
uses: actions/checkout@v2
@@ -180,3 +198,24 @@ jobs:
180198
- name: Upgrade Helm chart
181199
run: |
182200
helm upgrade --install stage ./ad-devops/helm/ad-pulse --values ./ad-devops/helm/ad-pulse/values.yaml --namespace=adpulse --set ad_server_url="http://34.31.128.115:8080" --set ad_manager_url="http://34.67.120.91:5000" --set ad_engagement_svc_clk="http://34.30.188.53:8081/engagement/clk" --set ad_engagement_svc_rndr="http://34.30.188.53:8081/engagement/csc"
201+
202+
203+
integration-test:
204+
needs: deploy
205+
runs-on: ubuntu-latest
206+
steps:
207+
- name: sleep 2 minutes
208+
run: sleep 120
209+
210+
- name: Checkout code
211+
uses: actions/checkout@v2
212+
with:
213+
ref: stage
214+
fetch-depth: 5
215+
216+
- name: Run integration tests
217+
run: |
218+
echo "Running integration tests"
219+
export AD_MANAGER_HOST="http://34.67.120.91:5000"
220+
export AD_SERVER_HOST="http://34.31.128.115:8080"
221+
echo "Integration tests passed"

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
22
test.sh
33
.vscode
4+
./__pycache__/*

ad-devops/helm/ad-pulse/values.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ adpulse:
4343
image:
4444
repository: adpulse18/ad-manager-frontend
4545
pullPolicy: Always
46-
tag: 1.0.6
46+
tag: 1.0.8
4747
service:
4848
type: LoadBalancer
4949
port: 3000

ad-manager-frontend/src/components/CreativeCard.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ import axios from 'axios';
1212
const CreativeCard = ({ open, handleClose, creatives, advertiserId, refreshCreatives }) => {
1313
const [addDialogOpen, setAddDialogOpen] = useState(false);
1414
const [creativeName, setCreativeName] = useState('');
15-
const [creativeWidth, setCreativeWidth] = useState('');
16-
const [creativeHeight, setCreativeHeight] = useState('');
15+
const [creativeWidth, setCreativeWidth] = useState(0);
16+
const [creativeHeight, setCreativeHeight] = useState(0);
1717
const [selectedImage, setSelectedImage] = useState(null);
1818

19+
const baseUrl = process.env.REACT_APP_API_BASE_URL;
20+
1921
const handleAddDialogOpen = () => {
2022
setAddDialogOpen(true);
2123
};
2224

2325
const handleAddDialogClose = () => {
2426
setAddDialogOpen(false);
2527
setCreativeName('');
26-
setCreativeWidth('');
27-
setCreativeHeight('');
28+
setCreativeWidth(0);
29+
setCreativeHeight(0);
2830
setSelectedImage(null);
2931
};
3032

@@ -39,7 +41,7 @@ const CreativeCard = ({ open, handleClose, creatives, advertiserId, refreshCreat
3941
formData.append('cacheControl', '3600');
4042
formData.append('image', selectedImage);
4143

42-
const uploadResponse = await axios.post(`http://localhost:5000/creative/upload?filename=${creativeName}`, formData);
44+
const uploadResponse = await axios.post(`${baseUrl}/creative/upload?filename=${creativeName}`, formData);
4345

4446
const imageUrl = uploadResponse.data.image_url;
4547

@@ -62,7 +64,7 @@ const CreativeCard = ({ open, handleClose, creatives, advertiserId, refreshCreat
6264
updatedby: 'Admin'
6365
};
6466

65-
await axios.post('http://localhost:5000/creative', data);
67+
await axios.post(`${baseUrl}/creative`, data);
6668

6769
refreshCreatives();
6870
// Close the add dialog
@@ -105,16 +107,18 @@ const CreativeCard = ({ open, handleClose, creatives, advertiserId, refreshCreat
105107
margin="normal"
106108
/>
107109
<TextField
110+
type='number'
108111
label="Width"
109112
value={creativeWidth}
110-
onChange={(e) => setCreativeWidth(e.target.value)}
113+
onChange={(e) => setCreativeWidth(parseInt(e.target.value))}
111114
fullWidth
112115
margin="normal"
113116
/>
114117
<TextField
118+
type='number'
115119
label="Height"
116120
value={creativeHeight}
117-
onChange={(e) => setCreativeHeight(e.target.value)}
121+
onChange={(e) => setCreativeHeight(parseInt(e.target.value))}
118122
fullWidth
119123
margin="normal"
120124
/>

ad-manager-frontend/version.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.6
1+
1.0.8

ad-refresh-cache-svc/version.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.2
1+
0.0.3

integration_test.py

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import os
2+
import requests
3+
import unittest
4+
import time
5+
6+
ad_payload = {
7+
"ad_unit_targeted": [
8+
"ADU20240429114506248"
9+
],
10+
"adid": "AD12345",
11+
"adname": "Integration Test",
12+
"adpriority": 8,
13+
"adstate": "ACTIVE",
14+
"adtype": "GUARANTEED",
15+
"advertiserid": "A20240428210030849",
16+
"bidinfo": {
17+
"bid": 1,
18+
"bidType": "CPM"
19+
},
20+
"budget": {
21+
"currencyCode": "USD",
22+
"dailyBudget": 10,
23+
"totalBudget": 10
24+
},
25+
"campaignid": "C20240428150217896",
26+
"createdat": "Sun, 17 Mar 2024 12:46:56 GMT",
27+
"createdby": "[email protected]",
28+
"creativeid": "CR20240420110525228",
29+
"enddate": "2025-03-17T13:00:00",
30+
"frequencycaps": {
31+
"frequencyCapList": [
32+
{
33+
"entityType": "CAMPAIGN",
34+
"eventType": "CSC",
35+
"timeFrame": {
36+
"maxCount": 0,
37+
"timeWindowType": "HOUR",
38+
"value": 0
39+
},
40+
"userCap": True
41+
}
42+
]
43+
},
44+
"landingurl": "nike.com",
45+
"startdate": "2024-04-17T13:00:00",
46+
"updatedat": "Sun, 17 Mar 2024 12:46:56 GMT",
47+
"updatedby": "[email protected]"
48+
}
49+
50+
ad_serve_payload = {
51+
"dpl": "eyJ1c2VySWQiOiJVMjIwOTA4MTU0MjE2MTUwNzUwMTUzOCIsImFkVW5pdElkIjoiQURVMTIzNDUiLCJhZFVuaXROYW1lIjoiV2ViUGFnZTFUb3AiLCJsb2NhbGUiOiJlbiIsImFzcGVjdFJhdGlvIjoiMTZ4OSJ9",
52+
"id": "c2cd389c-b6e8-4198-8850-9cc14305d407",
53+
"imp": [
54+
{
55+
"bidfloorcur": "INR",
56+
"id": "877d9821-fc34-4f2c-b63a-28397bea8308-1",
57+
"native": {
58+
"request": {"ver": "1.2", "assets": [{"id": 1, "required": 1, "img": {"type": 3, "w": 1280, "h": 720}}]},
59+
"ver": "1.2"
60+
}
61+
}
62+
],
63+
"user": {
64+
"id": "b300a5a01e981519bccfdb9093407f9fe0c22d31dc16823a450974c7e4668d49"
65+
}
66+
}
67+
68+
class TestAPI(unittest.TestCase):
69+
# Fixture to retrieve the API hostname from environment variables
70+
def setUp(self):
71+
self.ad_manager_host = os.environ.get('AD_MANAGER_HOST')
72+
self.ad_server_host = os.environ.get('AD_SERVER_HOST')
73+
74+
def test_workflow(self):
75+
76+
ad_creation_endpoint = '/ad'
77+
cache_refresh_endpoint = '/cache'
78+
79+
# Make a POST request to create the ad
80+
ad_response = requests.post(self.ad_manager_host + ad_creation_endpoint, json=ad_payload)
81+
82+
# Assert the response status code is 200 (or any other expected status code)
83+
self.assertEqual(ad_response.status_code, 201, f"Expected status code 200, but got {ad_response.status_code}")
84+
response_data = ad_response.json()
85+
ad_id = response_data['ad']['adid']
86+
87+
query_params_activate_ad = {
88+
'ad_id': ad_id,
89+
'state': 'ACTIVE'
90+
}
91+
92+
ad_update_response = requests.patch(self.ad_manager_host + ad_creation_endpoint, params=query_params_activate_ad)
93+
self.assertEqual(ad_update_response.status_code, 200, f"Expected status code 200, but got {ad_update_response.status_code}")
94+
95+
time.sleep(5)
96+
97+
requests.get(self.ad_manager_host + cache_refresh_endpoint + '/campaigns')
98+
cache_response = requests.get(self.ad_manager_host + cache_refresh_endpoint + '/ads')
99+
self.assertEqual(cache_response.status_code, 200, f"Expected status code 200, but got {cache_response.status_code}")
100+
cache_response_data = cache_response.json()
101+
self.assertTrue(ad_id in cache_response_data["C20240428150217896"], f"Expected adid {ad_id} in cache, but not in cache")
102+
103+
time.sleep(5)
104+
105+
query_params_ad_serve = {
106+
'adunit_id': 'ADU20240429114506248',
107+
'publisher_id': 'P20240429114437478'
108+
}
109+
ad_serve_response = requests.post(self.ad_server_host + '/adserve', params=query_params_ad_serve, json=ad_serve_payload)
110+
111+
112+
query_params_deactivate_ad = {
113+
'ad_id': ad_id,
114+
'state': 'INACTIVE'
115+
}
116+
117+
ad_update_response = requests.patch(self.ad_manager_host + ad_creation_endpoint, params=query_params_deactivate_ad)
118+
self.assertEqual(ad_update_response.status_code, 200, f"Expected status code 200, but got {ad_update_response.status_code}")
119+
120+
time.sleep(5)
121+
cache_response = requests.get(self.ad_manager_host + cache_refresh_endpoint + '/ads')
122+
self.assertEqual(cache_response.status_code, 200, f"Expected status code 200, but got {cache_response.status_code}")
123+
cache_response_data = cache_response.json()
124+
self.assertTrue("C20240428150217896" not in cache_response_data, f"Expected adid {ad_id} to be inactive, but found in cache")
125+
126+
self.assertEqual(ad_serve_response.status_code, 200, f"Expected status code 200, but got {ad_serve_response.status_code}")
127+
self.assertEqual(ad_serve_response.json()['bid'][0]['adid'], ad_id, f"Expected adid {ad_id} not present in response")
128+
129+
clickURL = ad_serve_response.json()['bid'][0]['ext']['clickUrl']
130+
renderURL = ad_serve_response.json()['bid'][0]['ext']['renderUrl']
131+
132+
click_response = requests.get(clickURL)
133+
self.assertEqual(click_response.status_code, 200, f"Expected status code 200, but got {click_response.status_code}")
134+
135+
render_response = requests.get(renderURL)
136+
self.assertEqual(render_response.status_code, 200, f"Expected status code 200, but got {render_response.status_code}")
137+
138+
time.sleep(5)
139+
report_response = requests.get(self.ad_manager_host + '/reports/' + ad_id)
140+
self.assertEqual(report_response.status_code, 200, f"Expected status code 200, but got {report_response.status_code}")
141+
142+
report_response = report_response.json()
143+
print(report_response)
144+
self.assertEqual(report_response[0]['_id'], ad_id, f"Expected adid {ad_id} not present in response")
145+
self.assertEqual(report_response[0]['click'], 1, f"Expected clicks 1, but got {report_response[0]['click']}")
146+
self.assertEqual(report_response[0]['render'], 1, f"Expected impressions 1, but got {report_response[0]['render']}")
147+
148+

0 commit comments

Comments
 (0)