Skip to content

Commit

Permalink
#1434 edge and error case tests for typeahead on view port
Browse files Browse the repository at this point in the history
  • Loading branch information
naleeha authored and keikeicheung committed Aug 20, 2024
1 parent c4c5a77 commit 3ed85d0
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ class ViewPortContainer(val tableContainer: TableContainer, val providerContaine

def callRpcService(vpId: String, method: String, params: Array[Any], namedParams: Map[String, Any], session: ClientSessionId)(ctx: RequestContext): ViewPortAction = {
val viewPort = this.getViewPortById(vpId)

if(viewPort == null)
throw new Exception(s"No viewport $vpId found for RPC Call for $method")

val viewPortDef = viewPort.getStructure.viewPortDef
viewPortDef.service.processViewPortRpcCall(method, params, namedParams)(ctx)
}
Expand Down
188 changes: 134 additions & 54 deletions vuu/src/test/scala/org/finos/vuu/wsapi/TypeAheadWSApiTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,85 +16,112 @@ import scala.collection.immutable.ListMap
class TypeAheadWSApiTest extends WebSocketApiTestBase {

private val tableName = "TypeaheadTest"
private val tableNameEmpty = "TypeaheadTestEmpty"
private val moduleName = "TEST"

Feature("Server web socket api") {

Scenario("Type ahead request for a column") {

Then("create viewport")
val createViewPortRequest = CreateViewPortRequest(ViewPortTable(tableName, moduleName), ViewPortRange(1, 100), columns = Array("Id", "Name", "Account"))
vuuClient.send(sessionId, tokenId, createViewPortRequest)
val viewPortCreateResponse = vuuClient.awaitForMsgWithBody[CreateViewPortSuccess]
val viewPortId = viewPortCreateResponse.get.viewPortId

//todo how to change the table data
//1. get access to provider and update directly - via adding new function to get provider from TableDefs in TableDefContainer?
//2. update the data source but have listener function to update the provider if data source change?
//3. only change when loading table for first time

val getTypeAheadRequest = ViewPortRpcCall(
viewPortId,
RpcNames.UniqueFieldValuesRpc,
params = Array(),
namedParams = Map(
"table" -> tableName,
"module" -> moduleName,
"column" -> "Account"
))
Given("a view port exist")
val viewPortId: String = createViewPort

When("request typeahead for Account column")
val getTypeAheadRequest = createTypeAheadRequest(viewPortId, tableName, "Account")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return top 10 unique values in that column")
val response = vuuClient.awaitForMsgWithBody[ViewPortRpcResponse]
assert(response.isDefined)

response.isDefined shouldBe true
response.get.method shouldEqual "getUniqueFieldValues"

val action = response.get.action
action shouldBe a[DisplayResultAction]
val displayResultAction = action.asInstanceOf[DisplayResultAction]
displayResultAction.result shouldEqual List("12355", "45321", "89564", "42262", "65879", "88875", "45897", "23564", "33657", "99854")
assertResponseReturns(response, List("12355", "45321", "89564", "42262", "65879", "88875", "45897", "23564", "33657", "99854"))
}

Scenario("Type ahead request that start with a string for a column") {

Then("create viewport")
val createViewPortRequest = CreateViewPortRequest(ViewPortTable(tableName, moduleName), ViewPortRange(1, 100), columns = Array("Id", "Name", "Account"))
vuuClient.send(sessionId, tokenId, createViewPortRequest)
val viewPortCreateResponse = vuuClient.awaitForMsgWithBody[CreateViewPortSuccess]
val viewPortId = viewPortCreateResponse.get.viewPortId

val getTypeAheadRequest = ViewPortRpcCall(
viewPortId,
RpcNames.UniqueFieldValuesStartWithRpc,
params = Array(),
namedParams = Map(
"table" -> tableName,
"module" -> moduleName,
"column" -> "Name",
"starts" -> "Tom"
))
Given("a view port exist")
val viewPortId: String = createViewPort

When("request typeahead for Name column with start string Tom")
val getTypeAheadRequest = createTypeAheadStartWithRequest(viewPortId,tableName, "Name", "Tom")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return top 10 values in that column")
Then("return all Name values that start with Tom")
val response = vuuClient.awaitForMsgWithBody[ViewPortRpcResponse]
assert(response.isDefined)

response.isDefined shouldBe true
response.get.method shouldEqual "getUniqueFieldValuesStartingWith"
assertResponseReturns(response, List("Tom Sawyer", "Tom Thatcher"))
}

Scenario("Type ahead request with start with no matching value") {

Given("a view port exist")
val viewPortId: String = createViewPort

val action = response.get.action
action shouldBe a[DisplayResultAction]
val displayResultAction = action.asInstanceOf[DisplayResultAction]
displayResultAction.result shouldEqual List("Tom Sawyer", "Tom Thatcher")
When("request typeahead for Name column with start string NoMatching")
val getTypeAheadRequest = createTypeAheadStartWithRequest(viewPortId, tableName, "Name", "NoMatch")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return success response with empty list")
val response = vuuClient.awaitForMsgWithBody[ViewPortRpcResponse]

response.isDefined shouldBe true
response.get.method shouldEqual "getUniqueFieldValuesStartingWith"
assertResponseReturns(response, List.empty)
}

Scenario("Type ahead request for a column that does not exist") {

Given("a view port exist")
val viewPortId: String = createViewPort

When("request typeahead for column that does not exist")
val getTypeAheadRequest = createTypeAheadRequest(viewPortId, tableName, "ColumnThatDoesNotExist")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return success response with empty list")
val response = vuuClient.awaitForMsgWithBody[ViewPortRpcResponse]

response.isDefined shouldBe true
response.get.method shouldEqual "getUniqueFieldValues"
assertResponseReturns(response, List.empty)
}

Scenario("Type ahead request for a view port that does not exist") {

When("request typeahead for column that does not exist")
val getTypeAheadRequest = createTypeAheadRequest("viewPortThatDoesNotExist", tableName, "Account")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return helpful error response")
val response = vuuClient.awaitForMsgWithBody[ViewPortMenuRpcReject]

response.isDefined shouldBe true
response.get.rpcName shouldEqual "getUniqueFieldValues"
response.get.error shouldEqual "No viewport viewPortThatDoesNotExist found for RPC Call for getUniqueFieldValues"
}

//create multiple view ports
// check type ahead work on view port columns rather than table columns
Scenario("Type ahead request for view port that does not exist") {}
Scenario("Type ahead request for column that does not exist") {}
Scenario("Type ahead request for empty table") {}
Scenario("Type ahead request with start with no matching value") {}
//check type ahead work on view port columns rather than table columns
//match response on request id?
Scenario("Type ahead request for empty table") {

Given("a view port exist")
val viewPortId: String = createViewPort

When("request typeahead for column when table is empty")
val getTypeAheadRequest = createTypeAheadRequest(viewPortId, tableNameEmpty, "Account")
vuuClient.send(sessionId, tokenId, getTypeAheadRequest)

Then("return success response with empty list")
val response = vuuClient.awaitForMsgWithBody[ViewPortRpcResponse]

response.isDefined shouldBe true
response.get.method shouldEqual "getUniqueFieldValues"
assertResponseReturns(response, List.empty)
}

}

protected def defineModuleWithTestTables(): ViewServerModule = {
Expand All @@ -109,6 +136,17 @@ class TypeAheadWSApiTest extends WebSocketApiTestBase {
.build()
)

val tableDef2 = TableDef(
name = tableNameEmpty,
keyField = "Id",
columns =
new ColumnBuilder()
.addString("Id")
.addString("Name")
.addInt("Account")
.build()
)

val viewPortDefFactory = (_: DataTable, _: Provider, _: ProviderContainer, tableContainer: TableContainer) =>
ViewPortDef(
columns =
Expand Down Expand Up @@ -139,6 +177,48 @@ class TypeAheadWSApiTest extends WebSocketApiTestBase {

ModuleFactory.withNamespace(moduleName)
.addTableForTest(tableDef, viewPortDefFactory, providerFactory)
.addTableForTest(tableDef2)
.asModule()
}

private def createViewPort = {
val createViewPortRequest = CreateViewPortRequest(ViewPortTable(tableName, moduleName), ViewPortRange(1, 100), columns = Array("Id", "Name", "Account"))
vuuClient.send(sessionId, tokenId, createViewPortRequest)
val viewPortCreateResponse = vuuClient.awaitForMsgWithBody[CreateViewPortSuccess]
val viewPortId = viewPortCreateResponse.get.viewPortId
viewPortId
}

private def createTypeAheadRequest(viewPortId: String, tableName: String, columnName: String): ViewPortRpcCall = {
ViewPortRpcCall(
viewPortId,
RpcNames.UniqueFieldValuesRpc,
params = Array(),
namedParams = Map(
"table" -> tableName,
"module" -> moduleName,
"column" -> columnName
))
}

private def createTypeAheadStartWithRequest(viewPortId: String, tableName: String, columnName: String, startString: String): ViewPortRpcCall = {
ViewPortRpcCall(
viewPortId,
RpcNames.UniqueFieldValuesStartWithRpc,
params = Array(),
namedParams = Map(
"table" -> tableName,
"module" -> moduleName,
"column" -> columnName,
"starts" -> startString
))
}

private def assertResponseReturns(response: Option[ViewPortRpcResponse], expectedResult: Any) = {
val action = response.get.action
action shouldBe a[DisplayResultAction]
val displayResultAction = action.asInstanceOf[DisplayResultAction]

displayResultAction.result shouldEqual expectedResult
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import org.finos.toolbox.lifecycle.LifecycleContainer
import org.finos.toolbox.time.Clock
import org.finos.vuu.api.{TableDef, ViewPortDef}
import org.finos.vuu.core.IVuuServer
import org.finos.vuu.core.module.{ModuleFactory, ModuleFactoryNode, TableDefContainer, ViewServerModule}
import org.finos.vuu.core.module.ModuleFactoryNode
import org.finos.vuu.core.table.{DataTable, TableContainer}
import org.finos.vuu.provider.{MockProvider, Provider, ProviderContainer}
import org.finos.vuu.provider.{Provider, ProviderContainer}

import scala.collection.immutable.ListMap

object TestExtension {
implicit class ModuleFactoryExtension(val moduleFactoryNode: ModuleFactoryNode) {

def addTableForTest(tableDef: TableDef)(implicit clock: Clock, lifecycle: LifecycleContainer): ModuleFactoryNode = {
moduleFactoryNode.addTable(
tableDef,
(table, _) => new MockProvider(table)
(table, _) => new TestProvider(table, new FakeDataSource(ListMap.empty))
)
}

Expand Down

0 comments on commit 3ed85d0

Please sign in to comment.