|
16 | 16 |
|
17 | 17 | package za.co.absa.statusboard.notification.deciders |
18 | 18 |
|
19 | | -import za.co.absa.statusboard.model.NotificationCondition |
| 19 | +import org.mockito.Mockito.{mock, reset, when} |
| 20 | +import za.co.absa.statusboard.model.AppError.DatabaseError.RecordNotFoundDatabaseError |
| 21 | +import za.co.absa.statusboard.model.{NotificationCondition, RefinedStatus} |
20 | 22 | import za.co.absa.statusboard.model.RawStatus.{Green, Red} |
| 23 | +import za.co.absa.statusboard.repository.StatusRepository |
21 | 24 | import za.co.absa.statusboard.testUtils.{ConfigProviderSpec, TestData} |
22 | 25 | import zio.test.Assertion.equalTo |
23 | | -import zio.test.{Spec, TestEnvironment, assertZIO} |
24 | | -import zio.Scope |
| 26 | +import zio.test.{Spec, TestAspect, TestEnvironment, assert} |
| 27 | +import zio.{Scope, Task, ZIO, ZLayer} |
25 | 28 |
|
26 | 29 | import java.time.Duration |
27 | 30 |
|
28 | 31 | object DurationBasedNotificationDeciderImplUnitTests extends ConfigProviderSpec { |
29 | | - private val statusNotSent10MinutesGreen = TestData.refinedStatus.copy( |
30 | | - status = Green("BAD"), |
31 | | - notificationSent = false, |
32 | | - lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(10)) |
33 | | - ) |
| 32 | + private def statusGreen(sent: Boolean, seen: Int) = TestData.refinedStatus.copy( |
| 33 | + status = Green("INFO"), |
| 34 | + notificationSent = sent, |
| 35 | + lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(seen)) |
| 36 | + ) |
34 | 37 |
|
35 | | - private val statusNotSent10Minutes = TestData.refinedStatus.copy( |
36 | | - status = Red("BAD", intermittent = false), |
37 | | - notificationSent = false, |
38 | | - lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(10)) |
| 38 | + private def statusRed(sent: Boolean, seen: Int) = TestData.refinedStatus.copy( |
| 39 | + status = Red("INFO", intermittent = false), |
| 40 | + notificationSent = sent, |
| 41 | + lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(seen)) |
39 | 42 | ) |
40 | 43 |
|
41 | | - private val statusNotSentIntermittent10Minutes = TestData.refinedStatus.copy( |
42 | | - status = Red("BAD", intermittent = true), |
43 | | - notificationSent = false, |
44 | | - lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(10)) |
| 44 | + private def statusRedInt(sent: Boolean, seen: Int) = TestData.refinedStatus.copy( |
| 45 | + status = Red("INFO", intermittent = true), |
| 46 | + notificationSent = sent, |
| 47 | + lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(seen)) |
45 | 48 | ) |
46 | 49 |
|
47 | | - private val statusYesSent10Minutes = TestData.refinedStatus.copy( |
48 | | - status = Red("BAD", intermittent = false), |
49 | | - notificationSent = true, |
50 | | - lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(10)) |
51 | | - ) |
| 50 | + private def condition(seen: Int) = NotificationCondition.DurationBased(Duration.ofMinutes(seen).toSeconds.toInt) |
52 | 51 |
|
53 | | - private val statusYesSentIntermittent10Minutes = TestData.refinedStatus.copy( |
54 | | - status = Red("BAD", intermittent = true), |
55 | | - notificationSent = true, |
56 | | - lastSeen = TestData.refinedStatus.firstSeen.plus(Duration.ofMinutes(10)) |
57 | | - ) |
| 52 | + private val repositoryMock = mock(classOf[StatusRepository]) |
58 | 53 |
|
59 | | - private val conditionDuration5Minutes = NotificationCondition.DurationBased(Duration.ofMinutes(5).toSeconds.toInt) |
| 54 | + private def setupRepoMock(lastNotifiedStatus: RefinedStatus): Task[Unit] = ZIO.attempt { |
| 55 | + reset(repositoryMock) |
| 56 | + when(repositoryMock.getLatestNotifiedStatus(TestData.refinedStatus.env, TestData.refinedStatus.serviceName)) |
| 57 | + .thenReturn(ZIO.succeed(lastNotifiedStatus)) |
| 58 | + } |
60 | 59 |
|
61 | | - private val conditionDuration30Minutes = NotificationCondition.DurationBased(Duration.ofMinutes(30).toSeconds.toInt) |
| 60 | + private def setupRepoMockEmpty(): Task[Unit] = ZIO.attempt { |
| 61 | + reset(repositoryMock) |
| 62 | + when(repositoryMock.getLatestNotifiedStatus(TestData.refinedStatus.env, TestData.refinedStatus.serviceName)) |
| 63 | + .thenReturn(ZIO.fail(RecordNotFoundDatabaseError("BAKA"))) |
| 64 | + } |
| 65 | + |
| 66 | + private def resetRepoMock(): Task[Unit] = ZIO.attempt { |
| 67 | + reset(repositoryMock) |
| 68 | + } |
62 | 69 |
|
63 | 70 | override def spec: Spec[TestEnvironment with Scope, Any] = { |
64 | 71 | suite("DurationBasedNotificationDeciderImplSuite")( |
65 | | - test("Should not request notification, when already sent regardless of being over time") { |
66 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration5Minutes, statusYesSent10Minutes))( |
67 | | - equalTo(false) |
68 | | - ) |
69 | | - }, |
70 | | - test("Should not request notification, when already sent (intermittent) regardless of being over time") { |
71 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration5Minutes, statusYesSentIntermittent10Minutes))( |
72 | | - equalTo(false) |
73 | | - ) |
| 72 | + test("Should yes request notification, when being stable (regardless of no overtime) and previously notified for different color") { |
| 73 | + for { |
| 74 | + _ <- setupRepoMock(statusGreen(sent = true, seen = 10)) |
| 75 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusRed(sent = false, seen = 5)) |
| 76 | + } yield assert(response)(equalTo(true)) |
74 | 77 | }, |
75 | | - test("Should not request notification, when already sent and not being over time") { |
76 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration30Minutes, statusYesSent10Minutes))( |
77 | | - equalTo(false) |
78 | | - ) |
| 78 | + test("Should yes request notification, when being stable (regardless of no overtime) and previously no notification at all") { |
| 79 | + for { |
| 80 | + _ <- setupRepoMockEmpty() |
| 81 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusRed(sent = false, seen = 5)) |
| 82 | + } yield assert(response)(equalTo(true)) |
79 | 83 | }, |
80 | | - test("Should not request notification, when already sent (intermittnent) and not being over time") { |
81 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration30Minutes, statusYesSentIntermittent10Minutes))( |
82 | | - equalTo(false) |
83 | | - ) |
| 84 | + test("Should yes request notification, when being intermittent, with overtime and previously notified for different color") { |
| 85 | + for { |
| 86 | + _ <- setupRepoMock(statusGreen(sent = true, seen = 10)) |
| 87 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 5), statusRedInt(sent = false, seen = 10)) |
| 88 | + } yield assert(response)(equalTo(true)) |
84 | 89 | }, |
85 | | - test("Should not request notification, when being over time but green #160") { |
86 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration5Minutes, statusNotSent10MinutesGreen))( |
87 | | - equalTo(false) |
88 | | - ) |
| 90 | + test("Should yes request notification, when being green (regardless of no overtime) and previously notified for different color (#160 negated in #5)") { |
| 91 | + for { |
| 92 | + _ <- setupRepoMock(statusRed(sent = true, seen = 10)) |
| 93 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusGreen(sent = false, seen = 5)) |
| 94 | + } yield assert(response)(equalTo(true)) |
89 | 95 | }, |
90 | | - test("Should yes request notification, when being over time") { |
91 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration5Minutes, statusNotSent10Minutes))( |
92 | | - equalTo(true) |
93 | | - ) |
| 96 | + test("Should not request notification, when already notified - also should not touch repo") { |
| 97 | + for { |
| 98 | + _ <- resetRepoMock() |
| 99 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusRed(sent = true, seen = 5)) |
| 100 | + } yield assert(response)(equalTo(false)) |
94 | 101 | }, |
95 | | - test("Should yes request notification, when being over time (intermittent)") { |
96 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration5Minutes, statusNotSentIntermittent10Minutes))( |
97 | | - equalTo(true) |
98 | | - ) |
| 102 | + test("Should not request notification, when being intermittent with no overtime - also should not touch repo") { |
| 103 | + for { |
| 104 | + _ <- resetRepoMock() |
| 105 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusRedInt(sent = false, seen = 5)) |
| 106 | + } yield assert(response)(equalTo(false)) |
99 | 107 | }, |
100 | | - test("Should yes request notification, when not being over time and NOT intermittent") { |
101 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration30Minutes, statusNotSent10Minutes))( |
102 | | - equalTo(true) |
103 | | - ) |
| 108 | + test("Should not request notification, when previously notified for same color") { |
| 109 | + for { |
| 110 | + _ <- setupRepoMock(statusRed(sent = true, seen = 10)) |
| 111 | + response <- DurationBasedNotificationDecider.shouldNotify(condition(seen = 10), statusRed(sent = false, seen = 5)) |
| 112 | + } yield assert(response)(equalTo(false)) |
104 | 113 | }, |
105 | | - test("Should not request notification, when not being over time (intermittent)") { |
106 | | - assertZIO(DurationBasedNotificationDecider.shouldNotify(conditionDuration30Minutes, statusNotSentIntermittent10Minutes))( |
107 | | - equalTo(false) |
108 | | - ) |
109 | | - } |
110 | | - ) |
111 | | - }.provide(DurationBasedNotificationDeciderImpl.layer |
| 114 | + ) @@ TestAspect.sequential |
| 115 | + }.provide( |
| 116 | + DurationBasedNotificationDeciderImpl.layer, |
| 117 | + ZLayer.succeed(repositoryMock) |
112 | 118 | ) |
113 | 119 | } |
0 commit comments