From e28c6d54c4ebfa69a6af7242f72dfc1e07edd164 Mon Sep 17 00:00:00 2001 From: Will Taylor Date: Wed, 19 Oct 2011 12:26:23 -0400 Subject: [PATCH] Initial Version - Facebook Ads API read only operations --- .gitignore | 3 + .../social/facebook/api/AdAccount.java | 164 +++++ .../social/facebook/api/AdAccountGroup.java | 104 +++ .../social/facebook/api/AdAccountUser.java | 50 ++ .../social/facebook/api/AdCampaign.java | 118 +++ .../social/facebook/api/AdCreative.java | 128 ++++ .../social/facebook/api/AdGroup.java | 210 ++++++ .../social/facebook/api/AdOperations.java | 50 ++ .../social/facebook/api/AdTargeting.java | 298 ++++++++ .../social/facebook/api/Collections2.java | 50 ++ .../social/facebook/api/Dates.java | 34 + .../social/facebook/api/impl/AdTemplate.java | 100 +++ .../facebook/api/impl/FacebookTemplate.java | 8 + .../api/impl/json/AdAccountGroupMixin.java | 50 ++ .../api/impl/json/AdAccountMixin.java | 52 ++ .../api/impl/json/AdAccountUserMixin.java | 31 + .../api/impl/json/AdCampaignMixin.java | 39 + .../api/impl/json/AdCreativeMixin.java | 44 ++ .../facebook/api/impl/json/AdGroupMixin.java | 49 ++ .../api/impl/json/AdTargetingMixin.java | 56 ++ .../api/impl/json/FacebookModule.java | 16 + .../social/facebook/api/AdTemplateTest.java | 681 ++++++++++++++++++ .../facebook/api/testdata/adaccount.json | 51 ++ .../facebook/api/testdata/adaccountgroup.json | 18 + .../api/testdata/adaccountgroups.json | 40 + .../facebook/api/testdata/adaccounts.json | 55 ++ .../facebook/api/testdata/adcampaign.json | 12 + .../facebook/api/testdata/adcampaigns.json | 19 + .../facebook/api/testdata/adcreative.json | 18 + .../facebook/api/testdata/adcreatives.json | 93 +++ .../social/facebook/api/testdata/adgroup.json | 106 +++ .../facebook/api/testdata/adgroups.json | 157 ++++ 32 files changed, 2904 insertions(+) create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccount.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountGroup.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountUser.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCampaign.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCreative.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdGroup.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdOperations.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdTargeting.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Collections2.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Dates.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/AdTemplate.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountGroupMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountUserMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCampaignMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCreativeMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdGroupMixin.java create mode 100644 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdTargetingMixin.java create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/AdTemplateTest.java create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccount.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroup.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroups.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccounts.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaign.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaigns.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreative.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreatives.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroup.json create mode 100644 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroups.json diff --git a/.gitignore b/.gitignore index f0a8ce2ed..605a919eb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,10 @@ build **/src/test/java/exploration .gradle spring-social-core/src/test/java/exploration +.classpath **/.classpath +.project **/.project **/.settings +bin **/bin diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccount.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccount.java new file mode 100644 index 000000000..cd5353878 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccount.java @@ -0,0 +1,164 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Ad account object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adaccount/} + * + * @author Will Taylor + * + */ +public class AdAccount { + + private final String id; + private final String accountId; + private final String name; + private final int status; + private final String currency; + private final int timezoneId; + private final String timezoneName; + private final int verticalId; + private final String verticalName; + private final int isPersonal; + private final String businessName; + private final String businessStreet; + private final String businessStreet2; + private final String businessCity; + private final String businessState; + private final String businessZip; + private final String businessCountryCode; + private final int vatStatus; + private final int dailySpendLimit; + private final List users; + private final List accountGroups; + private final List capabilities; // marked as "reserved for future use" + + public AdAccount(String id, String accountId, String name, int status, String currency, int timezoneId, String timezoneName, int verticalId, String verticalName, int isPersonal, String businessName, String businessStreet, String businessStreet2, String businessCity, String businessState, String businessZip, String businessCountryCode, int vatStatus, int dailySpendLimit, List users, List accountGroups, List capabilities) { + this.id = id; + this.accountId = accountId; + this.name = name; + this.status = status; + this.currency = currency; + this.timezoneId = timezoneId; + this.timezoneName = timezoneName; + this.verticalId = verticalId; + this.verticalName = verticalName; + this.isPersonal = isPersonal; + this.businessName = businessName; + this.businessStreet = businessStreet; + this.businessStreet2 = businessStreet2; + this.businessCity = businessCity; + this.businessState = businessState; + this.businessZip = businessZip; + this.businessCountryCode = businessCountryCode; + this.vatStatus = vatStatus; + this.dailySpendLimit = dailySpendLimit; + this.users = Collections2.immutable(users); + this.accountGroups = Collections2.immutable(accountGroups); + this.capabilities = Collections2.immutable(capabilities); + } + + public String getId() { + return id; + } + + public String getAccountId() { + return accountId; + } + + public String getName() { + return name; + } + + public int getStatus() { + return status; + } + + public String getCurrency() { + return currency; + } + + public int getTimezoneId() { + return timezoneId; + } + + public String getTimezoneName() { + return timezoneName; + } + + public int getVerticalId() { + return verticalId; + } + + public String getVerticalName() { + return verticalName; + } + + public int getIsPersonal() { + return isPersonal; + } + + public String getBusinessName() { + return businessName; + } + + public String getBusinessStreet() { + return businessStreet; + } + + public String getBusinessStreet2() { + return businessStreet2; + } + + public String getBusinessCity() { + return businessCity; + } + + public String getBusinessState() { + return businessState; + } + + public String getBusinessZip() { + return businessZip; + } + + public String getBusinessCountryCode() { + return businessCountryCode; + } + + public int getVatStatus() { + return vatStatus; + } + + public int getDailySpendLimit() { + return dailySpendLimit; + } + + public List getUsers() { + return Collections2.copy(users); + } + + public List getAccountGroups() { + return Collections2.copy(accountGroups); + } + + public List getCapabilities() { + return Collections2.copy(capabilities); + } + +} \ No newline at end of file diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountGroup.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountGroup.java new file mode 100644 index 000000000..71b7a5800 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountGroup.java @@ -0,0 +1,104 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Ad Account Group object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adaccountgroup/} + * + * @author Will Taylor + * + */ +public class AdAccountGroup { + + private final String accountGroupId; + private final String id; + private final String name; + private final int status; + private final List users; + private final List accounts; + + public AdAccountGroup(String accountGroupId, String id, String name, int status, List users, List accounts) { + this.accountGroupId = accountGroupId; + this.id = id; + this.name = name; + this.status = status; + this.users = Collections2.immutable(users); + this.accounts = Collections2.immutable(accounts); + } + + public String getAccountGroupId() { + return accountGroupId; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public int getStatus() { + return status; + } + + public List getUsers() { + return Collections2.copy(users); + } + + public List getAccounts() { + return Collections2.copy(accounts); + } + + public static class LiteAdAccountUser { + private final String uid; + private final int role; + + public LiteAdAccountUser(String uid, int role) { + this.uid = uid; + this.role = role; + } + + public String getUid() { + return uid; + } + + public int getRole() { + return role; + } + } + + public static class LiteAdAccount { + private final String accountId; + private final int status; + + public LiteAdAccount(String accountId, int status) { + this.accountId = accountId; + this.status = status; + } + + public String getAccountId() { + return accountId; + } + + public int getStatus() { + return status; + } + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountUser.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountUser.java new file mode 100644 index 000000000..4d4d15fb3 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdAccountUser.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Ad Account User object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adaccountgroup/} + * + * @author Will Taylor + * + */ +public class AdAccountUser { + + private final String uid; + private final List permissions; + private final int role; + + public AdAccountUser(String uid, List permissions, int role) { + this.uid = uid; + this.permissions = Collections2.immutable(permissions); + this.role = role; + } + + public String getUid() { + return uid; + } + + public List getPermissions() { + return Collections2.copy(permissions); + } + + public int getRole() { + return role; + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCampaign.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCampaign.java new file mode 100644 index 000000000..2708ca9ae --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCampaign.java @@ -0,0 +1,118 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.Date; + +/** + * Ad Campaign User object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adcampaign/} + * + * @author Will Taylor + * + */ +public class AdCampaign { + + private final String accountId; + private final String campaignId; + private final String name; + private final int dailyBudget; + private final CampaignStatus campaignStatus; + private final int dailyImpressions; + private final String id; + private final Date startTime; + private final Date endTime; + private final Date updatedTime; + + public AdCampaign(String accountId, String campaignId, String name, int dailyBudget, CampaignStatus campaignStatus, int dailyImpressions, String id, Date startTime, Date endTime, Date updatedTime) { + this.accountId = accountId; + this.campaignId = campaignId; + this.name = name; + this.dailyBudget = dailyBudget; + this.campaignStatus = campaignStatus; + this.dailyImpressions = dailyImpressions; + this.id = id; + this.startTime = Dates.copy(startTime); + this.endTime = Dates.copy(endTime); + this.updatedTime = Dates.copy(updatedTime); + } + + public String getAccountId() { + return accountId; + } + + public String getCampaignId() { + return campaignId; + } + + public String getName() { + return name; + } + + public int getDailyBudget() { + return dailyBudget; + } + + public CampaignStatus getCampaignStatus() { + return campaignStatus; + } + + public int getDailyImpressions() { + return dailyImpressions; + } + + public String getId() { + return id; + } + + public Date getStartTime() { + return Dates.copy(startTime); + } + + public Date getEndTime() { + return Dates.copy(endTime); + } + + public Date getUpdatedTime() { + return Dates.copy(updatedTime); + } + + public enum CampaignStatus { + UNUSED_0(0), ACTIVE(1), PAUSED(2), DELETED(3); + private final int campaignStatus; + private CampaignStatus(int campaignStatus){ this.campaignStatus = campaignStatus; } + public int getCampaignStatus() { return campaignStatus; } + public static CampaignStatus getValue(int campaignStatus) { + CampaignStatus result = null; + + switch ( campaignStatus ) { + case 1: + result = ACTIVE; + break; + case 2: + result = PAUSED; + break; + case 3: + result = DELETED; + break; + default: + throw new EnumConstantNotPresentException(CampaignStatus.class, String.valueOf(campaignStatus)); + } + + return result; + } + } + +} \ No newline at end of file diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCreative.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCreative.java new file mode 100644 index 000000000..2a68d0409 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdCreative.java @@ -0,0 +1,128 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Ad Creative object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adcreative/} + * + * @author Will Taylor + * + */ +public class AdCreative { + + private final String name; + private final int type; + private final long objectId; + private final String body; + private final String imageHash; + private final String imageUrl; + private final long creativeId; + private final int countCurrentAdGroups; //?? A string? + private final String title; + private final int runStatus; + private final String linkUrl; + private final String previewUrl; + private final String viewTag; + private final List altViewTags; + private final String id; + private final String urlTags; + + public AdCreative(String name, int type, long objectId, String body, String imageHash, String imageUrl, long creativeId, int countCurrentAdGroups, String title, int runStatus, String linkUrl, String previewUrl, String viewTag, List altViewTags, String id, String urlTags) { + this.name = name; + this.type = type; + this.objectId = objectId; + this.body = body; + this.imageHash = imageHash; + this.imageUrl = imageUrl; + this.creativeId = creativeId; + this.countCurrentAdGroups = countCurrentAdGroups; + this.title = title; + this.runStatus = runStatus; + this.linkUrl = linkUrl; + this.previewUrl = previewUrl; + this.viewTag = viewTag; + this.altViewTags = Collections2.immutable(altViewTags); + this.id = id; + this.urlTags = urlTags; + } + + public String getName() { + return name; + } + + public int getType() { + return type; + } + + public long getObjectId() { + return objectId; + } + + public String getBody() { + return body; + } + + public String getImageHash() { + return imageHash; + } + + public String getImageUrl() { + return imageUrl; + } + + public long getCreativeId() { + return creativeId; + } + + public int getCountCurrentAdGroups() { + return countCurrentAdGroups; + } + + public String getTitle() { + return title; + } + + public int getRunStatus() { + return runStatus; + } + + public String getLinkUrl() { + return linkUrl; + } + + public String getPreviewUrl() { + return previewUrl; + } + + public String getViewTag() { + return viewTag; + } + + public List getAltViewTags() { + return Collections2.copy(altViewTags); + } + + public String getId() { + return id; + } + + public String getUrlTags() { + return urlTags; + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdGroup.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdGroup.java new file mode 100644 index 000000000..cb213b80b --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdGroup.java @@ -0,0 +1,210 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.springframework.social.facebook.api.AdTargeting.EducationStatus; + +/** + * Ad Group object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adgroup/} + * + * @author Will Taylor + * + */ +public class AdGroup { + + private final String adId; + private final String id; + private final String accountId; + private final String campaignId; + private final String name; + private final int adStatus; + private final AdGroupStatus adGroupStatus; + private final int bidType; + private final String maxBid; //?? String? + private final AdTargeting targeting; + private final List creativeIds; + private final String adGroupId; + private final Date startTime; + private final Date endTime; + private final Date updatedTime; + private final Map bidInfo; + private final List disapproveReasonDescriptions; + + public AdGroup(String adId, String id, String accountId, String campaignId, String name, int adStatus, AdGroupStatus adGroupStatus, int bidType, String maxBid, AdTargeting targeting, List creativeIds, String adGroupId, Date startTime, Date endTime, Date updatedTime, Map bidInfo, List disapproveReasonDescriptions) { + this.adId = adId; + this.id = id; + this.accountId = accountId; + this.campaignId = campaignId; + this.name = name; + this.adStatus = adStatus; + this.adGroupStatus = adGroupStatus; + this.bidType = bidType; + this.maxBid = maxBid; + this.targeting = targeting; + this.creativeIds = Collections2.immutable(creativeIds); + this.adGroupId = adGroupId; + this.startTime = Dates.copy(startTime); + this.endTime = Dates.copy(endTime); + this.updatedTime = Dates.copy(updatedTime); + this.bidInfo = Collections2.immutable(bidInfo); + this.disapproveReasonDescriptions = Collections2.immutable(disapproveReasonDescriptions); + } + + public String getAdId() { + return adId; + } + + public String getId() { + return id; + } + + public String getAccountId() { + return accountId; + } + + public String getCampaignId() { + return campaignId; + } + + public String getName() { + return name; + } + + public int getAdStatus() { + return adStatus; + } + + public AdGroupStatus getAdGroupStatus() { + return adGroupStatus; + } + + public int getBidType() { + return bidType; + } + + public String getMaxBid() { + return maxBid; + } + + public AdTargeting getTargeting() { + return targeting; + } + + public List getCreativeIds() { + return Collections2.copy(creativeIds); + } + + public String getAdGroupId() { + return adGroupId; + } + + public Date getStartTime() { + return Dates.copy(startTime); + } + + public Date getEndTime() { + return Dates.copy(endTime); + } + + public Date getUpdatedTime() { + return Dates.copy(updatedTime); + } + + public Map getBidInfo() { + return Collections2.copy(bidInfo); + } + + public List getDisapproveReasonDescriptions() { + return Collections2.copy(disapproveReasonDescriptions); + } + + public enum AdGroupStatus { + UNUSED_0(0), + ACTIVE(1), + UNUSED_2(2), + DELETED(3), + PENDING_REVIEW(4), + DISAPPROVED(5), + UNUSED_6(6), + UNUSED_7(7), + CAMPAIGN_PAUSED(8), + ADGROUP_PAUSED(9); + private final int adGroupStatus; + AdGroupStatus(int adGroupStatus) { this.adGroupStatus = adGroupStatus; } + public int getAdGroupStatus() { return adGroupStatus; } + public static AdGroupStatus getValue(int adGroupStatus) { + AdGroupStatus result = null; + + switch ( adGroupStatus ) { + case 1: + result = ACTIVE; + break; + case 3: + result = DELETED; + break; + case 4: + result = PENDING_REVIEW; + break; + case 5: + result = DISAPPROVED; + break; + case 8: + result = CAMPAIGN_PAUSED; + break; + case 9: + result = ADGROUP_PAUSED; + break; + default: + throw new EnumConstantNotPresentException(EducationStatus.class, String.valueOf(adGroupStatus)); + } + + return result; + } + } + + // The behavior of the API isn't lining up with the documentation...I'm getting back 6 + // From the API Doc: http://developers.facebook.com/docs/reference/ads-api/adgroup/ + // bid_type, int, Use 1 for CPC and 2 for CPM; required when creating ad groups; cannot be updated + public enum BidType { + UNUSED_0(0), + CPC(1), + CPM(2); + private final int bidType; + BidType(int bidType) { this.bidType = bidType; } + public int getBidType() { return bidType; } + public static BidType getValue(int bidType) { + BidType result = null; + + switch ( bidType ) { + case 1: + result = CPC; + break; + case 2: + result = CPM; + break; + default: + throw new EnumConstantNotPresentException(EducationStatus.class, String.valueOf(bidType)); + } + + return result; + } + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdOperations.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdOperations.java new file mode 100644 index 000000000..754d7b1bf --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdOperations.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Facebook Advertising API Operations + * + * @author Will Taylor + * + */ +public interface AdOperations { + + List getAdAccountGroupsForUser(String userId); + + AdAccountGroup getAdAccountGroup(String adAccountGroupId); + + List getAdAccountsForUser(String userId); + + AdAccount getAdAccount(String adAccountId); + + List getAdGroups(String adAccountId); + + AdGroup getAdGroup(String adGroupId); + + List getCreatives(String adAccountId); + + AdCreative getCreative(String creativeId); + + List getAdCampaigns(String adAccountId); + + AdCampaign getAdCampaign(String campaignId); + + List getAdGroupsForCampaign(String campaignId); + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdTargeting.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdTargeting.java new file mode 100644 index 000000000..7de7482e2 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/AdTargeting.java @@ -0,0 +1,298 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.List; + +/** + * Ad Targeting object on Facebook {@link http://developers.facebook.com/docs/reference/ads-api/adgroup/} + * + * @author Will Taylor + * + */ +public class AdTargeting { + + // Location Targets + private final List countries; + private final List cities; + private final List zips; + private final List regions; + private final String radius; + private final List locales; + + // Likes / Interest Targets + private final List keywords; + private final List userAdClusters; + private final List interestedIn; + + // Demographics / Events + private final List genders; + private final Integer ageMin; + private final Integer ageMax; + private final BroadAge broadAge; + private final List relationshipStatuses; + private final UserEvent userEvent; + + // Facebook Connections + private final List connections; + private final List excludedConnections; + private final List friendsOfConnections; + + // Education and Work + private final List collegeNetworks; + private final List workNetworks; + private final List educationStatuses; + private final List collegeYears; + private final List collegeMajors; + + public AdTargeting(List countries, List cities, List zips, List regions, String radius, List locales, List keywords, List userAdClusters, List interestedIn, List genders, Integer ageMin, Integer ageMax, BroadAge broadAge, List relationshipStatuses, UserEvent userEvent, List connections, List excludedConnections, List friendsOfConnections, List collegeNetworks, List workNetworks, List educationStatuses, List collegeYears, List collegeMajors) { + this.countries = Collections2.immutable(countries); + this.cities = Collections2.immutable(cities); + this.zips = Collections2.immutable(zips); + this.regions = Collections2.immutable(regions); + this.radius = radius; + this.locales = Collections2.immutable(locales); + this.keywords = Collections2.immutable(keywords); + this.userAdClusters = Collections2.immutable(userAdClusters); + this.interestedIn = Collections2.immutable(interestedIn); + this.genders = Collections2.immutable(genders); + this.ageMin = ageMin; + this.ageMax = ageMax; + this.broadAge = broadAge; + this.relationshipStatuses = Collections2.immutable(relationshipStatuses); + this.userEvent = userEvent; + this.connections = Collections2.immutable(connections); + this.excludedConnections = Collections2.immutable(excludedConnections); + this.friendsOfConnections = Collections2.immutable(friendsOfConnections); + this.collegeNetworks = Collections2.immutable(collegeNetworks); + this.workNetworks = Collections2.immutable(workNetworks); + this.educationStatuses = Collections2.immutable(educationStatuses); + this.collegeYears = Collections2.immutable(collegeYears); + this.collegeMajors = Collections2.immutable(collegeMajors); + } + + public List getGenders( ) { + return Collections2.copy(genders); + } + + public List getCountries() { + return Collections2.copy(countries); + } + + public List getCities() { + return Collections2.copy(cities); + } + + public List getZips() { + return Collections2.copy(zips); + } + + public List getRegions() { + return Collections2.copy(regions); + } + + public String getRadius() { + return radius; + } + + public List getLocales() { + return Collections2.copy(locales); + } + + public List getKeywords() { + return Collections2.copy(keywords); + } + + public List getUserAdClusters() { + return Collections2.copy(userAdClusters); + } + + public List getInterestedIn() { + return Collections2.copy(interestedIn); + } + + public Integer getAgeMin() { + return ageMin; + } + + public Integer getAgeMax() { + return ageMax; + } + + public BroadAge getBroadAge() { + return broadAge; + } + + public List getRelationshipStatuses() { + return Collections2.copy(relationshipStatuses); + } + + public UserEvent getUserEvent() { + return userEvent; + } + + public List getConnections() { + return Collections2.copy(connections); + } + + public List getExcludedConnections() { + return Collections2.copy(excludedConnections); + } + + public List getFriendsOfConnections() { + return Collections2.copy(friendsOfConnections); + } + + public List getCollegeNetworks() { + return Collections2.copy(collegeNetworks); + } + + public List getWorkNetworks() { + return Collections2.copy(workNetworks); + } + + public List getEducationStatuses() { + return Collections2.copy(educationStatuses); + } + + public List getCollegeYears() { + return Collections2.copy(collegeYears); + } + + public List getCollegeMajors() { + return Collections2.copy(collegeMajors); + } + + public enum Gender { + UNUSED_0(0), MALE(1), FEMALE(2); + private final int gender; + private Gender(int gender){ this.gender = gender; } + public int getGender() { return gender; } + public static Gender getValue(int gender) { + Gender result = null; + + switch ( gender ) { + case 1: + result = MALE; + break; + case 2: + result = FEMALE; + break; + default: + throw new EnumConstantNotPresentException(Gender.class, String.valueOf(gender)); + } + + return result; + } + } + + public enum BroadAge { + UNUSED_0(0), ENABLED(1); + private final int broadAge; + private BroadAge(int broadAge){ this.broadAge = broadAge; } + public int getBroadAge() { return broadAge; } + public static BroadAge getValue(int broadAge) { + BroadAge result = null; + + switch ( broadAge ) { + case 1: + result = ENABLED; + break; + default: + throw new EnumConstantNotPresentException(BroadAge.class, String.valueOf(broadAge)); + } + + return result; + } + } + + public enum RelationshipStatus { + UNUSED_0(0), SINGLE(1), IN_RELATIONSHIP(2), MARRIED(3), ENGAGED(4); + private final int relationshipStatus; + private RelationshipStatus(int relationshipStatus){ this.relationshipStatus = relationshipStatus; } + public int getRelationshipStatus() { return relationshipStatus; } + public static RelationshipStatus getValue(int relationshipStatus) { + RelationshipStatus result = null; + + switch ( relationshipStatus ) { + case 1: + result = SINGLE; + break; + case 2: + result = IN_RELATIONSHIP; + break; + case 3: + result = MARRIED; + break; + case 4: + result = ENGAGED; + break; + default: + throw new EnumConstantNotPresentException(RelationshipStatus.class, String.valueOf(relationshipStatus)); + } + + return result; + } + } + + public enum UserEvent { + UNUSED_0(0), BIRTHDAY(1); + private final int userEvent; + private UserEvent(int userEvent){ this.userEvent = userEvent; } + public int getUserEvent() { return userEvent; } + public static UserEvent getValue(int userEvent) { + UserEvent result = null; + + switch ( userEvent ) { + case 1: + result = BIRTHDAY; + break; + default: + throw new EnumConstantNotPresentException(UserEvent.class, String.valueOf(userEvent)); + } + + return result; + } + } + + public enum EducationStatus { + UNUSED_0(0), HIGH_SCHOOL(1), UNDERGRAD(2), ALUM(3); + private final int educationStatus; + private EducationStatus(int educationStatus){ this.educationStatus = educationStatus; } + public int getEducationStatus() { return educationStatus; } + public static EducationStatus getValue(int educationStatus) { + EducationStatus result = null; + + switch ( educationStatus ) { + case 1: + result = HIGH_SCHOOL; + break; + case 2: + result = UNDERGRAD; + break; + case 3: + result = ALUM; + break; + default: + throw new EnumConstantNotPresentException(EducationStatus.class, String.valueOf(educationStatus)); + } + + return result; + } + } + + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Collections2.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Collections2.java new file mode 100644 index 000000000..b1efdf36b --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Collections2.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Utilities for various java.util.Collection implementations + * + * @author Will Taylor + * + */ +class Collections2 { + + private Collections2() {} // private to prevent instantiation + + static List immutable(List list) { + return list == null ? list : Collections.unmodifiableList(new ArrayList(list)); + } + + static List copy(List list) { + return list == null ? list : new ArrayList(list); + } + + static Map immutable(Map map) { + return map == null ? null : Collections.unmodifiableMap(new HashMap(map)); + } + + static Map copy(Map map) { + return map == null ? null : new HashMap(map); + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Dates.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Dates.java new file mode 100644 index 000000000..d9bc954f2 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/Dates.java @@ -0,0 +1,34 @@ +/* + * Copyright 2010 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import java.util.Date; + +/** + * Utilities for java.util.Date + * + * @author Will Taylor + * + */ +class Dates { + + private Dates() {} // private to prevent instantiation + + static Date copy(final Date date) { + return date == null ? null : new Date(date.getTime()); + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/AdTemplate.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/AdTemplate.java new file mode 100644 index 000000000..4cdf3ad72 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/AdTemplate.java @@ -0,0 +1,100 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl; + +import java.util.List; + +import org.springframework.social.facebook.api.AdAccount; +import org.springframework.social.facebook.api.AdAccountGroup; +import org.springframework.social.facebook.api.AdCampaign; +import org.springframework.social.facebook.api.AdCreative; +import org.springframework.social.facebook.api.AdGroup; +import org.springframework.social.facebook.api.AdOperations; +import org.springframework.social.facebook.api.GraphApi; + +/** + * Facebook Advertising API Operations + * + * @author Will Taylor + * + */ +public class AdTemplate extends AbstractFacebookOperations implements AdOperations { + + private static final String ACT_PREFIX = "act_"; + + private final GraphApi graphApi; + + public AdTemplate(GraphApi graphApi, boolean isAuthorized) { + super(isAuthorized); + this.graphApi = graphApi; + } + + @Override + public List getAdAccountGroupsForUser(String userId) { + return graphApi.fetchConnections(userId, "adaccountgroups", AdAccountGroup.class); + } + + @Override + public AdAccountGroup getAdAccountGroup(String adAccountGroupId) { + return graphApi.fetchObject(adAccountGroupId, AdAccountGroup.class); + } + + @Override + public List getAdAccountsForUser(String userId) { + return graphApi.fetchConnections(userId, "adaccounts", AdAccount.class); + } + + @Override + public AdAccount getAdAccount(String adAccountId) { + return graphApi.fetchObject(ACT_PREFIX + adAccountId, AdAccount.class); + } + + @Override + public List getAdGroups(String adAccountId) { + return graphApi.fetchConnections(ACT_PREFIX + adAccountId, "adgroups", AdGroup.class); + } + + @Override + public AdGroup getAdGroup(String adGroupId) { + return graphApi.fetchObject(adGroupId, AdGroup.class); + } + + @Override + public List getCreatives(String adAccountId) { + return graphApi.fetchConnections(ACT_PREFIX + adAccountId, "adcreatives", AdCreative.class); + } + + @Override + public AdCreative getCreative(String creativeId) { + return graphApi.fetchObject(creativeId, AdCreative.class); + } + + @Override + public List getAdCampaigns(String adAccountId) { + return graphApi.fetchConnections(ACT_PREFIX + adAccountId, "adcampaigns", AdCampaign.class); + } + + @Override + public AdCampaign getAdCampaign(String campaignId) { + return graphApi.fetchObject(campaignId, AdCampaign.class); + } + + @Override + public List getAdGroupsForCampaign(String campaignId) { + return graphApi.fetchConnections(campaignId, "adgroups", AdGroup.class); + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FacebookTemplate.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FacebookTemplate.java index 8e6c52adf..3c9953f34 100644 --- a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FacebookTemplate.java +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FacebookTemplate.java @@ -30,6 +30,7 @@ import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; import org.springframework.social.NotAuthorizedException; import org.springframework.social.UncategorizedApiException; +import org.springframework.social.facebook.api.AdOperations; import org.springframework.social.facebook.api.CommentOperations; import org.springframework.social.facebook.api.EventOperations; import org.springframework.social.facebook.api.Facebook; @@ -83,6 +84,8 @@ public class FacebookTemplate extends AbstractOAuth2ApiBinding implements Facebo private MediaOperations mediaOperations; private PageOperations pageOperations; + + private AdOperations adOperations; private ObjectMapper objectMapper; @@ -154,6 +157,10 @@ public PageOperations pageOperations() { return pageOperations; } + public AdOperations adOperations() { + return adOperations; + } + // low-level Graph API operations public T fetchObject(String objectId, Class type) { URI uri = URIBuilder.fromUri(GRAPH_API_URL + objectId).build(); @@ -256,6 +263,7 @@ private void initSubApis() { mediaOperations = new MediaTemplate(this, getRestTemplate(), isAuthorized()); groupOperations = new GroupTemplate(this, isAuthorized()); pageOperations = new PageTemplate(this, isAuthorized()); + adOperations = new AdTemplate(this, isAuthorized()); } @SuppressWarnings("unchecked") diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountGroupMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountGroupMixin.java new file mode 100644 index 000000000..f75af1aee --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountGroupMixin.java @@ -0,0 +1,50 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.springframework.social.facebook.api.AdAccount; +import org.springframework.social.facebook.api.AdAccountUser; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdAccountGroupMixin { + + @JsonCreator + AdAccountGroupMixin(@JsonProperty("account_group_id") String accountGroupId, + @JsonProperty("id") String id, + @JsonProperty("name") String name, + @JsonProperty("status") int status, + @JsonProperty("users") List users, + @JsonProperty("accounts") List accounts) {} + + //@JsonIgnoreProperties(ignoreUnknown = true) + static class LiteAdAccountUserMixin { + @JsonCreator + LiteAdAccountUserMixin(@JsonProperty("uid") String uid, + @JsonProperty("role") int role) {} + } + + //@JsonIgnoreProperties(ignoreUnknown = true) + static class LiteAdAccountMixIn { + @JsonCreator + LiteAdAccountMixIn(@JsonProperty("account_id") String accountId, + @JsonProperty("status") int status) {} + } + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountMixin.java new file mode 100644 index 000000000..ab9ca577c --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountMixin.java @@ -0,0 +1,52 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.springframework.social.facebook.api.AdAccountGroup; +import org.springframework.social.facebook.api.AdAccountUser; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdAccountMixin { + + @JsonCreator + AdAccountMixin(@JsonProperty("id") String id, + @JsonProperty("account_id") String accountId, + @JsonProperty("name") String name, + @JsonProperty("account_status") int status, + @JsonProperty("currency") String currency, + @JsonProperty("timezone_id") int timezoneId, + @JsonProperty("timezone_name") String timezoneName, + @JsonProperty("vertical_id") int verticalId, + @JsonProperty("vertical_name") String verticalName, + @JsonProperty("is_personal") int isPersonal, + @JsonProperty("business_name") String businessName, + @JsonProperty("business_street") String businessStreet, + @JsonProperty("business_street2") String businessStreet2, + @JsonProperty("business_city") String businessCity, + @JsonProperty("business_state") String businessState, + @JsonProperty("business_zip") String businessZip, + @JsonProperty("business_country_code") String businessCountryCode, + @JsonProperty("vat_status") int vatStatus, + @JsonProperty("daily_spend_limit") int dailySpendLimit, + @JsonProperty("users") List users, + @JsonProperty("account_groups") List accountGroups, + @JsonProperty("capabilities") List capabilities) {} + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountUserMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountUserMixin.java new file mode 100644 index 000000000..6c09bd934 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdAccountUserMixin.java @@ -0,0 +1,31 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdAccountUserMixin { + + @JsonCreator + AdAccountUserMixin(@JsonProperty("uid") String uid, + @JsonProperty("permissions") List permissions, + @JsonProperty("role") int role) {} + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCampaignMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCampaignMixin.java new file mode 100644 index 000000000..c8be7edc2 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCampaignMixin.java @@ -0,0 +1,39 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.Date; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.springframework.social.facebook.api.AdCampaign.CampaignStatus; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdCampaignMixin { + + @JsonCreator + AdCampaignMixin(@JsonProperty("account_id") String accountId, + @JsonProperty("campaign_id") String campaignId, + @JsonProperty("name") String name, + @JsonProperty("daily_budget") int dailyBudget, + @JsonProperty("campaign_status") CampaignStatus campaignStatus, + @JsonProperty("daily_imps") int dailyImpressions, + @JsonProperty("id") String id, + @JsonProperty("start_time") Date startTime, + @JsonProperty("end_time") Date endTime, + @JsonProperty("updated_time") Date updatedTime) {} + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCreativeMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCreativeMixin.java new file mode 100644 index 000000000..b62393dc4 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdCreativeMixin.java @@ -0,0 +1,44 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdCreativeMixin { + + @JsonCreator + AdCreativeMixin(@JsonProperty("name") String name, + @JsonProperty("type") int type, + @JsonProperty("object_id") long objectId, + @JsonProperty("body") String body, + @JsonProperty("image_hash") String imageHash, + @JsonProperty("image_url") String imageUrl, + @JsonProperty("creative_id") long creativeId, + @JsonProperty("count_current_adgroups") int countCurrentAdGroups, + @JsonProperty("title") String title, + @JsonProperty("run_status") int runStatus, + @JsonProperty("link_url") String linkUrl, + @JsonProperty("preview_url") String previewUrl, + @JsonProperty("view_tag") String viewTag, + @JsonProperty("alt_view_tags") List altViewTags, + @JsonProperty("id") String id, + @JsonProperty("url_tags") String urlTags) {} + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdGroupMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdGroupMixin.java new file mode 100644 index 000000000..c9f3ecfe0 --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdGroupMixin.java @@ -0,0 +1,49 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.springframework.social.facebook.api.AdGroup.AdGroupStatus; +import org.springframework.social.facebook.api.AdTargeting; + +//@JsonIgnoreProperties(ignoreUnknown = true) +class AdGroupMixin { + + @JsonCreator + AdGroupMixin(@JsonProperty("ad_id") String adId, + @JsonProperty("id") String id, + @JsonProperty("account_id") String accountId, + @JsonProperty("campaign_id") String campaignId, + @JsonProperty("name") String name, + @JsonProperty("ad_status") int status, + @JsonProperty("adgroup_status") AdGroupStatus adGroupStatus, + @JsonProperty("bid_type") int bidType, + @JsonProperty("max_bid") String maxBid, + @JsonProperty("targeting") AdTargeting targeting, + @JsonProperty("creative_ids") List creativeIds, + @JsonProperty("adgroup_id") String adGroupId, + @JsonProperty("start_time") Date startTime, + @JsonProperty("end_time") Date endTime, + @JsonProperty("updated_time") Date updatedTime, + @JsonProperty("bid_info") Map bidInfo, + @JsonProperty("disapprove_reason_descriptions") List disapproveReasonDescriptions) {} + +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdTargetingMixin.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdTargetingMixin.java new file mode 100644 index 000000000..7459cf0aa --- /dev/null +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/AdTargetingMixin.java @@ -0,0 +1,56 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api.impl.json; + +import java.util.List; + +import org.codehaus.jackson.annotate.JsonCreator; +import org.codehaus.jackson.annotate.JsonProperty; +import org.springframework.social.facebook.api.AdTargeting.BroadAge; +import org.springframework.social.facebook.api.AdTargeting.EducationStatus; +import org.springframework.social.facebook.api.AdTargeting.Gender; +import org.springframework.social.facebook.api.AdTargeting.RelationshipStatus; +import org.springframework.social.facebook.api.AdTargeting.UserEvent; +import org.springframework.social.facebook.api.Reference; + +//@JsonIgnoreProperties(ignoreUnknown=true) +public class AdTargetingMixin { + + @JsonCreator + AdTargetingMixin(@JsonProperty("countries") List countries, + @JsonProperty("cities") List cities, + @JsonProperty("zips") List zips, + @JsonProperty("regions") List regions, + @JsonProperty("radius") String radius, + @JsonProperty("locales") List locales, + @JsonProperty("keywords") List keywords, + @JsonProperty("user_adclusters") List userAdClusters, + @JsonProperty("interested_in") List interestedIn, + @JsonProperty("genders") List genders, + @JsonProperty("age_min") Integer ageMin, + @JsonProperty("age_max") Integer ageMax, + @JsonProperty("broad_age") BroadAge broadAge, + @JsonProperty("relationship_statuses") List relationshipStatuses, + @JsonProperty("user_event") UserEvent userEvent, + @JsonProperty("connections") List connections, + @JsonProperty("excluded_connections") List excludedConnections, + @JsonProperty("friends_of_connections") List friendsOfConnections, + @JsonProperty("college_networks") List collegeNetworks, + @JsonProperty("work_networks") List workNetworks, + @JsonProperty("education_statuses") List educationStatuses, + @JsonProperty("college_years") List collegeYears, + @JsonProperty("college_majors") List collegeMajors) {} +} diff --git a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/FacebookModule.java b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/FacebookModule.java index 84dc2e615..0d7665361 100644 --- a/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/FacebookModule.java +++ b/spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/FacebookModule.java @@ -18,6 +18,13 @@ import org.codehaus.jackson.Version; import org.codehaus.jackson.map.module.SimpleModule; import org.springframework.social.facebook.api.Account; +import org.springframework.social.facebook.api.AdAccount; +import org.springframework.social.facebook.api.AdAccountGroup; +import org.springframework.social.facebook.api.AdAccountUser; +import org.springframework.social.facebook.api.AdCampaign; +import org.springframework.social.facebook.api.AdCreative; +import org.springframework.social.facebook.api.AdGroup; +import org.springframework.social.facebook.api.AdTargeting; import org.springframework.social.facebook.api.Album; import org.springframework.social.facebook.api.Checkin; import org.springframework.social.facebook.api.CheckinPost; @@ -88,5 +95,14 @@ public void setupModule(SetupContext context) { context.setMixInAnnotations(Account.class, AccountMixin.class); context.setMixInAnnotations(SwfPost.class, SwfPostMixin.class); context.setMixInAnnotations(MusicPost.class, MusicPostMixin.class); + context.setMixInAnnotations(AdAccount.class, AdAccountMixin.class); + context.setMixInAnnotations(AdAccountUser.class, AdAccountUserMixin.class); + context.setMixInAnnotations(AdAccountGroup.class, AdAccountGroupMixin.class); + context.setMixInAnnotations(AdAccountGroup.LiteAdAccountUser.class, AdAccountGroupMixin.LiteAdAccountUserMixin.class); + context.setMixInAnnotations(AdAccountGroup.LiteAdAccount.class, AdAccountGroupMixin.LiteAdAccountMixIn.class); + context.setMixInAnnotations(AdGroup.class, AdGroupMixin.class); + context.setMixInAnnotations(AdTargeting.class, AdTargetingMixin.class); + context.setMixInAnnotations(AdCreative.class, AdCreativeMixin.class); + context.setMixInAnnotations(AdCampaign.class, AdCampaignMixin.class); } } diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/AdTemplateTest.java b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/AdTemplateTest.java new file mode 100644 index 000000000..9d5d9f78d --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/AdTemplateTest.java @@ -0,0 +1,681 @@ +/* + * Copyright 2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.social.facebook.api; + +import static org.junit.Assert.*; +import static org.springframework.http.HttpMethod.*; +import static org.springframework.social.test.client.RequestMatchers.*; +import static org.springframework.social.test.client.ResponseCreators.*; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.springframework.social.facebook.api.AdAccountGroup.LiteAdAccount; +import org.springframework.social.facebook.api.AdAccountGroup.LiteAdAccountUser; +import org.springframework.social.facebook.api.AdCampaign.CampaignStatus; +import org.springframework.social.facebook.api.AdGroup.AdGroupStatus; +import org.springframework.social.facebook.api.AdGroup.BidType; +import org.springframework.social.facebook.api.AdTargeting.BroadAge; +import org.springframework.social.facebook.api.AdTargeting.EducationStatus; +import org.springframework.social.facebook.api.AdTargeting.Gender; +import org.springframework.social.facebook.api.AdTargeting.RelationshipStatus; +import org.springframework.social.facebook.api.AdTargeting.UserEvent; + +/** + * Tests for org.springframework.social.facebook.api.AdOperations + * + * @author Will Taylor + */ +public class AdTemplateTest extends AbstractFacebookApiTest { + + @Test + public void getAdAccount() { + mockServer.expect(requestTo("https://graph.facebook.com/act_123456")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adaccount"), responseHeaders)); + + AdAccount adAccount = facebook.adOperations().getAdAccount("123456"); + assertNotNull(adAccount); + assertEquals("act_123456", adAccount.getId()); + assertEquals("123456", adAccount.getAccountId()); + assertEquals("Will's Test Account", adAccount.getName()); + assertEquals(1, adAccount.getStatus()); + assertEquals("USD", adAccount.getCurrency()); + assertEquals(7, adAccount.getTimezoneId()); + assertEquals("America/New_York", adAccount.getTimezoneName()); + assertEquals(25000, adAccount.getDailySpendLimit()); + assertEquals(Arrays.asList(), adAccount.getCapabilities()); + assertEquals(17, adAccount.getVerticalId()); + assertEquals("Other Services", adAccount.getVerticalName()); + assertEquals(0, adAccount.getIsPersonal()); + assertEquals("Will Taylor", adAccount.getBusinessName()); + assertEquals("123 Fake St", adAccount.getBusinessStreet()); + assertEquals("", adAccount.getBusinessStreet2()); + assertEquals("Springfield", adAccount.getBusinessCity()); + assertEquals("VT", adAccount.getBusinessState()); + assertEquals("12345", adAccount.getBusinessZip()); + assertEquals("US", adAccount.getBusinessCountryCode()); + assertEquals(1, adAccount.getVatStatus()); + + List users = adAccount.getUsers(); + assertNotNull(users); + assertEquals(2, users.size()); + + AdAccountUser user = users.get(0); + assertNotNull(user); + assertEquals("234567", user.getUid()); + assertEquals(Arrays.asList(1, 2, 3, 4, 5, 7), user.getPermissions()); + assertEquals(1001, user.getRole()); + + user = users.get(1); + assertNotNull(user); + assertEquals("345678", user.getUid()); + assertEquals(Arrays.asList(7), user.getPermissions()); + assertEquals(1003, user.getRole()); + + List groups = adAccount.getAccountGroups(); + assertNotNull(groups); + assertEquals(1, groups.size()); + AdAccountGroup group = groups.get(0); + assertNotNull(group); + assertEquals("987654", group.getAccountGroupId()); + assertEquals("Test Account Group 1", group.getName()); + assertEquals(1, group.getStatus()); + } + + @Test + public void getAdAccountGroupsForUser() { + mockServer.expect(requestTo("https://graph.facebook.com/123456/adaccountgroups")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adaccountgroups"), responseHeaders)); + + List adAccountGroups = facebook.adOperations().getAdAccountGroupsForUser("123456"); + assertNotNull(adAccountGroups); + assertEquals(2, adAccountGroups.size()); + + AdAccountGroup group = adAccountGroups.get(0); + assertNotNull(group); + assertEquals("112233445566", group.getAccountGroupId()); + assertEquals("Test Account Group 2", group.getName()); + assertEquals(1, group.getStatus()); + assertEquals("112233445566", group.getId()); + + List users = group.getUsers(); + assertNotNull(users); + assertEquals(1, users.size()); + LiteAdAccountUser user = users.get(0); + assertNotNull(user); + assertEquals("12345667", user.getUid()); + assertEquals(1001, user.getRole()); + + List accounts = group.getAccounts(); + assertNotNull(accounts); + assertEquals(1, accounts.size()); + LiteAdAccount account = accounts.get(0); + assertNotNull(account); + assertEquals("2345678", account.getAccountId()); + assertEquals(1, account.getStatus()); + + group = adAccountGroups.get(1); + assertNotNull(group); + assertEquals("223344556677", group.getAccountGroupId()); + assertEquals("Test Account Group 1", group.getName()); + assertEquals(1, group.getStatus()); + assertEquals("223344556677", group.getId()); + + users = group.getUsers(); + assertNotNull(users); + assertEquals(1, users.size()); + user = users.get(0); + assertNotNull(user); + assertEquals("12345667", user.getUid()); + assertEquals(1001, user.getRole()); + + accounts = group.getAccounts(); + assertNotNull(accounts); + assertEquals(1, accounts.size()); + account = accounts.get(0); + assertNotNull(account); + assertEquals("1234567", account.getAccountId()); + assertEquals(1, account.getStatus()); + } + + @Test + public void getAdAccountGroup() { + mockServer.expect(requestTo("https://graph.facebook.com/112233445566")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adaccountgroup"), responseHeaders)); + + AdAccountGroup group = facebook.adOperations().getAdAccountGroup("112233445566"); + assertNotNull(group); + assertEquals("112233445566", group.getAccountGroupId()); + assertEquals("Test Account Group 2", group.getName()); + assertEquals(1, group.getStatus()); + assertEquals("112233445566", group.getId()); + + List users = group.getUsers(); + assertNotNull(users); + assertEquals(1, users.size()); + LiteAdAccountUser user = users.get(0); + assertNotNull(user); + assertEquals("12345667", user.getUid()); + assertEquals(1001, user.getRole()); + + List accounts = group.getAccounts(); + assertNotNull(accounts); + assertEquals(1, accounts.size()); + LiteAdAccount account = accounts.get(0); + assertNotNull(account); + assertEquals("2345678", account.getAccountId()); + assertEquals(1, account.getStatus()); + } + + @Test public void getAdAccountsForUser() { + mockServer.expect(requestTo("https://graph.facebook.com/123456/adaccounts")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adaccounts"), responseHeaders)); + + List adAccounts = facebook.adOperations().getAdAccountsForUser("123456"); + assertNotNull(adAccounts); + } + + @Test + public void getAdGroups() throws ParseException { + mockServer.expect(requestTo("https://graph.facebook.com/act_123456/adgroups")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adgroups"), responseHeaders)); + + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + + List adGroups = facebook.adOperations().getAdGroups("123456"); + assertNotNull(adGroups); + assertEquals(1, adGroups.size()); + + AdGroup adGroup = adGroups.get(0); + assertNotNull(adGroup); + assertEquals(df.parse("2011-09-09T12:58:18+0000"), adGroup.getUpdatedTime()); + assertEquals("636694801526", adGroup.getAccountId()); + assertEquals("1123456703", adGroup.getAdGroupId()); + assertEquals("1123456703", adGroup.getAdId()); + assertEquals("64819048213", adGroup.getCampaignId()); + assertEquals(Arrays.asList("574017476042"), adGroup.getCreativeIds()); + assertEquals(df.parse("2011-11-09T12:58:18+0000"), adGroup.getEndTime()); + assertEquals("1123456703", adGroup.getId()); + assertEquals("80", adGroup.getMaxBid()); + assertEquals("Test Ad", adGroup.getName()); + assertEquals(df.parse("2011-10-09T12:58:18+0000"), adGroup.getStartTime()); + assertEquals(df.parse("2011-09-09T12:58:18+0000"), adGroup.getUpdatedTime()); + assertEquals(Arrays.asList("The content promoted in your ad or Sponsored Story violates Facebook's Advertising Guidelines. Please visit our Help Center (http://www.facebook.com/help/?page=174952259238535) for additional information and examples compliant with our Advertising Guidelines."), + adGroup.getDisapproveReasonDescriptions()); + + Map bidInfo = new HashMap(); + bidInfo.put("1", "80"); + bidInfo.put("37", "0"); + bidInfo.put("38", "0"); + bidInfo.put("44", "0"); + bidInfo.put("45", "0"); + bidInfo.put("46", "20"); + + assertEquals(bidInfo, adGroup.getBidInfo()); + assertEquals(AdGroupStatus.PENDING_REVIEW, adGroup.getAdGroupStatus()); + + assertEquals(4, adGroup.getAdStatus()); + assertEquals(6, adGroup.getBidType()); + + AdTargeting targeting = adGroup.getTargeting(); + assertNotNull(targeting); + assertEquals("50", targeting.getRadius()); + assertEquals(18, targeting.getAgeMin().intValue()); + assertEquals(64, targeting.getAgeMax().intValue()); + assertEquals(BroadAge.getValue(1), targeting.getBroadAge()); + assertEquals(UserEvent.getValue(1), targeting.getUserEvent()); + assertEquals(Arrays.asList("24", "43", "51", "6"), targeting.getLocales()); + assertEquals(Arrays.asList("05401", "05446", "90210", "90266", "90267"), targeting.getZips()); + assertEquals(Arrays.asList(Gender.getValue(1), Gender.getValue(2)), targeting.getGenders()); + assertEquals(Arrays.asList(Gender.getValue(1), Gender.getValue(2)), targeting.getInterestedIn()); + assertEquals(Arrays.asList("US", "CA"), targeting.getCountries()); + assertEquals(Arrays.asList("dirtbikes"), targeting.getKeywords()); + assertEquals(Arrays.asList("business", "computer science"), targeting.getCollegeMajors()); + assertEquals(Arrays.asList(2012, 2013, 2014, 2015), targeting.getCollegeYears()); + assertEquals(Arrays.asList(RelationshipStatus.getValue(1), + RelationshipStatus.getValue(2), + RelationshipStatus.getValue(3), + RelationshipStatus.getValue(4)), targeting.getRelationshipStatuses()); + assertEquals(Arrays.asList(EducationStatus.getValue(1), + EducationStatus.getValue(2), + EducationStatus.getValue(3)), targeting.getEducationStatuses()); + + List workNetworks = targeting.getWorkNetworks(); + assertNotNull(workNetworks); + assertEquals(1, workNetworks.size()); + Reference workNetwork = workNetworks.get(0); + assertNotNull(workNetwork); + assertEquals("50432078", workNetwork.getId()); + assertEquals("IBM", workNetwork.getName()); + + List collegeNetworks = targeting.getCollegeNetworks(); + assertNotNull(collegeNetworks); + assertEquals(1, collegeNetworks.size()); + Reference collegeNetwork = collegeNetworks.get(0); + assertNotNull(collegeNetwork); + assertEquals("16777220", collegeNetwork.getId()); + assertEquals("Yale", collegeNetwork.getName()); + + List cities = targeting.getCities(); + assertNotNull(cities); + assertEquals(2, cities.size()); + + Reference city = cities.get(0); + assertNotNull(city); + assertEquals("2420467", city.getId()); + assertEquals("Manhattan Beach, CA", city.getName()); + + city = cities.get(1); + assertNotNull(city); + assertEquals("2532970", city.getId()); + assertEquals("Burlington, VT", city.getName()); + + List regions = targeting.getRegions(); + assertNotNull(regions); + assertEquals(2, regions.size()); + + Reference region = regions.get(0); + assertNotNull(region); + assertEquals("50", region.getId()); + assertEquals("Vermont", region.getName()); + + region = regions.get(1); + assertNotNull(region); + assertEquals("6", region.getId()); + assertEquals("California", region.getName()); + + List connections = targeting.getConnections(); + assertNotNull(connections); + assertEquals(1, connections.size()); + Reference connection = connections.get(0); + assertNotNull(connection); + assertEquals("125614587505822", connection.getId()); + assertEquals("Demo Motors", connection.getName()); + + List excludedConnections = targeting.getExcludedConnections(); + assertNotNull(excludedConnections); + assertEquals(1, excludedConnections.size()); + Reference excludedConnection = excludedConnections.get(0); + assertNotNull(excludedConnection); + assertEquals("125614587505822", excludedConnection.getId()); + assertEquals("Demo Motors", excludedConnection.getName()); + + List friendsOfConnections = targeting.getFriendsOfConnections(); + assertNotNull(friendsOfConnections); + assertEquals(1, friendsOfConnections.size()); + Reference friendsOfConnection = friendsOfConnections.get(0); + assertNotNull(friendsOfConnection); + assertEquals("47190376042235", friendsOfConnection.getId()); + assertEquals("Scuba Steve", friendsOfConnection.getName()); + + List userAdClusters = targeting.getUserAdClusters(); + assertNotNull(userAdClusters); + assertEquals(3, userAdClusters.size()); + + Reference userAdCluster = userAdClusters.get(0); + assertNotNull(userAdCluster); + assertEquals("6002714398172", userAdCluster.getId()); + assertEquals("Newlywed (<1 year)", userAdCluster.getName()); + + userAdCluster = userAdClusters.get(1); + assertNotNull(userAdCluster); + assertEquals("6002714398772", userAdCluster.getId()); + assertEquals("Engaged (<6 months)", userAdCluster.getName()); + + userAdCluster = userAdClusters.get(2); + assertNotNull(userAdCluster); + assertEquals("6002714885172", userAdCluster.getId()); + assertEquals("Cooking", userAdCluster.getName()); + } + + @Test + public void getAdGroup() { + mockServer.expect(requestTo("https://graph.facebook.com/123456")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adgroup"), responseHeaders)); + + AdGroup adGroup = facebook.adOperations().getAdGroup("123456"); + assertNotNull(adGroup); + } + + @Test public void getCreatives() { + mockServer.expect(requestTo("https://graph.facebook.com/act_123456/adcreatives")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adcreatives"), responseHeaders)); + + List creatives = facebook.adOperations().getCreatives("123456"); + assertNotNull(creatives); + assertEquals(5, creatives.size()); + + AdCreative creative = creatives.get(0); + assertNotNull(creative); + assertEquals("", creative.getViewTag()); + assertEquals(Arrays.asList(), creative.getAltViewTags()); + assertEquals(6003608508993l, creative.getCreativeId()); + assertEquals(2, creative.getType()); + assertEquals("", creative.getTitle()); + assertEquals("this is some ad copy", creative.getBody()); + assertEquals("1b1134eae61cdd6d9be8499b8dcbe663", creative.getImageHash()); + assertEquals("http://www.facebook.com/demomotors?sk=wall", creative.getLinkUrl()); + assertEquals(125614587505822l, creative.getObjectId()); + assertEquals("Demo Motors-00", creative.getName()); + assertEquals(1, creative.getRunStatus()); + assertEquals("http://www.facebook.com/ads/api/creative_preview.php?cid=6003608508993", creative.getPreviewUrl()); + assertEquals(0, creative.getCountCurrentAdGroups()); + assertEquals("6003608508993", creative.getId()); + assertEquals("http://creative.ak.fbcdn.net/v41818/flyers/35/10/1315831679242172105_1_e0cee20a.jpg", creative.getImageUrl()); + assertNull( creative.getUrlTags()); + } + + @Test public void getCreative() { + mockServer.expect(requestTo("https://graph.facebook.com/123456")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adcreative"), responseHeaders)); + + AdCreative creative = facebook.adOperations().getCreative("123456"); + assertNotNull(creative); + assertEquals("", creative.getViewTag()); + assertEquals(Arrays.asList(), creative.getAltViewTags()); + assertEquals(6003608508993l, creative.getCreativeId()); + assertEquals(2, creative.getType()); + assertEquals("", creative.getTitle()); + assertEquals("this is some ad copy", creative.getBody()); + assertEquals("1b1134eae61cdd6d9be8499b8dcbe663", creative.getImageHash()); + assertEquals("http://www.facebook.com/demomotors?sk=wall", creative.getLinkUrl()); + assertEquals(125614587505822l, creative.getObjectId()); + assertEquals("Demo Motors-00", creative.getName()); + assertEquals(1, creative.getRunStatus()); + assertEquals("http://www.facebook.com/ads/api/creative_preview.php?cid=6003608508993", creative.getPreviewUrl()); + assertEquals(0, creative.getCountCurrentAdGroups()); + assertEquals("6003608508993", creative.getId()); + assertEquals("http://creative.ak.fbcdn.net/v41818/flyers/35/10/1315831679242172105_1_e0cee20a.jpg", creative.getImageUrl()); + assertNull( creative.getUrlTags()); + } + + @Test + public void getAdCampaigns() throws ParseException { + mockServer.expect(requestTo("https://graph.facebook.com/act_123456/adcampaigns")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adcampaigns"), responseHeaders)); + + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + + List adCampaigns = facebook.adOperations().getAdCampaigns("123456"); + assertNotNull(adCampaigns); + assertEquals(1, adCampaigns.size()); + + AdCampaign campaign = adCampaigns.get(0); + assertNotNull(campaign); + assertEquals("234567", campaign.getAccountId()); + assertEquals("123456", campaign.getCampaignId()); + assertEquals("My Ads", campaign.getName()); + assertEquals(500, campaign.getDailyBudget()); + assertEquals(CampaignStatus.ACTIVE, campaign.getCampaignStatus()); + assertEquals(0, campaign.getDailyImpressions()); + assertEquals("123456", campaign.getId()); + assertEquals(df.parse("2011-10-31T22:00:00+0000"), campaign.getStartTime()); + assertEquals(df.parse("2011-11-18T22:00:00+0000"), campaign.getEndTime()); + assertEquals(df.parse("2011-10-19T18:37:08+0000"), campaign.getUpdatedTime()); + } + + @Test + public void getAdCampaign() throws ParseException { + mockServer.expect(requestTo("https://graph.facebook.com/234567")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adcampaign"), responseHeaders)); + + DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + + AdCampaign campaign = facebook.adOperations().getAdCampaign("234567"); + assertNotNull(campaign); + assertEquals("234567", campaign.getAccountId()); + assertEquals("123456", campaign.getCampaignId()); + assertEquals("My Ads", campaign.getName()); + assertEquals(500, campaign.getDailyBudget()); + assertEquals(CampaignStatus.ACTIVE, campaign.getCampaignStatus()); + assertEquals(0, campaign.getDailyImpressions()); + assertEquals("123456", campaign.getId()); + assertEquals(df.parse("2011-10-31T22:00:00+0000"), campaign.getStartTime()); + assertEquals(df.parse("2011-11-18T22:00:00+0000"), campaign.getEndTime()); + assertEquals(df.parse("2011-10-19T18:37:08+0000"), campaign.getUpdatedTime()); + } + + @Test + public void getAdGroupsForCampaign() { + mockServer.expect(requestTo("https://graph.facebook.com/234567/adgroups")) + .andExpect(method(GET)) + .andExpect(header("Authorization", "OAuth someAccessToken")) + .andRespond(withResponse(jsonResource("testdata/adgroups"), responseHeaders)); + + List adGroups = facebook.adOperations().getAdGroupsForCampaign("234567"); + assertNotNull(adGroups); + assertEquals(1, adGroups.size()); + } + + @Test + public void gender() { + assertEquals(Gender.MALE, Gender.getValue(1)); + assertEquals(1, Gender.MALE.getGender()); + assertEquals(Gender.FEMALE, Gender.getValue(2)); + assertEquals(2, Gender.FEMALE.getGender()); + + EnumConstantNotPresentException exception = null; + try { + Gender.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + Gender.getValue(3); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void broadAge() { + assertEquals(BroadAge.ENABLED, BroadAge.getValue(1)); + assertEquals(1, BroadAge.ENABLED.getBroadAge()); + + EnumConstantNotPresentException exception = null; + try { + BroadAge.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + BroadAge.getValue(2); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void relationshipStatus() { + assertEquals(RelationshipStatus.SINGLE, RelationshipStatus.getValue(1)); + assertEquals(1, RelationshipStatus.SINGLE.getRelationshipStatus()); + assertEquals(RelationshipStatus.IN_RELATIONSHIP, RelationshipStatus.getValue(2)); + assertEquals(2, RelationshipStatus.IN_RELATIONSHIP.getRelationshipStatus()); + assertEquals(RelationshipStatus.MARRIED, RelationshipStatus.getValue(3)); + assertEquals(3, RelationshipStatus.MARRIED.getRelationshipStatus()); + assertEquals(RelationshipStatus.ENGAGED, RelationshipStatus.getValue(4)); + assertEquals(4, RelationshipStatus.ENGAGED.getRelationshipStatus()); + + EnumConstantNotPresentException exception = null; + try { + RelationshipStatus.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + RelationshipStatus.getValue(5); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void userEvent() { + assertEquals(UserEvent.BIRTHDAY, UserEvent.getValue(1)); + assertEquals(1, UserEvent.BIRTHDAY.getUserEvent()); + + EnumConstantNotPresentException exception = null; + try { + UserEvent.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + UserEvent.getValue(2); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void educationStatus() { + assertEquals(EducationStatus.HIGH_SCHOOL, EducationStatus.getValue(1)); + assertEquals(1, EducationStatus.HIGH_SCHOOL.getEducationStatus()); + assertEquals(EducationStatus.UNDERGRAD, EducationStatus.getValue(2)); + assertEquals(2, EducationStatus.UNDERGRAD.getEducationStatus()); + assertEquals(EducationStatus.ALUM, EducationStatus.getValue(3)); + assertEquals(3, EducationStatus.ALUM.getEducationStatus()); + + EnumConstantNotPresentException exception = null; + try { + EducationStatus.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + EducationStatus.getValue(4); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void campaignStatus() { + assertEquals(CampaignStatus.ACTIVE, CampaignStatus.getValue(1)); + assertEquals(1, CampaignStatus.ACTIVE.getCampaignStatus()); + assertEquals(CampaignStatus.PAUSED, CampaignStatus.getValue(2)); + assertEquals(2, CampaignStatus.PAUSED.getCampaignStatus()); + assertEquals(CampaignStatus.DELETED, CampaignStatus.getValue(3)); + assertEquals(3, CampaignStatus.DELETED.getCampaignStatus()); + + EnumConstantNotPresentException exception = null; + try { + CampaignStatus.getValue(0); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + + exception = null; + try { + CampaignStatus.getValue(4); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + + @Test + public void adGroupStatus() { + assertEquals(AdGroupStatus.ACTIVE, AdGroupStatus.getValue(1)); + assertEquals(1, AdGroupStatus.ACTIVE.getAdGroupStatus()); + assertEquals(AdGroupStatus.DELETED, AdGroupStatus.getValue(3)); + assertEquals(3, AdGroupStatus.DELETED.getAdGroupStatus()); + assertEquals(AdGroupStatus.PENDING_REVIEW, AdGroupStatus.getValue(4)); + assertEquals(4, AdGroupStatus.PENDING_REVIEW.getAdGroupStatus()); + assertEquals(AdGroupStatus.DISAPPROVED, AdGroupStatus.getValue(5)); + assertEquals(5, AdGroupStatus.DISAPPROVED.getAdGroupStatus()); + assertEquals(AdGroupStatus.CAMPAIGN_PAUSED, AdGroupStatus.getValue(8)); + assertEquals(8, AdGroupStatus.CAMPAIGN_PAUSED.getAdGroupStatus()); + assertEquals(AdGroupStatus.ADGROUP_PAUSED, AdGroupStatus.getValue(9)); + assertEquals(9, AdGroupStatus.ADGROUP_PAUSED.getAdGroupStatus()); + + for ( int invalid : Arrays.asList(0, 2, 6, 7, 10) ) { + EnumConstantNotPresentException exception = null; + try { + AdGroupStatus.getValue(invalid); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + } + + @Test + public void bidType() { + assertEquals(BidType.CPC, BidType.getValue(1)); + assertEquals(1, BidType.CPC.getBidType()); + assertEquals(BidType.CPM, BidType.getValue(2)); + assertEquals(2, BidType.CPM.getBidType()); + + for ( int invalid : Arrays.asList(0, 3) ) { + EnumConstantNotPresentException exception = null; + try { + BidType.getValue(invalid); + } catch ( EnumConstantNotPresentException e ) { + exception = e; + } + assertNotNull(exception); + } + } + +} diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccount.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccount.json new file mode 100644 index 000000000..069ba707c --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccount.json @@ -0,0 +1,51 @@ +{ + "id": "act_123456", + "account_id": 123456, + "name": "Will's Test Account", + "account_status": 1, + "currency": "USD", + "timezone_id": 7, + "timezone_name": "America/New_York", + "vertical_id": 17, + "vertical_name": "Other Services", + "is_personal": 0, + "business_name": "Will Taylor", + "business_street": "123 Fake St", + "business_street2": "", + "business_city": "Springfield", + "business_state": "VT", + "business_zip": "12345", + "business_country_code": "US", + "vat_status": 1, + "daily_spend_limit": 25000, + "users": [ + { + "uid": 234567, + "permissions": [ + 1, + 2, + 3, + 4, + 5, + 7 + ], + "role": 1001 + }, + { + "uid": 345678, + "permissions": [ + 7 + ], + "role": 1003 + } + ], + "account_groups": [ + { + "account_group_id": 987654, + "name": "Test Account Group 1", + "status": 1 + } + ], + "capabilities": [ + ] +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroup.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroup.json new file mode 100644 index 000000000..740fc91f5 --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroup.json @@ -0,0 +1,18 @@ +{ + "account_group_id": 112233445566, + "name": "Test Account Group 2", + "status": 1, + "users": [ + { + "uid": 12345667, + "role": 1001 + } + ], + "accounts": [ + { + "account_id": 2345678, + "status": 1 + } + ], + "id": "112233445566" +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroups.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroups.json new file mode 100644 index 000000000..ab9fce756 --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccountgroups.json @@ -0,0 +1,40 @@ +{ + "data": [ + { + "account_group_id": 112233445566, + "name": "Test Account Group 2", + "status": 1, + "users": [ + { + "uid": 12345667, + "role": 1001 + } + ], + "accounts": [ + { + "account_id": 2345678, + "status": 1 + } + ], + "id": 112233445566 + }, + { + "account_group_id": 223344556677, + "name": "Test Account Group 1", + "status": 1, + "users": [ + { + "uid": 12345667, + "role": 1001 + } + ], + "accounts": [ + { + "account_id": 1234567, + "status": 1 + } + ], + "id": 223344556677 + } + ] +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccounts.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccounts.json new file mode 100644 index 000000000..763540470 --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adaccounts.json @@ -0,0 +1,55 @@ +{ + "data": [ + { + "id": "act_123456", + "account_id": 123456, + "name": "Will's Test Account", + "account_status": 1, + "currency": "USD", + "timezone_id": 7, + "timezone_name": "America/New_York", + "vertical_id": 17, + "vertical_name": "Other Services", + "is_personal": 0, + "business_name": "Will Taylor", + "business_street": "123 Fake St", + "business_street2": "", + "business_city": "Springfield", + "business_state": "VT", + "business_zip": "12345", + "business_country_code": "US", + "vat_status": 1, + "daily_spend_limit": 25000, + "users": [ + { + "uid": 234567, + "permissions": [ + 1, + 2, + 3, + 4, + 5, + 7 + ], + "role": 1001 + }, + { + "uid": 345678, + "permissions": [ + 7 + ], + "role": 1003 + } + ], + "account_groups": [ + { + "account_group_id": 987654, + "name": "Test Account Group 1", + "status": 1 + } + ], + "capabilities": [ + ] + } + ] +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaign.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaign.json new file mode 100644 index 000000000..a131a3c7b --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaign.json @@ -0,0 +1,12 @@ +{ + "account_id": 234567, + "campaign_id": 123456, + "name": "My Ads", + "daily_budget": 500, + "campaign_status": 1, + "daily_imps": 0, + "id": "123456", + "start_time": "2011-10-31T22:00:00+0000", + "end_time": "2011-11-18T22:00:00+0000", + "updated_time": "2011-10-19T18:37:08+0000" +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaigns.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaigns.json new file mode 100644 index 000000000..3776e2b56 --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcampaigns.json @@ -0,0 +1,19 @@ +{ + "data": [ + { + "account_id": 234567, + "campaign_id": 123456, + "name": "My Ads", + "daily_budget": 500, + "campaign_status": 1, + "daily_imps": 0, + "id": "123456", + "start_time": "2011-10-31T22:00:00+0000", + "end_time": "2011-11-18T22:00:00+0000", + "updated_time": "2011-10-19T18:37:08+0000" + } + ], + "count": 1, + "limit": 100, + "offset": 0 +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreative.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreative.json new file mode 100644 index 000000000..bb3e7066c --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreative.json @@ -0,0 +1,18 @@ +{ + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003608508993, + "type": 2, + "title": "", + "body": "this is some ad copy", + "image_hash": "1b1134eae61cdd6d9be8499b8dcbe663", + "link_url": "http://www.facebook.com/demomotors?sk=wall", + "object_id": 125614587505822, + "name": "Demo Motors-00", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003608508993", + "count_current_adgroups": 0, + "id": "6003608508993", + "image_url": "http://creative.ak.fbcdn.net/v41818/flyers/35/10/1315831679242172105_1_e0cee20a.jpg" +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreatives.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreatives.json new file mode 100644 index 000000000..cd7033e9d --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adcreatives.json @@ -0,0 +1,93 @@ +{ + "data": [ + { + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003608508993, + "type": 2, + "title": "", + "body": "this is some ad copy", + "image_hash": "1b1134eae61cdd6d9be8499b8dcbe663", + "link_url": "http://www.facebook.com/demomotors?sk=wall", + "object_id": 125614587505822, + "name": "Demo Motors-00", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003608508993", + "count_current_adgroups": 0, + "id": "6003608508993", + "image_url": "http://creative.ak.fbcdn.net/v41818/flyers/35/10/1315831679242172105_1_e0cee20a.jpg" + }, + { + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003603579993, + "type": 2, + "title": "", + "body": "ad copy", + "image_hash": "c90fb45af2330064e6a9a0326cc40a40", + "link_url": "http://www.facebook.com/demomotors", + "object_id": 125614587505822, + "name": "Demo Motors", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003603579993", + "count_current_adgroups": 0, + "id": "6003603579993", + "image_url": "http://creative.ak.fbcdn.net/v41818/flyers/76/23/1315572935724739266_1_75556589.jpg" + }, + { + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003597629193, + "type": 9, + "object_id": "125614587505822", + "url_tags": "", + "name": "Page Like Story #6003597629193", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003597629193", + "count_current_adgroups": 0, + "id": "6003597629193" + }, + { + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003608511993, + "type": 2, + "title": "", + "body": "body!", + "image_hash": "c90fb45af2330064e6a9a0326cc40a40", + "link_url": "http://www.facebook.com/demomotors", + "object_id": 125614587505822, + "name": "Demo Motors-01", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003608511993", + "count_current_adgroups": 0, + "id": "6003608511993", + "image_url": "http://creative.ak.fbcdn.net/v41818/flyers/76/23/1315572935724739266_1_75556589.jpg" + }, + { + "view_tag": "", + "alt_view_tags": [ + ], + "creative_id": 6003608514393, + "type": 3, + "title": "", + "body": "this party is totally awesome", + "image_hash": "1b1134eae61cdd6d9be8499b8dcbe663", + "link_url": "http://graph.facebook.com/event.php?eid=113783858725466", + "object_id": 113783858725466, + "name": "Awesome Party", + "run_status": 1, + "preview_url": "http://www.facebook.com/ads/api/creative_preview.php?cid=6003608514393", + "count_current_adgroups": 0, + "id": "6003608514393", + "image_url": "http://creative.ak.fbcdn.net/v41818/flyers/35/10/1315831679242172105_1_e0cee20a.jpg" + } + ], + "limit": 500, + "offset": 0, + "count": 5 +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroup.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroup.json new file mode 100644 index 000000000..8082e191c --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroup.json @@ -0,0 +1,106 @@ +{ + "adgroup_id": 1123456703, + "ad_id": 1123456703, + "campaign_id": 64819048213, + "name": "Test Ad", + "ad_status": 4, + "adgroup_status": 4, + "bid_type": 6, + "max_bid": "80", + "bid_info": { + "1": "80", + "37": "0", + "38": "0", + "44": "0", + "45": "0", + "46": "20" + }, + "account_id": 636694801526, + "id": "1123456703", + "creative_ids": [ + 574017476042 + ], + "targeting": { + "age_max": 64, + "age_min": 18, + "radius" : 50, + "regions": [ + { + "id": "50", + "name": "Vermont" + }, + { + "id": "6", + "name": "California" + } + ], + "cities": [ + { + "id": "2420467", + "name": "Manhattan Beach, CA" + }, + { + "id": "2532970", + "name": "Burlington, VT" + } + ], + "zips": [ + "05401", + "05446", + "90210", + "90266", + "90267" + ], + "countries": [ + "US", + "CA" + ], + "user_adclusters": [ + { + "id": "6002714398172", + "name": "Newlywed (<1 year)" + }, + { + "id": "6002714398772", + "name": "Engaged (<6 months)" + }, + { + "id": "6002714885172", + "name": "Cooking" + } + ], + "relationship_statuses": [ + 1, + 2, + 3 + ], + "education_statuses": [ + 3 + ], + "excluded_connections": [ + { + "id": "125614587505822", + "name": "Demo Motors" + } + ], + "friends_of_connections": [ + { + "id": "47190376042235", + "name": "Scuba Steve" + } + ], + "locales": [ + "24", + "43", + "51", + "6" + ], + "broad_age": 1, + "keywords": [ + "dirtbikes" + ] + }, + "start_time": null, + "end_time": null, + "updated_time": "2011-09-09T12:58:18+0000" +} \ No newline at end of file diff --git a/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroups.json b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroups.json new file mode 100644 index 000000000..64a05cf66 --- /dev/null +++ b/spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/adgroups.json @@ -0,0 +1,157 @@ +{ + "data": [ + { + "adgroup_id": 1123456703, + "ad_id": 1123456703, + "campaign_id": 64819048213, + "name": "Test Ad", + "ad_status": 4, + "adgroup_status": 4, + "bid_type": 6, + "max_bid": "80", + "bid_info": { + "1": "80", + "37": "0", + "38": "0", + "44": "0", + "45": "0", + "46": "20" + }, + "account_id": 636694801526, + "id": "1123456703", + "creative_ids": [ + 574017476042 + ], + "disapprove_reason_descriptions": [ + "The content promoted in your ad or Sponsored Story violates Facebook's Advertising Guidelines. Please visit our Help Center (http://www.facebook.com/help/?page=174952259238535) for additional information and examples compliant with our Advertising Guidelines." + ], + "targeting": { + "age_max": 64, + "age_min": 18, + "radius" : 50, + "regions": [ + { + "id": "50", + "name": "Vermont" + }, + { + "id": "6", + "name": "California" + } + ], + "cities": [ + { + "id": "2420467", + "name": "Manhattan Beach, CA" + }, + { + "id": "2532970", + "name": "Burlington, VT" + } + ], + "zips": [ + "05401", + "05446", + "90210", + "90266", + "90267" + ], + "countries": [ + "US", + "CA" + ], + "user_adclusters": [ + { + "id": "6002714398172", + "name": "Newlywed (<1 year)" + }, + { + "id": "6002714398772", + "name": "Engaged (<6 months)" + }, + { + "id": "6002714885172", + "name": "Cooking" + } + ], + "relationship_statuses": [ + 1, + 2, + 3, + 4 + ], + "education_statuses": [ + 1, + 2, + 3 + ], + "genders": [ + 1, + 2 + ], + "college_networks": [ + { + "id": "16777220", + "name": "Yale" + } + ], + "college_majors": [ + "business", + "computer science" + ], + "college_years": [ + 2012, + 2013, + 2014, + 2015 + ], + "interested_in": [ + 1, + 2 + ], + "work_networks": [ + { + "id": "50432078", + "name": "IBM" + } + ], + "user_event": 1, + "connections": [ + { + "id": "125614587505822", + "name": "Demo Motors" + } + ], + "excluded_connections": [ + { + "id": "125614587505822", + "name": "Demo Motors" + } + ], + "friends_of_connections": [ + { + "id": "47190376042235", + "name": "Scuba Steve" + } + ], + "locales": [ + "24", + "43", + "51", + "6" + ], + "broad_age": 1, + "keywords": [ + "dirtbikes" + ] + }, + "start_time": "2011-10-09T12:58:18+0000", + "end_time": "2011-11-09T12:58:18+0000", + "updated_time": "2011-09-09T12:58:18+0000" + } + ], + "count": 1, + "limit": 500, + "offset": 0, + "include_deleted": null +} \ No newline at end of file