Skip to content

Commit f8d2929

Browse files
committed
Add test: PrivateViewsUserCanAccessTest
1 parent 7009a3f commit f8d2929

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package code.views
2+
3+
import code.api.Constant
4+
import code.api.Constant.ALL_CONSUMERS
5+
import code.setup.{DefaultUsers, ServerSetup}
6+
import code.views.system.{AccountAccess, ViewDefinition}
7+
import com.openbankproject.commons.model.{AccountId, BankId, BankIdAccountId}
8+
import net.liftweb.common.Full
9+
10+
class PrivateViewsUserCanAccessTest extends ServerSetup with DefaultUsers {
11+
12+
override def beforeAll(): Unit = {
13+
super.beforeAll()
14+
}
15+
16+
override def afterEach(): Unit = {
17+
super.afterEach()
18+
AccountAccess.bulkDelete_!!()
19+
ViewDefinition.bulkDelete_!!()
20+
}
21+
22+
val bankId1 = BankId("test-bank-1")
23+
val bankId2 = BankId("test-bank-2")
24+
val accountId1 = AccountId("test-account-1")
25+
val accountId2 = AccountId("test-account-2")
26+
val accountId3 = AccountId("test-account-3")
27+
28+
private def createSystemViewAndGrantAccess(bankId: BankId, accountId: AccountId, viewId: String, user: code.model.dataAccess.ResourceUser): Unit = {
29+
// Ensure the system view exists
30+
MapperViews.getOrCreateSystemViewFromCbs(viewId)
31+
// Grant access
32+
val view = ViewDefinition.findSystemView(viewId).openOrThrowException(s"System view $viewId not found")
33+
MapperViews.grantAccessToSystemView(bankId, accountId, view, user)
34+
}
35+
36+
feature("privateViewsUserCanAccess") {
37+
38+
scenario("User with no account access returns empty lists") {
39+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
40+
views should be(empty)
41+
accountAccess should be(empty)
42+
}
43+
44+
scenario("User with one system view access returns that view") {
45+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
46+
47+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
48+
views.size should be(1)
49+
accountAccess.size should be(1)
50+
views.head.viewId.value should equal(Constant.SYSTEM_OWNER_VIEW_ID.toLowerCase())
51+
accountAccess.head.bank_id.get should equal(bankId1.value)
52+
accountAccess.head.account_id.get should equal(accountId1.value)
53+
}
54+
55+
scenario("User with access to multiple accounts returns all views") {
56+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
57+
createSystemViewAndGrantAccess(bankId1, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
58+
createSystemViewAndGrantAccess(bankId2, accountId3, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
59+
60+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
61+
accountAccess.size should be(3)
62+
// All three account access records should be for the owner view
63+
accountAccess.map(_.view_id.get).distinct should equal(List(Constant.SYSTEM_OWNER_VIEW_ID.toLowerCase()))
64+
// Check all bank/account combinations are present
65+
val bankAccountPairs = accountAccess.map(a => (a.bank_id.get, a.account_id.get)).toSet
66+
bankAccountPairs should contain((bankId1.value, accountId1.value))
67+
bankAccountPairs should contain((bankId1.value, accountId2.value))
68+
bankAccountPairs should contain((bankId2.value, accountId3.value))
69+
}
70+
71+
scenario("User with multiple view types on the same account") {
72+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
73+
createSystemViewAndGrantAccess(bankId1, accountId1, "accountant", resourceUser1)
74+
75+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
76+
accountAccess.size should be(2)
77+
views.map(_.viewId.value).toSet should contain(Constant.SYSTEM_OWNER_VIEW_ID.toLowerCase())
78+
views.map(_.viewId.value).toSet should contain("accountant")
79+
}
80+
81+
scenario("Different users have independent access") {
82+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
83+
createSystemViewAndGrantAccess(bankId1, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser2)
84+
85+
val (views1, access1) = MapperViews.privateViewsUserCanAccess(resourceUser1)
86+
val (views2, access2) = MapperViews.privateViewsUserCanAccess(resourceUser2)
87+
88+
access1.size should be(1)
89+
access1.head.account_id.get should equal(accountId1.value)
90+
91+
access2.size should be(1)
92+
access2.head.account_id.get should equal(accountId2.value)
93+
}
94+
95+
scenario("Views are distinct even when user has access to same view type across accounts") {
96+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
97+
createSystemViewAndGrantAccess(bankId1, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
98+
99+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
100+
accountAccess.size should be(2)
101+
// The underlying ViewDefinition for system views is the same, so distinct views should be
102+
// based on the view definition, but with bank_id/account_id set per account access
103+
views.size should be >= 1
104+
}
105+
106+
scenario("Returned accountAccess entries match returned views") {
107+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
108+
createSystemViewAndGrantAccess(bankId1, accountId1, "accountant", resourceUser1)
109+
createSystemViewAndGrantAccess(bankId2, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
110+
111+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccess(resourceUser1)
112+
accountAccess.size should be(3)
113+
114+
// Every accountAccess view_id should correspond to a returned view
115+
val viewIds = views.map(_.viewId.value).toSet
116+
accountAccess.foreach { aa =>
117+
viewIds should contain(aa.view_id.get)
118+
}
119+
}
120+
}
121+
122+
feature("privateViewsUserCanAccessAtBank") {
123+
124+
scenario("Filters to only the requested bank") {
125+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
126+
createSystemViewAndGrantAccess(bankId2, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
127+
128+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccessAtBank(resourceUser1, bankId1)
129+
accountAccess.size should be(1)
130+
accountAccess.head.bank_id.get should equal(bankId1.value)
131+
}
132+
133+
scenario("Returns empty for bank with no access") {
134+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
135+
136+
val (views, accountAccess) = MapperViews.privateViewsUserCanAccessAtBank(resourceUser1, bankId2)
137+
views should be(empty)
138+
accountAccess should be(empty)
139+
}
140+
}
141+
142+
feature("privateViewsUserCanAccessForAccount") {
143+
144+
scenario("Returns views for the specific account only") {
145+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
146+
createSystemViewAndGrantAccess(bankId1, accountId1, "accountant", resourceUser1)
147+
createSystemViewAndGrantAccess(bankId1, accountId2, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
148+
149+
val views = MapperViews.privateViewsUserCanAccessForAccount(resourceUser1, BankIdAccountId(bankId1, accountId1))
150+
views.size should be(2)
151+
views.map(_.viewId.value).toSet should equal(Set(Constant.SYSTEM_OWNER_VIEW_ID.toLowerCase(), "accountant"))
152+
}
153+
154+
scenario("Returns empty for account with no access") {
155+
createSystemViewAndGrantAccess(bankId1, accountId1, Constant.SYSTEM_OWNER_VIEW_ID, resourceUser1)
156+
157+
val views = MapperViews.privateViewsUserCanAccessForAccount(resourceUser1, BankIdAccountId(bankId1, accountId2))
158+
views should be(empty)
159+
}
160+
}
161+
}

0 commit comments

Comments
 (0)