nexus_mods 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a25aa2568a5be1e1a8592196344fde1ca68bcf814b67a51cf6921f7ed64c0f70
4
- data.tar.gz: cdb50c9b1394af620109ea82439a3254b96ad223286ae1f797fcbc37c32a1a58
3
+ metadata.gz: a55e8c7bacc06ef260c5b4e6f0ac64d3e9391e39f7d1ebb00c74c110a6eae214
4
+ data.tar.gz: 9647e6745975eb0c8c0fe9023a2e66936773fd9389a5d5087511e8edb3e06876
5
5
  SHA512:
6
- metadata.gz: b7f49167041ee67f3855c0a474cdba90a744660f424356943516016628f1e65f37154c7c6b596eca2b7ac2430eae4b0726db6a45d3685b750bdf7a33e8674d2e
7
- data.tar.gz: ce904391c82e93f029a41a47d3e7e391af8dac23625ac38eda01b2066ea9261ae3ff7bbea2aed23fbbba9b124846be80640bdbbf94ef98291b1b020824ec74df
6
+ metadata.gz: 29732e93998b9b8b88d66af4ebd67d37d8eaa51f8ab47b487bf0ce2aa3f81312aed8e1275e83a428e5cfa60a2330a7603a6c114f9bf8898593695b0df79603c3
7
+ data.tar.gz: 8b3542308bd2736695165a337cef28a2e8ea7e63bd7f67d55f74b4ec797edf556d92e4792e3ea7f83a3f7f56dd028b914bcfba8f713b96679687bb29ddac8a00
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # [v2.4.0](https://github.com/Muriel-Salvan/nexus_mods/compare/v2.3.0...v2.4.0) (2023-04-12 17:23:29)
2
+
3
+ ### Features
4
+
5
+ * [[Feature] Add options and methods for mod and mod_files to query for updates to check data freshness](https://github.com/Muriel-Salvan/nexus_mods/commit/72a933a6ac22faae601fbdc547cc9e0ffa8908fc)
6
+
7
+ # [v2.3.0](https://github.com/Muriel-Salvan/nexus_mods/compare/v2.2.0...v2.3.0) (2023-04-12 15:08:22)
8
+
9
+ ### Features
10
+
11
+ * [[Feature] Add a way to set cache timestamps manually](https://github.com/Muriel-Salvan/nexus_mods/commit/7e5ac1d16d1d31f4aa33ebb9a748310e4572a06f)
12
+
1
13
  # [v2.2.0](https://github.com/Muriel-Salvan/nexus_mods/compare/v2.1.0...v2.2.0) (2023-04-12 12:56:31)
2
14
 
3
15
  ### Features
@@ -76,6 +76,21 @@ class NexusMods
76
76
  str_time.nil? ? nil : Time.parse(str_time)
77
77
  end
78
78
 
79
+ # Set the timestamp of the cached data linked to a given API call.
80
+ # This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
81
+ #
82
+ # Parameters::
83
+ # * *path* (String): API path to contact (from v1/ and without .json)
84
+ # * *parameters* (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
85
+ # * *verb* (Symbol): Verb to be used (:get, :post...) [default: :get]
86
+ # * *cache_timestamp* (Time): The cache timestamp to set for this resource
87
+ def set_api_cache_timestamp(path, cache_timestamp:, parameters: {}, verb: :get)
88
+ key = ApiClient.cache_key(path, parameters:, verb:)
89
+ Cacheable.cache_adapter.context[key] = {} unless Cacheable.cache_adapter.context.key?(key)
90
+ Cacheable.cache_adapter.context[key]['invalidate_time'] = cache_timestamp.utc.strftime('%FT%T.%9NUTC')
91
+ save_api_cache
92
+ end
93
+
79
94
  # Send an HTTP request to the API and get back the HTTP response
80
95
  #
81
96
  # Parameters::
@@ -1,5 +1,5 @@
1
1
  class NexusMods
2
2
 
3
- VERSION = '2.2.0'
3
+ VERSION = '2.4.0'
4
4
 
5
5
  end
data/lib/nexus_mods.rb CHANGED
@@ -151,15 +151,28 @@ class NexusMods
151
151
  @api_client.api_cache_timestamp('games')
152
152
  end
153
153
 
154
+ # Set the cached timestamp of the list of games.
155
+ # This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
156
+ #
157
+ # Parameters::
158
+ # * *cache_timestamp* (Time): The cache timestamp to set for this resource
159
+ def set_games_cache_timestamp(cache_timestamp:)
160
+ @api_client.set_api_cache_timestamp('games', cache_timestamp:)
161
+ end
162
+
154
163
  # Get information about a mod
155
164
  #
156
165
  # Parameters::
157
166
  # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
158
167
  # * *mod_id* (Integer): The mod ID [default: @mod_id]
159
168
  # * *clear_cache* (Boolean): Should we clear the API cache for this resource? [default: false]
169
+ # * *check_updates* (Boolean): Should we check updates?
170
+ # If yes then an extra call to updated_mods may be done to check for updates before retrieving the mod information.
171
+ # In case the mod was previously retrieved and may be in an old cache, then using this will optimize the calls to NexusMods API to the minimum.
160
172
  # Result::
161
173
  # * Mod: Mod information
162
- def mod(game_domain_name: @game_domain_name, mod_id: @mod_id, clear_cache: false)
174
+ def mod(game_domain_name: @game_domain_name, mod_id: @mod_id, clear_cache: false, check_updates: false)
175
+ mod_cache_up_to_date?(game_domain_name:, mod_id:) if check_updates
163
176
  mod_json = @api_client.api("games/#{game_domain_name}/mods/#{mod_id}", clear_cache:)
164
177
  Api::Mod.new(
165
178
  uid: mod_json['uid'],
@@ -202,15 +215,30 @@ class NexusMods
202
215
  @api_client.api_cache_timestamp("games/#{game_domain_name}/mods/#{mod_id}")
203
216
  end
204
217
 
218
+ # Set the cached timestamp of a mod information.
219
+ # This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
220
+ #
221
+ # Parameters::
222
+ # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
223
+ # * *mod_id* (Integer): The mod ID [default: @mod_id]
224
+ # * *cache_timestamp* (Time): The cache timestamp to set for this resource
225
+ def set_mod_cache_timestamp(cache_timestamp:, game_domain_name: @game_domain_name, mod_id: @mod_id)
226
+ @api_client.set_api_cache_timestamp("games/#{game_domain_name}/mods/#{mod_id}", cache_timestamp:)
227
+ end
228
+
205
229
  # Get files belonging to a mod
206
230
  #
207
231
  # Parameters::
208
232
  # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
209
233
  # * *mod_id* (Integer): The mod ID [default: @mod_id]
210
234
  # * *clear_cache* (Boolean): Should we clear the API cache for this resource? [default: false]
235
+ # * *check_updates* (Boolean): Should we check updates?
236
+ # If yes then an extra call to updated_mods may be done to check for updates before retrieving the mod information.
237
+ # In case the mod files were previously retrieved and may be in an old cache, then using this will optimize the calls to NexusMods API to the minimum.
211
238
  # Result::
212
239
  # * Array<ModFile>: List of mod's files
213
- def mod_files(game_domain_name: @game_domain_name, mod_id: @mod_id, clear_cache: false)
240
+ def mod_files(game_domain_name: @game_domain_name, mod_id: @mod_id, clear_cache: false, check_updates: false)
241
+ mod_files_cache_up_to_date?(game_domain_name:, mod_id:) if check_updates
214
242
  @api_client.api("games/#{game_domain_name}/mods/#{mod_id}/files", clear_cache:)['files'].map do |file_json|
215
243
  Api::ModFile.new(
216
244
  ids: file_json['id'],
@@ -244,6 +272,17 @@ class NexusMods
244
272
  @api_client.api_cache_timestamp("games/#{game_domain_name}/mods/#{mod_id}/files")
245
273
  end
246
274
 
275
+ # Set the cached timestamp of a mod files information.
276
+ # This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
277
+ #
278
+ # Parameters::
279
+ # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
280
+ # * *mod_id* (Integer): The mod ID [default: @mod_id]
281
+ # * *cache_timestamp* (Time): The cache timestamp to set for this resource
282
+ def set_mod_files_cache_timestamp(cache_timestamp:, game_domain_name: @game_domain_name, mod_id: @mod_id)
283
+ @api_client.set_api_cache_timestamp("games/#{game_domain_name}/mods/#{mod_id}/files", cache_timestamp:)
284
+ end
285
+
247
286
  # Get a list of updated mod ids since a given time
248
287
  #
249
288
  # Parameters::
@@ -266,7 +305,7 @@ class NexusMods
266
305
  end
267
306
  end
268
307
 
269
- # Get the cached timestamp of a mod files information
308
+ # Get the cached timestamp of updated mod ids
270
309
  #
271
310
  # Parameters::
272
311
  # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
@@ -281,6 +320,95 @@ class NexusMods
281
320
  @api_client.api_cache_timestamp("games/#{game_domain_name}/mods/updated", parameters: period_to_url_params(since))
282
321
  end
283
322
 
323
+ # Set the cached timestamp of updated mod ids.
324
+ # This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
325
+ #
326
+ # Parameters::
327
+ # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
328
+ # * *since* (Symbol): The time from which we look for updated mods [default: :one_day]
329
+ # Possible values are:
330
+ # * *one_day*: Since 1 day
331
+ # * *one_week*: Since 1 week
332
+ # * *one_month*: Since 1 month
333
+ # * *cache_timestamp* (Time): The cache timestamp to set for this resource
334
+ def set_updated_mods_cache_timestamp(cache_timestamp:, game_domain_name: @game_domain_name, since: :one_day)
335
+ @api_client.set_api_cache_timestamp("games/#{game_domain_name}/mods/updated", parameters: period_to_url_params(since), cache_timestamp:)
336
+ end
337
+
338
+ # Does a given mod id have fresh information in our cache?
339
+ # This may fire queries to the updated mods API to get info from NexusMods about the latest updated mods.
340
+ # If we know the mod is up-to-date, then its mod information cache timestamp will be set to the time when we checked for updates if it was greater than the cache date.
341
+ #
342
+ # Here is the algorithm:
343
+ # If it is not in the cache, then it is not up-to-date.
344
+ # Otherwise, the API allows us to know if it has been updated up to 1 month in the past.
345
+ # Therefore if the current cache timestamp is older than 1 month, assume that it has to be updated.
346
+ # Otherwise query the API to know the latest updated mods since 1 month:
347
+ # * If the mod ID is not there, then it is up-to-date.
348
+ # * If the mod ID is there, then check if our cache timestamp is older than the last update timestamp from NexusMods.
349
+ #
350
+ # Parameters::
351
+ # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
352
+ # * *mod_id* (Integer): The mod ID [default: @mod_id]
353
+ # Result::
354
+ # * Boolean: Is the mod cache up-to-date?
355
+ def mod_cache_up_to_date?(game_domain_name: @game_domain_name, mod_id: @mod_id)
356
+ existing_cache_timestamp = mod_cache_timestamp(game_domain_name:, mod_id:)
357
+ mod_up_to_date =
358
+ if existing_cache_timestamp.nil? || existing_cache_timestamp < Time.now - (30 * 24 * 60 * 60)
359
+ # It's not in the cache
360
+ # or it's older than 1 month
361
+ false
362
+ else
363
+ found_mod_updates = updated_mods(game_domain_name:, since: :one_month).find { |mod_updates| mod_updates.mod_id == mod_id }
364
+ # true if it has not been updated on NexusMods since 1 month
365
+ # or our cache timestamp is more recent
366
+ found_mod_updates.nil? || found_mod_updates.latest_mod_activity < existing_cache_timestamp
367
+ end
368
+ if mod_up_to_date
369
+ update_time = updated_mods_cache_timestamp(game_domain_name:, since: :one_month)
370
+ set_mod_cache_timestamp(cache_timestamp: update_time, game_domain_name:, mod_id:) if update_time > existing_cache_timestamp
371
+ end
372
+ mod_up_to_date
373
+ end
374
+
375
+ # Does a given mod id have fresh files information in our cache?
376
+ # This may fire queries to the updated mods API to get info from NexusMods about the latest updated mods.
377
+ # If we know the mod is up-to-date, then its mod information cache timestamp will be set to the time when we checked for updates if it was greater than the cache date.
378
+ #
379
+ # Here is the algorithm:
380
+ # If it is not in the cache, then it is not up-to-date.
381
+ # Otherwise, the API allows us to know if it has been updated up to 1 month in the past.
382
+ # Therefore if the current cache timestamp is older than 1 month, assume that it has to be updated.
383
+ # Otherwise query the API to know the latest updated mods since 1 month:
384
+ # * If the mod ID is not there, then it is up-to-date.
385
+ # * If the mod ID is there, then check if our cache timestamp is older than the last update timestamp from NexusMods.
386
+ #
387
+ # Parameters::
388
+ # * *game_domain_name* (String): Game domain name to query by default [default: @game_domain_name]
389
+ # * *mod_id* (Integer): The mod ID [default: @mod_id]
390
+ # Result::
391
+ # * Boolean: Is the mod cache up-to-date?
392
+ def mod_files_cache_up_to_date?(game_domain_name: @game_domain_name, mod_id: @mod_id)
393
+ existing_cache_timestamp = mod_files_cache_timestamp(game_domain_name:, mod_id:)
394
+ mod_up_to_date =
395
+ if existing_cache_timestamp.nil? || existing_cache_timestamp < Time.now - (30 * 24 * 60 * 60)
396
+ # It's not in the cache
397
+ # or it's older than 1 month
398
+ false
399
+ else
400
+ found_mod_updates = updated_mods(game_domain_name:, since: :one_month).find { |mod_updates| mod_updates.mod_id == mod_id }
401
+ # true if it has not been updated on NexusMods since 1 month
402
+ # or our cache timestamp is more recent
403
+ found_mod_updates.nil? || found_mod_updates.latest_file_update < existing_cache_timestamp
404
+ end
405
+ if mod_up_to_date
406
+ update_time = updated_mods_cache_timestamp(game_domain_name:, since: :one_month)
407
+ set_mod_files_cache_timestamp(cache_timestamp: update_time, game_domain_name:, mod_id:) if update_time > existing_cache_timestamp
408
+ end
409
+ mod_up_to_date
410
+ end
411
+
284
412
  private
285
413
 
286
414
  # Get the URL parameters from the required period
@@ -25,60 +25,47 @@ describe NexusMods::Api::ModFile do
25
25
  expect_mod_file_to_be2487(sorted_mod_files[1])
26
26
  end
27
27
 
28
- it 'returns a mod files list' do
29
- expect_http_call_to(
30
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
31
- json: { files: json_example_mod_files }
32
- )
33
- expect_mod_files_to_be_example(nexus_mods.mod_files(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
34
- end
28
+ context 'when testing a mod with 2 files' do
35
29
 
36
- it 'returns the default mod files list' do
37
- expect_http_call_to(
38
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
39
- json: { files: json_example_mod_files }
40
- )
41
- expect_mod_files_to_be_example(nexus_mods(mod_id: 2014).mod_files(game_domain_name: 'skyrimspecialedition'))
42
- end
30
+ before do
31
+ expect_http_call_to(
32
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
33
+ json: { 'files' => json_example_mod_files }
34
+ )
35
+ end
43
36
 
44
- it 'returns mod files list for the default game' do
45
- expect_http_call_to(
46
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
47
- json: { files: json_example_mod_files }
48
- )
49
- expect_mod_files_to_be_example(nexus_mods(game_domain_name: 'skyrimspecialedition').mod_files(mod_id: 2014))
50
- end
37
+ it 'returns a mod files list' do
38
+ expect_mod_files_to_be_example(nexus_mods.mod_files(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
39
+ end
51
40
 
52
- it 'returns mod files list for the default game set using accessor' do
53
- expect_http_call_to(
54
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
55
- json: { files: json_example_mod_files }
56
- )
57
- nexus_mods.game_domain_name = 'skyrimspecialedition'
58
- expect_mod_files_to_be_example(nexus_mods.mod_files(mod_id: 2014))
59
- end
41
+ it 'returns the default mod files list' do
42
+ expect_mod_files_to_be_example(nexus_mods(mod_id: 2014).mod_files(game_domain_name: 'skyrimspecialedition'))
43
+ end
60
44
 
61
- it 'returns mod files list for the default game and mod' do
62
- expect_http_call_to(
63
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
64
- json: { files: json_example_mod_files }
65
- )
66
- expect_mod_files_to_be_example(nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod_files)
67
- end
45
+ it 'returns mod files list for the default game' do
46
+ expect_mod_files_to_be_example(nexus_mods(game_domain_name: 'skyrimspecialedition').mod_files(mod_id: 2014))
47
+ end
48
+
49
+ it 'returns mod files list for the default game set using accessor' do
50
+ nexus_mods.game_domain_name = 'skyrimspecialedition'
51
+ expect_mod_files_to_be_example(nexus_mods.mod_files(mod_id: 2014))
52
+ end
53
+
54
+ it 'returns mod files list for the default game and mod' do
55
+ expect_mod_files_to_be_example(nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod_files)
56
+ end
57
+
58
+ it 'returns mod files list for the default game and mod using accessor' do
59
+ nexus_mods.mod_id = 2014
60
+ expect_mod_files_to_be_example(nexus_mods.mod_files(game_domain_name: 'skyrimspecialedition'))
61
+ end
68
62
 
69
- it 'returns mod files list for the default game and mod using accessor' do
70
- expect_http_call_to(
71
- path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
72
- json: { files: json_example_mod_files }
73
- )
74
- nexus_mods.mod_id = 2014
75
- expect_mod_files_to_be_example(nexus_mods.mod_files(game_domain_name: 'skyrimspecialedition'))
76
63
  end
77
64
 
78
65
  it 'compares objects for equality' do
79
66
  expect_http_call_to(
80
67
  path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
81
- json: { files: [json_mod_file2472] }
68
+ json: { 'files' => [json_mod_file2472] }
82
69
  )
83
70
  mod_file1 = nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod_files.first
84
71
  mod_file2 = nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod_files.first
@@ -100,7 +87,7 @@ describe NexusMods::Api::ModFile do
100
87
  expect_http_call_to(
101
88
  path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
102
89
  json: {
103
- files: [
90
+ 'files' => [
104
91
  {
105
92
  'id' => [
106
93
  2472,
@@ -134,6 +121,196 @@ describe NexusMods::Api::ModFile do
134
121
  end
135
122
  end
136
123
 
124
+ context 'when checking cache data freshness' do
125
+
126
+ it 'returns that mod files never retrieved are not up-to-date' do
127
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
128
+ end
129
+
130
+ context 'when retrieving mod files previously' do
131
+
132
+ before do
133
+ expect_http_call_to(
134
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
135
+ json: { 'files' => [json_mod_file2472] }
136
+ )
137
+ nexus_mods.mod_files(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
138
+ end
139
+
140
+ context 'when retrieved 40 days ago' do
141
+
142
+ let(:forty_days_ago) { Time.now - (40 * 24 * 60 * 60) }
143
+
144
+ before do
145
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: forty_days_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
146
+ end
147
+
148
+ it 'returns that mod files are not up-to-date' do
149
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
150
+ expect(nexus_mods.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq forty_days_ago
151
+ end
152
+
153
+ end
154
+
155
+ context 'when retrieved 2 days ago' do
156
+
157
+ let(:two_days_ago) { Time.now - (2 * 24 * 60 * 60) }
158
+
159
+ before do
160
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: two_days_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
161
+ end
162
+
163
+ it 'returns that mod files are up-to-date after checking updated mods and not finding it, and updates its cache timestamp to the update time' do
164
+ expect_http_call_to(
165
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
166
+ json: []
167
+ )
168
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
169
+ expect(nexus_mods.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq(
170
+ nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)
171
+ )
172
+ end
173
+
174
+ it 'returns that mod files are up-to-date after checking updated mods and finding that cache is more recent, and updates its cache timestamp to the update time' do
175
+ expect_http_call_to(
176
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
177
+ json: [
178
+ {
179
+ 'mod_id' => 2014,
180
+ # Mock that mod was updated 3 days ago
181
+ 'latest_file_update' => Integer((Time.now - (3 * 24 * 60 * 60)).strftime('%s')),
182
+ 'latest_mod_activity' => 1
183
+ }
184
+ ]
185
+ )
186
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
187
+ expect(nexus_mods.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq(
188
+ nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)
189
+ )
190
+ end
191
+
192
+ it 'returns that mod files are not up-to-date after checking updated mods and finding that cache is less recent' do
193
+ expect_http_call_to(
194
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
195
+ json: [
196
+ {
197
+ 'mod_id' => 2014,
198
+ # Mock that mod was updated yesterday
199
+ 'latest_file_update' => Integer((Time.now - (24 * 60 * 60)).strftime('%s')),
200
+ 'latest_mod_activity' => 1
201
+ }
202
+ ]
203
+ )
204
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
205
+ expect(nexus_mods.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq two_days_ago
206
+ end
207
+
208
+ end
209
+
210
+ context 'when retrieved 3 minutes ago with an updated mods query 4 minutes ago in the cache' do
211
+
212
+ let(:three_minutes_ago) { Time.now - (3 * 60) }
213
+ let(:four_minutes_ago) { Time.now - (4 * 60) }
214
+
215
+ before do
216
+ expect_http_call_to(
217
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
218
+ json: [
219
+ {
220
+ 'mod_id' => 2014,
221
+ # Mock that mod was updated 3 days ago
222
+ 'latest_file_update' => Integer((Time.now - (3 * 24 * 60 * 60)).strftime('%s')),
223
+ 'latest_mod_activity' => 1
224
+ }
225
+ ]
226
+ )
227
+ nexus_mods.updated_mods(game_domain_name: 'skyrimspecialedition', since: :one_month)
228
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: three_minutes_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
229
+ nexus_mods.set_updated_mods_cache_timestamp(cache_timestamp: four_minutes_ago, game_domain_name: 'skyrimspecialedition', since: :one_month)
230
+ end
231
+
232
+ it 'returns that mod files are up-to-date but doesn\'t change its mod cache timestamp' do
233
+ expect(nexus_mods.mod_files_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
234
+ expect(nexus_mods.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq three_minutes_ago
235
+ expect(nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)).to eq four_minutes_ago
236
+ end
237
+
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ context 'when checking for updates' do
245
+
246
+ before do
247
+ nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
248
+ end
249
+
250
+ it 'does not check for updates if mod files have not been retrieved before' do
251
+ expect_http_call_to(
252
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
253
+ json: { 'files' => [json_mod_file2472] }
254
+ )
255
+ expect_mod_file_to_be2472(nexus_mods.mod_files(check_updates: true).first)
256
+ end
257
+
258
+ it 'does not check for updates if mod files have been retrieved more than 1 month ago, and re-query the mod' do
259
+ expect_http_call_to(
260
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
261
+ json: { 'files' => [json_mod_file2472] },
262
+ times: 2
263
+ )
264
+ nexus_mods.mod_files
265
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: Time.now - (40 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
266
+ expect_mod_file_to_be2472(nexus_mods.mod_files(check_updates: true).first)
267
+ end
268
+
269
+ it 'checks for updates when mod has been retrieved less than 1 month ago and does nothing if its date is less recent than the cache' do
270
+ expect_http_call_to(
271
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
272
+ json: { 'files' => [json_mod_file2472] }
273
+ )
274
+ expect_http_call_to(
275
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
276
+ json: [
277
+ {
278
+ 'mod_id' => 2014,
279
+ # Mock that mod was updated 25 days ago
280
+ 'latest_file_update' => Integer((Time.now - (25 * 24 * 60 * 60)).strftime('%s')),
281
+ 'latest_mod_activity' => 1
282
+ }
283
+ ]
284
+ )
285
+ nexus_mods.mod_files
286
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: Time.now - (20 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
287
+ expect_mod_file_to_be2472(nexus_mods.mod_files(check_updates: true).first)
288
+ end
289
+
290
+ it 'checks for updates when mod has been retrieved less than 1 month ago and re-query the mod if its date is more recent than the cache' do
291
+ expect_http_call_to(
292
+ path: '/v1/games/skyrimspecialedition/mods/2014/files.json',
293
+ json: { 'files' => [json_mod_file2472] },
294
+ times: 2
295
+ )
296
+ expect_http_call_to(
297
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
298
+ json: [
299
+ {
300
+ 'mod_id' => 2014,
301
+ # Mock that mod was updated 15 days ago
302
+ 'latest_file_update' => Integer((Time.now - (15 * 24 * 60 * 60)).strftime('%s')),
303
+ 'latest_mod_activity' => 1
304
+ }
305
+ ]
306
+ )
307
+ nexus_mods.mod_files
308
+ nexus_mods.set_mod_files_cache_timestamp(cache_timestamp: Time.now - (20 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
309
+ expect_mod_file_to_be2472(nexus_mods.mod_files(check_updates: true).first)
310
+ end
311
+
312
+ end
313
+
137
314
  end
138
315
 
139
316
  end
@@ -6,73 +6,253 @@ describe NexusMods::Api::Mod do
6
6
  expect_validate_user
7
7
  end
8
8
 
9
- it 'returns a mod complete information' do
10
- expect_http_call_to(
11
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
12
- json: json_complete_mod
13
- )
14
- expect_mod_to_be_complete(nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
15
- end
9
+ context 'when accessing a partial mod' do
16
10
 
17
- it 'returns a mod partial information' do
18
- expect_http_call_to(
19
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
20
- json: json_partial_mod
21
- )
22
- expect_mod_to_be_partial(nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
23
- end
11
+ before do
12
+ expect_http_call_to(
13
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
14
+ json: json_partial_mod
15
+ )
16
+ end
24
17
 
25
- it 'returns the default mod information' do
26
- expect_http_call_to(
27
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
28
- json: json_complete_mod
29
- )
30
- expect_mod_to_be_complete(nexus_mods(mod_id: 2014).mod(game_domain_name: 'skyrimspecialedition'))
31
- end
18
+ it 'returns the mod information' do
19
+ expect_mod_to_be_partial(nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
20
+ end
32
21
 
33
- it 'returns mod information for the default game' do
34
- expect_http_call_to(
35
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
36
- json: json_complete_mod
37
- )
38
- expect_mod_to_be_complete(nexus_mods(game_domain_name: 'skyrimspecialedition').mod(mod_id: 2014))
39
22
  end
40
23
 
41
- it 'returns mod information for the default game set using accessor' do
42
- expect_http_call_to(
43
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
44
- json: json_complete_mod
45
- )
46
- nexus_mods.game_domain_name = 'skyrimspecialedition'
47
- expect_mod_to_be_complete(nexus_mods.mod(mod_id: 2014))
48
- end
24
+ context 'when accessing a complete mod' do
25
+
26
+ before do
27
+ expect_http_call_to(
28
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
29
+ json: json_complete_mod
30
+ )
31
+ end
32
+
33
+ it 'returns the mod information' do
34
+ expect_mod_to_be_complete(nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014))
35
+ end
36
+
37
+ it 'returns the default mod information' do
38
+ expect_mod_to_be_complete(nexus_mods(mod_id: 2014).mod(game_domain_name: 'skyrimspecialedition'))
39
+ end
40
+
41
+ it 'returns mod information for the default game' do
42
+ expect_mod_to_be_complete(nexus_mods(game_domain_name: 'skyrimspecialedition').mod(mod_id: 2014))
43
+ end
44
+
45
+ it 'returns mod information for the default game set using accessor' do
46
+ nexus_mods.game_domain_name = 'skyrimspecialedition'
47
+ expect_mod_to_be_complete(nexus_mods.mod(mod_id: 2014))
48
+ end
49
+
50
+ it 'returns mod information for the default game and mod' do
51
+ expect_mod_to_be_complete(nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod)
52
+ end
53
+
54
+ it 'returns mod information for the default game and mod set using accessor' do
55
+ nexus_mods.mod_id = 2014
56
+ expect_mod_to_be_complete(nexus_mods.mod(game_domain_name: 'skyrimspecialedition'))
57
+ end
58
+
59
+ it 'compares objects for equality' do
60
+ mod1 = nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
61
+ mod2 = nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
62
+ expect(mod1.object_id).not_to eq mod2.object_id
63
+ expect(mod1).to eq mod2
64
+ end
49
65
 
50
- it 'returns mod information for the default game and mod' do
51
- expect_http_call_to(
52
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
53
- json: json_complete_mod
54
- )
55
- expect_mod_to_be_complete(nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014).mod)
56
66
  end
57
67
 
58
- it 'returns mod information for the default game and mod set using accessor' do
59
- expect_http_call_to(
60
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
61
- json: json_complete_mod
62
- )
63
- nexus_mods.mod_id = 2014
64
- expect_mod_to_be_complete(nexus_mods.mod(game_domain_name: 'skyrimspecialedition'))
68
+ context 'when checking cache data freshness' do
69
+
70
+ it 'returns that a mod never retrieved is not up-to-date' do
71
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
72
+ end
73
+
74
+ context 'when retrieving a mod previously' do
75
+
76
+ before do
77
+ expect_http_call_to(
78
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
79
+ json: json_complete_mod
80
+ )
81
+ nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
82
+ end
83
+
84
+ context 'when retrieved 40 days ago' do
85
+
86
+ let(:forty_days_ago) { Time.now - (40 * 24 * 60 * 60) }
87
+
88
+ before do
89
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: forty_days_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
90
+ end
91
+
92
+ it 'returns that the mod is not up-to-date' do
93
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
94
+ expect(nexus_mods.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq forty_days_ago
95
+ end
96
+
97
+ end
98
+
99
+ context 'when retrieved 2 days ago' do
100
+
101
+ let(:two_days_ago) { Time.now - (2 * 24 * 60 * 60) }
102
+
103
+ before do
104
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: two_days_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
105
+ end
106
+
107
+ it 'returns that the mod is up-to-date after checking updated mods and not finding it, and updates its cache timestamp to the update time' do
108
+ expect_http_call_to(
109
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
110
+ json: []
111
+ )
112
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
113
+ expect(nexus_mods.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq(
114
+ nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)
115
+ )
116
+ end
117
+
118
+ it 'returns that the mod is up-to-date after checking updated mods and finding that cache is more recent, and updates its cache timestamp to the update time' do
119
+ expect_http_call_to(
120
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
121
+ json: [
122
+ {
123
+ 'mod_id' => 2014,
124
+ # Mock that mod was updated 3 days ago
125
+ 'latest_file_update' => 1,
126
+ 'latest_mod_activity' => Integer((Time.now - (3 * 24 * 60 * 60)).strftime('%s'))
127
+ }
128
+ ]
129
+ )
130
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
131
+ expect(nexus_mods.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq(
132
+ nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)
133
+ )
134
+ end
135
+
136
+ it 'returns that the mod is not up-to-date after checking updated mods and finding that cache is less recent' do
137
+ expect_http_call_to(
138
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
139
+ json: [
140
+ {
141
+ 'mod_id' => 2014,
142
+ # Mock that mod was updated yesterday
143
+ 'latest_file_update' => 1,
144
+ 'latest_mod_activity' => Integer((Time.now - (24 * 60 * 60)).strftime('%s'))
145
+ }
146
+ ]
147
+ )
148
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be false
149
+ expect(nexus_mods.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq two_days_ago
150
+ end
151
+
152
+ end
153
+
154
+ context 'when retrieved 3 minutes ago with an updated mods query 4 minutes ago in the cache' do
155
+
156
+ let(:three_minutes_ago) { Time.now - (3 * 60) }
157
+ let(:four_minutes_ago) { Time.now - (4 * 60) }
158
+
159
+ before do
160
+ expect_http_call_to(
161
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
162
+ json: [
163
+ {
164
+ 'mod_id' => 2014,
165
+ # Mock that mod was updated 3 days ago
166
+ 'latest_file_update' => 1,
167
+ 'latest_mod_activity' => Integer((Time.now - (3 * 24 * 60 * 60)).strftime('%s'))
168
+ }
169
+ ]
170
+ )
171
+ nexus_mods.updated_mods(game_domain_name: 'skyrimspecialedition', since: :one_month)
172
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: three_minutes_ago, game_domain_name: 'skyrimspecialedition', mod_id: 2014)
173
+ nexus_mods.set_updated_mods_cache_timestamp(cache_timestamp: four_minutes_ago, game_domain_name: 'skyrimspecialedition', since: :one_month)
174
+ end
175
+
176
+ it 'returns that the mod is up-to-date but doesn\'t change its mod cache timestamp' do
177
+ expect(nexus_mods.mod_cache_up_to_date?(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to be true
178
+ expect(nexus_mods.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014)).to eq three_minutes_ago
179
+ expect(nexus_mods.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: :one_month)).to eq four_minutes_ago
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+
65
186
  end
66
187
 
67
- it 'compares objects for equality' do
68
- expect_http_call_to(
69
- path: '/v1/games/skyrimspecialedition/mods/2014.json',
70
- json: json_complete_mod
71
- )
72
- mod1 = nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
73
- mod2 = nexus_mods.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
74
- expect(mod1.object_id).not_to eq mod2.object_id
75
- expect(mod1).to eq mod2
188
+ context 'when checking for updates' do
189
+
190
+ before do
191
+ nexus_mods(game_domain_name: 'skyrimspecialedition', mod_id: 2014)
192
+ end
193
+
194
+ it 'does not check for updates if mod has not been retrieved before' do
195
+ expect_http_call_to(
196
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
197
+ json: json_complete_mod
198
+ )
199
+ expect_mod_to_be_complete(nexus_mods.mod(check_updates: true))
200
+ end
201
+
202
+ it 'does not check for updates if mod has been retrieved more than 1 month ago, and re-query the mod' do
203
+ expect_http_call_to(
204
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
205
+ json: json_complete_mod,
206
+ times: 2
207
+ )
208
+ nexus_mods.mod
209
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: Time.now - (40 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
210
+ expect_mod_to_be_complete(nexus_mods.mod(check_updates: true))
211
+ end
212
+
213
+ it 'checks for updates when mod has been retrieved less than 1 month ago and does nothing if its date is less recent than the cache' do
214
+ expect_http_call_to(
215
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
216
+ json: json_complete_mod
217
+ )
218
+ expect_http_call_to(
219
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
220
+ json: [
221
+ {
222
+ 'mod_id' => 2014,
223
+ # Mock that mod was updated 25 days ago
224
+ 'latest_file_update' => 1,
225
+ 'latest_mod_activity' => Integer((Time.now - (25 * 24 * 60 * 60)).strftime('%s'))
226
+ }
227
+ ]
228
+ )
229
+ nexus_mods.mod
230
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: Time.now - (20 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
231
+ expect_mod_to_be_complete(nexus_mods.mod(check_updates: true))
232
+ end
233
+
234
+ it 'checks for updates when mod has been retrieved less than 1 month ago and re-query the mod if its date is more recent than the cache' do
235
+ expect_http_call_to(
236
+ path: '/v1/games/skyrimspecialedition/mods/2014.json',
237
+ json: json_complete_mod,
238
+ times: 2
239
+ )
240
+ expect_http_call_to(
241
+ path: '/v1/games/skyrimspecialedition/mods/updated.json?period=1m',
242
+ json: [
243
+ {
244
+ 'mod_id' => 2014,
245
+ # Mock that mod was updated 15 days ago
246
+ 'latest_file_update' => 1,
247
+ 'latest_mod_activity' => Integer((Time.now - (15 * 24 * 60 * 60)).strftime('%s'))
248
+ }
249
+ ]
250
+ )
251
+ nexus_mods.mod
252
+ nexus_mods.set_mod_cache_timestamp(cache_timestamp: Time.now - (20 * 24 * 60 * 60), game_domain_name: 'skyrimspecialedition', mod_id: 2014)
253
+ expect_mod_to_be_complete(nexus_mods.mod(check_updates: true))
254
+ end
255
+
76
256
  end
77
257
 
78
258
  end
@@ -20,6 +20,7 @@ describe NexusMods do
20
20
  query: proc { |nm| nm.games },
21
21
  query_without_cache: proc { |nm| nm.games(clear_cache: true) },
22
22
  get_cache_timestamp: proc { |nm| nm.games_cache_timestamp },
23
+ set_cache_timestamp: proc { |nm, ts| nm.set_games_cache_timestamp(cache_timestamp: ts) },
23
24
  expiry_cache_param: :games
24
25
  },
25
26
  'mods' => {
@@ -28,6 +29,7 @@ describe NexusMods do
28
29
  query: proc { |nm| nm.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014) },
29
30
  query_without_cache: proc { |nm| nm.mod(game_domain_name: 'skyrimspecialedition', mod_id: 2014, clear_cache: true) },
30
31
  get_cache_timestamp: proc { |nm| nm.mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014) },
32
+ set_cache_timestamp: proc { |nm, ts| nm.set_mod_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014, cache_timestamp: ts) },
31
33
  expiry_cache_param: :mod
32
34
  },
33
35
  'mod files' => {
@@ -41,6 +43,7 @@ describe NexusMods do
41
43
  query: proc { |nm| nm.mod_files(game_domain_name: 'skyrimspecialedition', mod_id: 2014) },
42
44
  query_without_cache: proc { |nm| nm.mod_files(game_domain_name: 'skyrimspecialedition', mod_id: 2014, clear_cache: true) },
43
45
  get_cache_timestamp: proc { |nm| nm.mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014) },
46
+ set_cache_timestamp: proc { |nm, ts| nm.set_mod_files_cache_timestamp(game_domain_name: 'skyrimspecialedition', mod_id: 2014, cache_timestamp: ts) },
44
47
  expiry_cache_param: :mod_files
45
48
  }
46
49
  }.merge(
@@ -68,7 +71,8 @@ describe NexusMods do
68
71
  ],
69
72
  query: proc { |nm| nm.updated_mods(game_domain_name: 'skyrimspecialedition', since: since_config[:since]) },
70
73
  query_without_cache: proc { |nm| nm.updated_mods(game_domain_name: 'skyrimspecialedition', since: since_config[:since], clear_cache: true) },
71
- get_cache_timestamp: proc { |nm| nm.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: since_config[:since]) }
74
+ get_cache_timestamp: proc { |nm| nm.updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: since_config[:since]) },
75
+ set_cache_timestamp: proc { |nm, ts| nm.set_updated_mods_cache_timestamp(game_domain_name: 'skyrimspecialedition', since: since_config[:since], cache_timestamp: ts) }
72
76
  }
73
77
  ]
74
78
  end
@@ -131,6 +135,18 @@ describe NexusMods do
131
135
  expect(resource_config[:get_cache_timestamp].call(nexus_mods)).to be_between(before, after)
132
136
  end
133
137
 
138
+ it 'changes manually the timestamp of the data stored in the API cache' do
139
+ expect_validate_user
140
+ expect_http_call_to(
141
+ path: resource_config[:expected_api_path],
142
+ json: resource_config[:mocked_api_json]
143
+ )
144
+ resource_config[:query].call(nexus_mods)
145
+ new_cache_timestamp = Time.parse('2023-01-12 11:22:33 UTC')
146
+ resource_config[:set_cache_timestamp].call(nexus_mods, new_cache_timestamp)
147
+ expect(resource_config[:get_cache_timestamp].call(nexus_mods)).to eq new_cache_timestamp
148
+ end
149
+
134
150
  it 'retrieves the timestamp of the games data stored in the cache even after cache is used' do
135
151
  expect_validate_user
136
152
  expect_http_call_to(
@@ -159,7 +175,22 @@ describe NexusMods do
159
175
  end
160
176
  end
161
177
 
162
- it 'updates the timestamp of the data stored in the API cache' do
178
+ it 'persists the cache timestamp that has been changed manually' do
179
+ with_api_cache_file do |api_cache_file|
180
+ expect_validate_user(times: 2)
181
+ expect_http_call_to(
182
+ path: resource_config[:expected_api_path],
183
+ json: resource_config[:mocked_api_json]
184
+ )
185
+ resource_config[:query].call(nexus_mods(api_cache_file:))
186
+ new_cache_timestamp = Time.parse('2023-01-12 11:22:33 UTC')
187
+ resource_config[:set_cache_timestamp].call(nexus_mods, new_cache_timestamp)
188
+ reset_nexus_mods
189
+ expect(resource_config[:get_cache_timestamp].call(nexus_mods(api_cache_file:))).to eq new_cache_timestamp
190
+ end
191
+ end
192
+
193
+ it 'updates the timestamp of the data stored in the API cache by forcing an API query' do
163
194
  expect_validate_user
164
195
  expect_http_call_to(
165
196
  path: resource_config[:expected_api_path],
@@ -174,6 +205,21 @@ describe NexusMods do
174
205
  expect(resource_config[:get_cache_timestamp].call(nexus_mods)).to be_between(before, after)
175
206
  end
176
207
 
208
+ it 'updates the timestamp of the data stored in the API cache by updating manually the cache timestamp' do
209
+ expect_validate_user
210
+ expect_http_call_to(
211
+ path: resource_config[:expected_api_path],
212
+ json: resource_config[:mocked_api_json],
213
+ times: 2
214
+ )
215
+ resource_config[:query].call(nexus_mods)
216
+ resource_config[:set_cache_timestamp].call(nexus_mods, Time.now.utc - (365 * 24 * 60 * 60))
217
+ before = Time.now
218
+ resource_config[:query].call(nexus_mods)
219
+ after = Time.now
220
+ expect(resource_config[:get_cache_timestamp].call(nexus_mods)).to be_between(before, after)
221
+ end
222
+
177
223
  context 'when testing cache persistence in files' do
178
224
 
179
225
  it 'persists API cache in a file' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexus_mods
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan