// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 com.google.api.ads.adwords.lib.utils.testing;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.verify;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.api.ads.adwords.lib.utils.BatchJobException;
import com.google.api.ads.adwords.lib.utils.BatchJobHelperInterface;
import com.google.api.ads.adwords.lib.utils.BatchJobMutateRequestInterface;
import com.google.api.ads.adwords.lib.utils.BatchJobMutateResponseInterface;
import com.google.api.ads.adwords.lib.utils.BatchJobMutateResultInterface;
import com.google.api.ads.adwords.lib.utils.BatchJobUploadStatus;
import com.google.api.ads.adwords.lib.utils.BatchJobUploader;
import com.google.api.ads.adwords.lib.utils.logging.BatchJobLogger;
import com.google.api.ads.common.lib.utils.AdsUtilityRegistry;
import com.google.api.ads.common.lib.utils.Streams;
import com.google.common.collect.ImmutableList;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
* Base class for tests of {@link BatchJobHelperInterface} implementations.
*
* <p>
* Abstract methods allow subclasses to provide version and SOAP toolkit-specific objects for
* testing.
*/
@RunWith(JUnit4.class)
public abstract class BatchJobHelperTest<
OperationT, OperandT, ErrorT, ResultT extends BatchJobMutateResultInterface<OperandT, ErrorT>,
ResponseT extends BatchJobMutateResponseInterface<OperandT, ErrorT, ResultT>> {
@Rule public TemporaryFolder tempFolder = new TemporaryFolder();
@Mock protected AdWordsSession session;
protected AdsUtilityRegistry adsUtilityRegistry;
@Mock protected BatchJobLogger batchJobLogger;
@Mock private BatchJobUploader uploader;
private BatchJobHelperInterface<OperationT, OperandT, ErrorT, ResultT, ResponseT> batchJobHelper;
private ImmutableList<OperationT> operations;
private static final String UPLOAD_URL = "https://www.example.com/upload";
private static final Long TEST_CAMPAIGN_ID = 12345L;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
adsUtilityRegistry = AdsUtilityRegistry.getInstance();
batchJobHelper = createBatchJobHelper(uploader);
operations = ImmutableList.<OperationT>of(getPauseCampaignOperation(TEST_CAMPAIGN_ID));
}
@Test
public void testDownloadBatchJobMutateResponse() throws BatchJobException, IOException {
File tempFile = tempFolder.newFile();
OutputStream responseOutputStream = new FileOutputStream(tempFile);
Streams.write(getResponseString(), responseOutputStream, StandardCharsets.UTF_8);
ResponseT downloadResponse =
batchJobHelper.downloadBatchJobMutateResponse(tempFile.toURI().toURL().toString());
assertDownloadResponse(downloadResponse);
}
/**
* Verifies that the helper handles the case where the response does not contain any results.
*/
@Test
public void testDownloadBatchJobMutateResponse_emptyResponse()
throws BatchJobException, IOException {
String noResultsResponse = String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<mutateResponse xmlns=\"https://adwords.google.com/api/adwords/cm/%s\">"
+ "</mutateResponse>", getVersion());
File tempFile = tempFolder.newFile();
OutputStream responseOutputStream = new FileOutputStream(tempFile);
Streams.write(noResultsResponse, responseOutputStream, StandardCharsets.UTF_8);
ResponseT downloadResponse =
batchJobHelper.downloadBatchJobMutateResponse(tempFile.toURI().toURL().toString());
assertNotNull("Download response is null", downloadResponse);
if (expectNullResultsForEmptyResponse()) {
assertNull(
"Mutate results of download response should be null",
downloadResponse.getMutateResults());
} else {
assertNotNull(
"Mutate results of download response is null", downloadResponse.getMutateResults());
assertEquals(
"Size of mutate results of an empty download response != 0",
0,
downloadResponse.getMutateResults().length);
}
}
@Test
public void testUploadBatchJobOperations() throws BatchJobException {
BatchJobUploadStatus status = new BatchJobUploadStatus(0L, URI.create(UPLOAD_URL));
batchJobHelper.uploadBatchJobOperations(operations, UPLOAD_URL);
verify(uploader)
.uploadIncrementalBatchJobOperations(
Matchers.<BatchJobMutateRequestInterface>any(),
Matchers.eq(true),
Matchers.eq(status));
}
@Test
public void testUploadIncrementalBatchJobOperations() throws BatchJobException {
BatchJobUploadStatus status = new BatchJobUploadStatus(0L, URI.create(UPLOAD_URL));
batchJobHelper.uploadIncrementalBatchJobOperations(operations, false, status);
verify(uploader)
.uploadIncrementalBatchJobOperations(
Matchers.<BatchJobMutateRequestInterface>any(),
Matchers.eq(false),
Matchers.eq(status));
}
@Test
public void testUploadIncrementalBatchJobOperations_isLastRequest() throws BatchJobException {
BatchJobUploadStatus status = new BatchJobUploadStatus(0L, URI.create(UPLOAD_URL));
batchJobHelper.uploadIncrementalBatchJobOperations(operations, true, status);
verify(uploader)
.uploadIncrementalBatchJobOperations(
Matchers.<BatchJobMutateRequestInterface>any(), Matchers.eq(true), Matchers.eq(status));
}
/**
* Returns the {@link BatchJobHelperInterface} for this test's version and SOAP toolkit.
*/
protected abstract BatchJobHelperInterface<OperationT, OperandT, ErrorT, ResultT, ResponseT>
createBatchJobHelper(BatchJobUploader uploader);
/**
* Returns a {@code CampaignOperation} that sets the status to {@code PAUSED} for the campaign
* with the specified {@code campaignId}.
*/
protected abstract OperationT getPauseCampaignOperation(Long campaignId);
/**
* Subclasses should override to confirm that the response contains the deserialized entries from
* {@link #getResponseString()}.
*/
protected abstract void assertDownloadResponse(ResponseT downloadResponse);
/**
* Returns if the framework is expected to return a response with a {@code null}
* {@code ResultT} collection if the XML does not contain any result elements.
*/
protected abstract boolean expectNullResultsForEmptyResponse();
/**
* Returns the AdWords API version being tested.
*/
protected abstract String getVersion();
/**
* Returns the test download response string after substituting the API version and test campaign
* ID.
*/
private String getResponseString() {
return String.format(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<mutateResponse xmlns=\"https://adwords.google.com/api/adwords/cm/%s\">"
+ " <rval>"
+ " <result>"
+ " <Campaign>"
+ " <id>%d</id>"
+ " <status>PAUSED</status>"
+ " </Campaign>"
+ " </result>"
+ " </rval>"
+ "</mutateResponse>",
getVersion(),
TEST_CAMPAIGN_ID);
}
}