Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit tests for optimize extension #105

Open
wants to merge 2 commits into
base: dev-v3.2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1024,4 +1024,14 @@ void setUpdateRequestEventIdsInProgress(
void setEventsDispatcher(final SerialWorkDispatcher<Event> eventsDispatcher) {
this.eventsDispatcher = eventsDispatcher;
}

@VisibleForTesting
Map<String, AEPOptimizeError> getUpdateRequestEventIdsErrors() {
return updateRequestEventIdsErrors;
}

@VisibleForTesting
void clearUpdateRequestEventIdsErrors() {
updateRequestEventIdsErrors.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class AEPOptimizeErrorTest {
)
assertEquals(reportData, eventData[AEPOptimizeError.REPORT])
assertNotNull(eventData[AEPOptimizeError.ADOBE_ERROR])

val adobeErrorData = eventData[AEPOptimizeError.ADOBE_ERROR]
val errorMap = adobeErrorData as? Map<String, Any>
assertNotNull(errorMap)
val errorName = errorMap?.get("errorName") as? String
assertEquals(AdobeError.UNEXPECTED_ERROR.errorName, errorName)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,129 @@ public void testHandleEdgeErrorResponse() throws Exception {

Assert.assertEquals(0, extension.getPropositionsInProgress().size());
Assert.assertEquals(0, extension.getCachedPropositions().size());
extension.clearUpdateRequestEventIdsErrors();
}
}

@Test
public void testHandleEdgeErrorResponse_nonRecoverableError() throws Exception {
try (MockedStatic<Log> logMockedStatic = Mockito.mockStatic(Log.class)) {
// setup
final Map<String, Object> edgeErrorResponseData =
new ObjectMapper()
.readValue(
getClass()
.getClassLoader()
.getResource(
"json/EVENT_DATA_EDGE_ERROR_RESPONSE.json"),
HashMap.class);

extension.setUpdateRequestEventIdsInProgress(
"AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA",
new ArrayList<DecisionScope>() {
{
add(
new DecisionScope(
"eydhY3Rpdml0eUlkIjoieGNvcmU6b2ZmZXItYWN0aXZpdHk6MTExMTExMTExMTExMTExMSIsInBsYWNlbWVudElkIjoieGNvcmU6b2ZmZXItcGxhY2VtZW50OjExMTExMTExMTExMTExMTEifQ=="));
}
});

final Event testEvent =
new Event.Builder(
"AEP Error Response",
"com.adobe.eventType.edge",
"com.adobe.eventSource.errorResponseContent")
.setEventData(edgeErrorResponseData)
.build();

// test
extension.handleEdgeErrorResponse(testEvent);

// verify
logMockedStatic.verify(
() ->
Log.warning(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.any()));

Assert.assertEquals(0, extension.getPropositionsInProgress().size());
Assert.assertEquals(0, extension.getCachedPropositions().size());
Assert.assertEquals(1, extension.getUpdateRequestEventIdsErrors().size());

// validate AEPOptimizeError is created correctly

Map.Entry<String, AEPOptimizeError> firstEntry =
extension.getUpdateRequestEventIdsErrors().entrySet().iterator().next();
AEPOptimizeError aepOptimizeError = firstEntry.getValue();

Assert.assertEquals(
"https://ns.adobe.com/aep/errors/ODE-0001-404", aepOptimizeError.getType());
Assert.assertEquals(
"The following scope was not found:"
+ " xcore:offer-activity:1111111111111111/xcore:offer-placement:1111111111111111",
aepOptimizeError.getDetail());
Assert.assertEquals("Not Found", aepOptimizeError.getTitle());
extension.clearUpdateRequestEventIdsErrors();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can we move extension.clearUpdateRequestEventIdsErrors(); to the @After block so it is not repeated in every single test?

}
}

@Test
public void testHandleEdgeErrorResponse_recoverableError() throws Exception {
try (MockedStatic<Log> logMockedStatic = Mockito.mockStatic(Log.class)) {
// setup
final Map<String, Object> edgeErrorResponseData =
new ObjectMapper()
.readValue(
getClass()
.getClassLoader()
.getResource(
"json/EVENT_DATA_EDGE_ERROR_RESPONSE_RECOVERABLE_ERROR.json"),
HashMap.class);

extension.setUpdateRequestEventIdsInProgress(
"AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA",
new ArrayList<DecisionScope>() {
{
add(
new DecisionScope(
"eydhY3Rpdml0eUlkIjoieGNvcmU6b2ZmZXItYWN0aXZpdHk6MTExMTExMTExMTExMTExMSIsInBsYWNlbWVudElkIjoieGNvcmU6b2ZmZXItcGxhY2VtZW50OjExMTExMTExMTExMTExMTEifQ=="));
}
});

final Event testEvent =
new Event.Builder(
"AEP Error Response",
"com.adobe.eventType.edge",
"com.adobe.eventSource.errorResponseContent")
.setEventData(edgeErrorResponseData)
.build();

// test
extension.handleEdgeErrorResponse(testEvent);

// verify
logMockedStatic.verify(
() ->
Log.warning(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.any()));

Assert.assertEquals(0, extension.getPropositionsInProgress().size());
Assert.assertEquals(0, extension.getCachedPropositions().size());
Assert.assertEquals(0, extension.getUpdateRequestEventIdsErrors().size());

logMockedStatic.verify(
() ->
Log.debug(
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.anyString(),
ArgumentMatchers.eq(502)));
extension.clearUpdateRequestEventIdsErrors();
}
}

Expand Down Expand Up @@ -1333,6 +1456,8 @@ public void testHandleEdgeErrorResponse_nullEventData() {
extension.getCachedPropositions();
Assert.assertNotNull(cachedPropositions);
Assert.assertTrue(cachedPropositions.isEmpty());
Assert.assertEquals(0, extension.getUpdateRequestEventIdsErrors().size());
extension.clearUpdateRequestEventIdsErrors();
}
}

