Skip to content

Commit e364bc7

Browse files
committed
add options to license expired filter
1 parent 494ef1b commit e364bc7

File tree

3 files changed

+159
-6
lines changed

3 files changed

+159
-6
lines changed

app/controllers/api/v1/licenses_controller.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ class LicensesController < Api::V1::BaseController
1818
}
1919
has_scope :suspended
2020
has_scope :expiring
21-
has_scope :expired
21+
has_scope(:expired, type: :any, only: :index) { |c, s, v|
22+
if v in Hash
23+
s.expired(**v.symbolize_keys.slice(:within, :in, :before, :after))
24+
else
25+
s.expired(v)
26+
end
27+
}
2228
has_scope :unassigned
2329
has_scope :assigned
2430
has_scope :activated

app/models/license.rb

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,34 @@ class License < ApplicationRecord
573573
where 'expiry IS NULL OR expiry < ? OR expiry > ?', Time.current, 3.days.from_now
574574
end
575575
}
576-
scope :expired, -> (status = true) {
577-
if ActiveRecord::Type::Boolean.new.cast(status)
578-
where 'expiry IS NOT NULL AND expiry < ?', Time.current
579-
else
580-
where 'expiry IS NULL OR expiry >= ?', Time.current
576+
scope :expired, -> (status = true, within: nil, in: nil, before: nil, after: nil) {
577+
within ||= binding.local_variable_get(:in)
578+
579+
begin
580+
case
581+
when within.present?
582+
s = within.to_s.match?(/\A\d+\z/) ? "PT#{within.to_s}S".upcase : "P#{within.to_s.delete_prefix('P').upcase}"
583+
d = ActiveSupport::Duration.parse(s)
584+
585+
where 'expiry IS NOT NULL AND expiry < ? AND expiry >= ?', Time.current, d.ago
586+
when before.present?
587+
t = before.to_s.match?(/\A\d+\z/) ? Time.at(before.to_i) : before.to_time
588+
589+
where 'expiry IS NOT NULL AND expiry < ? AND expiry <= ?', Time.current, t
590+
when after.present?
591+
t = after.to_s.match?(/\A\d+\z/) ? Time.at(after.to_i) : after.to_time
592+
593+
where 'expiry IS NOT NULL AND expiry < ? AND expiry >= ?', Time.current, t
594+
else
595+
if ActiveRecord::Type::Boolean.new.cast(status) # general expired/unexpired scopes
596+
where 'expiry IS NOT NULL AND expiry < ?', Time.current
597+
else
598+
where 'expiry IS NULL OR expiry >= ?', Time.current
599+
end
600+
end
601+
rescue ActiveSupport::Duration::ISO8601Parser::ParsingError,
602+
ArgumentError # to_time raises for invalid input
603+
none
581604
end
582605
}
583606
scope :expires, -> (within: nil, in: nil, before: nil, after: nil) {

features/api/v1/licenses/index.feature

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,130 @@ Feature: List license
10381038
And the response body should be an array with 0 "licenses"
10391039
And time is unfrozen
10401040

1041+
Scenario: Admin retrieves all licenses expired within the last 31 days (duration)
1042+
Given I am an admin of account "test1"
1043+
And the current account is "test1"
1044+
And the current account has 5 "licenses"
1045+
And the first "license" has the following attributes:
1046+
"""
1047+
{ "expiry": "2022-06-10T12:00:00.000Z" }
1048+
"""
1049+
And the second "license" has the following attributes:
1050+
"""
1051+
{ "expiry": null }
1052+
"""
1053+
And the third "license" has the following attributes:
1054+
"""
1055+
{ "expiry": "2022-01-10T12:00:00.000Z" }
1056+
"""
1057+
And the fourth "license" has the following attributes:
1058+
"""
1059+
{ "expiry": "2022-05-10T13:00:00.000Z" }
1060+
"""
1061+
And the fifth "license" has the following attributes:
1062+
"""
1063+
{ "expiry": "2022-08-01T12:00:00.000Z" }
1064+
"""
1065+
And time is frozen at "2022-06-10T13:00:00.000Z"
1066+
And I use an authentication token
1067+
When I send a GET request to "/accounts/test1/licenses?expired[within]=31d"
1068+
Then the response status should be "200"
1069+
And the response body should be an array with 2 "licenses"
1070+
And time is unfrozen
1071+
1072+
Scenario: Admin retrieves all licenses expired in the last 31 days (duration)
1073+
Given I am an admin of account "test1"
1074+
And the current account is "test1"
1075+
And the current account has 5 "licenses"
1076+
And the first "license" has the following attributes:
1077+
"""
1078+
{ "expiry": "2022-06-10T12:00:00.000Z" }
1079+
"""
1080+
And the second "license" has the following attributes:
1081+
"""
1082+
{ "expiry": null }
1083+
"""
1084+
And the third "license" has the following attributes:
1085+
"""
1086+
{ "expiry": "2022-01-10T12:00:00.000Z" }
1087+
"""
1088+
And the fourth "license" has the following attributes:
1089+
"""
1090+
{ "expiry": "2022-05-10T13:00:00.000Z" }
1091+
"""
1092+
And the fifth "license" has the following attributes:
1093+
"""
1094+
{ "expiry": "2022-08-01T12:00:00.000Z" }
1095+
"""
1096+
And time is frozen at "2022-06-10T13:00:00.000Z"
1097+
And I use an authentication token
1098+
When I send a GET request to "/accounts/test1/licenses?expired[in]=31d"
1099+
Then the response status should be "200"
1100+
And the response body should be an array with 2 "licenses"
1101+
And time is unfrozen
1102+
1103+
Scenario: Admin retrieves all licenses expired before a timestamp (ISO)
1104+
Given I am an admin of account "test1"
1105+
And the current account is "test1"
1106+
And the current account has 5 "licenses"
1107+
And the first "license" has the following attributes:
1108+
"""
1109+
{ "expiry": "2022-06-10T12:00:00.000Z" }
1110+
"""
1111+
And the second "license" has the following attributes:
1112+
"""
1113+
{ "expiry": null }
1114+
"""
1115+
And the third "license" has the following attributes:
1116+
"""
1117+
{ "expiry": "2022-01-10T12:00:00.000Z" }
1118+
"""
1119+
And the fourth "license" has the following attributes:
1120+
"""
1121+
{ "expiry": "2022-05-10T13:00:00.000Z" }
1122+
"""
1123+
And the fifth "license" has the following attributes:
1124+
"""
1125+
{ "expiry": "2022-08-01T12:00:00.000Z" }
1126+
"""
1127+
And time is frozen at "2022-06-10T13:00:00.000Z"
1128+
And I use an authentication token
1129+
When I send a GET request to "/accounts/test1/licenses?expired[before]=2022-05-10T13:00:01.000Z"
1130+
Then the response status should be "200"
1131+
And the response body should be an array with 2 "licenses"
1132+
And time is unfrozen
1133+
1134+
Scenario: Admin retrieves all licenses expired after a timestamp (unix)
1135+
Given I am an admin of account "test1"
1136+
And the current account is "test1"
1137+
And the current account has 5 "licenses"
1138+
And the first "license" has the following attributes:
1139+
"""
1140+
{ "expiry": "2022-06-10T12:00:00.000Z" }
1141+
"""
1142+
And the second "license" has the following attributes:
1143+
"""
1144+
{ "expiry": null }
1145+
"""
1146+
And the third "license" has the following attributes:
1147+
"""
1148+
{ "expiry": "2022-01-10T12:00:00.000Z" }
1149+
"""
1150+
And the fourth "license" has the following attributes:
1151+
"""
1152+
{ "expiry": "2022-05-10T13:00:00.000Z" }
1153+
"""
1154+
And the fifth "license" has the following attributes:
1155+
"""
1156+
{ "expiry": "2022-08-01T12:00:00.000Z" }
1157+
"""
1158+
And time is frozen at "2022-06-10T13:00:00.000Z"
1159+
And I use an authentication token
1160+
When I send a GET request to "/accounts/test1/licenses?expired[after]=1652313600"
1161+
Then the response status should be "200"
1162+
And the response body should be an array with 1 "license"
1163+
And time is unfrozen
1164+
10411165
Scenario: Admin retrieves licenses with activity inside the last 30 days (simple ISO)
10421166
Given I am an admin of account "test1"
10431167
And the current account is "test1"

0 commit comments

Comments
 (0)