Expand Down Expand Up @@ -1362,6 +1487,8 @@ public void testHandleEdgeErrorResponse_emptyEventData() {

Assert.assertEquals(0, extension.getPropositionsInProgress().size());
Assert.assertEquals(0, extension.getCachedPropositions().size());
Assert.assertEquals(0, extension.getUpdateRequestEventIdsErrors().size());
extension.clearUpdateRequestEventIdsErrors();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"requestId": "BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBBA",
"detail": "Bad Gateway",
"status": 502,
"requestEventId": "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA",
"type": "https://ns.adobe.com/aep/errors/ODE-0001-502",
"title": "Bad Gateway"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package com.adobe.marketing.optimizeapp

import android.view.ViewGroup
import android.webkit.WebView
import android.widget.Toast
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -25,11 +26,13 @@ import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -57,6 +60,7 @@ private val displayHandler: (Offer) -> Unit = { offer ->

@Composable
fun OffersView(viewModel: MainViewModel) {
val context = LocalContext.current
var listState = rememberLazyListState()
Column(
modifier = Modifier
Expand Down Expand Up @@ -108,6 +112,9 @@ fun OffersView(viewModel: MainViewModel) {
JSONOffers(offers = viewModel.optimizePropositionStateMap[viewModel.jsonDecisionScope?.name]?.offers, listState = listState)
}
viewModel.targetMboxDecisionScope?.name -> {
val updatePropositionsErrorMsg = viewModel.optimizeErrors.collectAsState().value
Toast.makeText(context, updatePropositionsErrorMsg, Toast.LENGTH_LONG).show()

OffersSectionText(sectionName = "Target Offers")
TargetOffersView(offers = viewModel.optimizePropositionStateMap[viewModel.targetMboxDecisionScope?.name]?.offers, listState = listState)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.adobe.marketing.mobile.optimize.DecisionScope
import com.adobe.marketing.mobile.optimize.Optimize
import com.adobe.marketing.mobile.optimize.OptimizeProposition
import com.adobe.marketing.optimizeapp.models.OptimizePair
import kotlinx.coroutines.flow.MutableStateFlow

class MainViewModel: ViewModel() {

Expand All @@ -44,6 +45,8 @@ class MainViewModel: ViewModel() {

var optimizePropositionStateMap = mutableStateMapOf<String, OptimizeProposition>()

var optimizeErrors = MutableStateFlow("")

private val optimizePropositionUpdateCallback = object : AdobeCallbackWithError<Map<DecisionScope, OptimizeProposition>> {
override fun call(propositions: Map<DecisionScope, OptimizeProposition>?) {
propositions?.forEach {
Expand Down Expand Up @@ -99,11 +102,16 @@ class MainViewModel: ViewModel() {
optimizePropositionStateMap.clear()
Optimize.updatePropositions(decisionScopes, xdm, data, object: AdobeCallbackWithOptimizeError<Map<DecisionScope, OptimizeProposition>>{
override fun call(propositions: Map<DecisionScope, OptimizeProposition>?) {
Log.i("Optimize Test App","Propositions updated successfully.")
propositions?.let {
Log.i("Optimize Test App","Propositions updated successfully.")
} ?: run {
Log.i("Optimize Test App","No propositions provided.")
}
}

override fun fail(error: AEPOptimizeError?) {
Log.i("Optimize Test App","Error in updating Propositions:: ${error?.title ?: "Undefined"}.")
Log.i("Optimize Test App","Error in updating Propositions:: Status: ${error?.status ?: "Undefined"}, Title: ${error?.title ?: "Undefined"}.")
optimizeErrors.value = "Error in updating Propositions:: ${error?.status ?: "Undefined"}."
}

})
Expand Down