Skip to content

Commit

Permalink
Merge pull request #290 from NYPL/HOTFIX_NoFulfillLinkInWorks
Browse files Browse the repository at this point in the history
Overwrite with fulfill link in FormatWork
  • Loading branch information
Apophenia authored Feb 5, 2024
2 parents 4cbc34e + 1a2c792 commit 149958c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 57 deletions.
21 changes: 13 additions & 8 deletions api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ def formatWorkOutput(
showAll,
dbClient,
formats=formats,
reader=reader
reader=reader,
request=request
)

cls.addWorkMeta(outWork, highlights=highlights)
Expand All @@ -171,30 +172,28 @@ def formatWorkOutput(
#Formatted work with a specific format given
elif formats != None and identifiers == None:
formattedWork = cls.formatWork(
works, None, showAll, dbClient, formats=formats, reader=reader
works, None, showAll, dbClient, formats=formats, reader=reader, request=request
)

formattedWork['editions'].sort(
key=lambda x: x['publication_date']
if x['publication_date'] else 9999
)

return formattedWork
#Formatted work with no format specified
else:
formattedWork = cls.formatWork(
works, None, showAll, dbClient, reader=reader
works, None, showAll, dbClient, reader=reader, request=request
)

formattedWork['editions'].sort(
key=lambda x: x['publication_date']
if x['publication_date'] else 9999
)

return formattedWork

@classmethod
def formatWork(cls, work, editionIds, showAll, dbClient=None, formats=None, reader=None):
def formatWork(cls, work, editionIds, showAll, dbClient=None, formats=None, reader=None, request=None):
workDict = dict(work)
workDict['edition_count'] = len(work.editions)
workDict['inCollections'] = cls.checkEditionInCollection(work, None, dbClient=dbClient)
Expand Down Expand Up @@ -224,6 +223,11 @@ def formatWork(cls, work, editionIds, showAll, dbClient=None, formats=None, read
None, [e for _, e in orderedEds.items()])
)

for edition in workDict['editions']:
for item in edition['items']:
if item.get("links"):
# Map over item links and patch with pre-signed URL where necessary
item['links']= list(map(APIUtils.replacePrivateLinkUrl, item['links'], repeat(request)))
return workDict

@classmethod
Expand All @@ -247,8 +251,9 @@ def formatEditionOutput(
if formattedEdition.get("instances"):
for instance in formattedEdition['instances']:
for item in instance['items']:
# Map over item links and patch with pre-signed URL where necessary
item['links']= list(map(APIUtils.replacePrivateLinkUrl, item['links'], repeat(request)))
if item.get("links"):
# Map over item links and patch with pre-signed URL where necessary
item['links']= list(map(APIUtils.replacePrivateLinkUrl, item['links'], repeat(request)))

return formattedEdition

Expand Down
100 changes: 51 additions & 49 deletions tests/unit/test_api_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def test_formatWorkOutput_single_work(self, mocker, testApp):
assert outWork['uuid'] == 1
assert outWork['editions'][0]['id'] == 'ed3'
assert outWork['editions'][2]['id'] == 'ed1'
mockFormat.assert_called_once_with('testWork', None, True, mocker.sentinel.dbClient, reader=None)
mockFormat.assert_called_once_with('testWork', None, True, mocker.sentinel.dbClient, reader=None, request=request)

def test_formatWorkOutput_multiple_works(self, mocker, testApp):
mockFormat = mocker.patch.object(APIUtils, 'formatWork')
Expand All @@ -302,74 +302,77 @@ def test_formatWorkOutput_multiple_works(self, mocker, testApp):

assert outWorks == ['formattedWork1', 'formattedWork2']
mockFormat.assert_has_calls([
mocker.call(testWorks[0], 1, True, mocker.sentinel.dbClient, formats=None, reader=None),
mocker.call(testWorks[1], 2, True, mocker.sentinel.dbClient, formats=None, reader=None),
mocker.call(testWorks[0], 1, True, mocker.sentinel.dbClient, formats=None, reader=None, request=request),
mocker.call(testWorks[1], 2, True, mocker.sentinel.dbClient, formats=None, reader=None, request=request),
])

mockAddMeta.assert_has_calls([
mocker.call('formattedWork1', highlights='highlight1'),
mocker.call('formattedWork2', highlights='highlight2')
])

def test_formatWork_showAll(self, testWork, mocker):
def test_formatWork_showAll(self, testWork, mocker, testApp):
mockFormatEdition = mocker.patch.object(APIUtils, 'formatEdition')
mockFormatEdition.return_value = {
'edition_id': 'ed1', 'items': ['it1']
'edition_id': 'ed1', 'items': [{'item1':'foo'}]
}
testWork.id = 'testID'

mockDB = mocker.MagicMock()
mockDBClient = mocker.patch('api.blueprints.drbWork.DBClient')
mockDBClient.return_value = mockDB

testWorkDict = APIUtils.formatWork(testWork, ['ed1'], True, dbClient=mockDBClient)
with testApp.test_request_context('/'):
testWorkDict = APIUtils.formatWork(testWork, ['ed1'], True, dbClient=mockDBClient, request=request)

assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert testWorkDict['editions'][0]['edition_id'] == 'ed1'
assert testWorkDict['editions'][0]['items'][0] == 'it1'
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'
mockFormatEdition.assert_called_once()
assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert testWorkDict['editions'][0]['edition_id'] == 'ed1'
assert testWorkDict['editions'][0]['items'][0] == {'item1':'foo'}
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'
mockFormatEdition.assert_called_once()

def test_formatWork_showAll_false(self, testWork, mocker):
def test_formatWork_showAll_false(self, testWork, mocker, testApp):

mockDB = mocker.MagicMock()
mockDBClient = mocker.patch('api.blueprints.drbWork.DBClient')
mockDBClient.return_value = mockDB

testWork.id = 'testID'
mockFormatEdition = mocker.patch.object(APIUtils, 'formatEdition')
mockFormatEdition.return_value = {
'edition_id': 'ed1', 'items': ['it1']
}
testWorkDict = APIUtils.formatWork(testWork, ['ed1'], False, dbClient=mockDBClient)
with testApp.test_request_context('/'):
testWork.id = 'testID'
mockFormatEdition = mocker.patch.object(APIUtils, 'formatEdition')
mockFormatEdition.return_value = {
'edition_id': 'ed1', 'items': [{'item1':'foo'}]
}
testWorkDict = APIUtils.formatWork(testWork, ['ed1'], False, dbClient=mockDBClient, request=request)

assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert len(testWorkDict['editions']) == 1
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'
assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert len(testWorkDict['editions']) == 1
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'

def test_formatWork_blocked_edition(self, testWork, mocker):
def test_formatWork_blocked_edition(self, testWork, mocker, testApp):
mockDB = mocker.MagicMock()
mockDBClient = mocker.patch('api.blueprints.drbWork.DBClient')
mockDBClient.return_value = mockDB

testWork.id = 'testID'
testWork.editions[0].items = []
testWorkDict = APIUtils.formatWork(testWork, ['ed2'], True, dbClient=mockDBClient)

assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert len(testWorkDict['editions']) == 0
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'

def test_formatWork_ordered_editions(self, testWork, mocker):
with testApp.test_request_context('/'):
testWork.id = 'testID'
testWork.editions[0].items = []
testWorkDict = APIUtils.formatWork(testWork, ['ed2'], True, dbClient=mockDBClient, request=request)

assert testWorkDict['uuid'] == 'testUUID'
assert testWorkDict['title'] == 'Test Title'
assert len(testWorkDict['editions']) == 0
assert testWorkDict['edition_count'] == 1
assert testWorkDict['date_created'] == '2022-05-12T10:00:41'
assert testWorkDict['date_modified'] == '2022-05-13T10:00:44'

def test_formatWork_ordered_editions(self, testWork, mocker, testApp):
testWork.editions = [mocker.MagicMock(id=1), mocker.MagicMock(id=2)]
testWork.id = 'testID'

Expand All @@ -379,14 +382,15 @@ def test_formatWork_ordered_editions(self, testWork, mocker):

mockFormatEdition = mocker.patch.object(APIUtils, 'formatEdition')
mockFormatEdition.side_effect = [
{'edition_id': 'ed1', 'items': ['it1']},
{'edition_id': 'ed2', 'items': ['it2']}
{'edition_id': 'ed1', 'items': [{'it1':'item'}]},
{'edition_id': 'ed2', 'items': [{'it2':'item'}]}
]

testWorkDict = APIUtils.formatWork(testWork, [2, 1], True, dbClient=mockDBClient)
with testApp.test_request_context('/'):
testWorkDict = APIUtils.formatWork(testWork, [2, 1], True, dbClient=mockDBClient, request=request)

assert testWorkDict['editions'][0]['edition_id'] == 'ed2'
assert testWorkDict['editions'][1]['edition_id'] == 'ed1'
assert testWorkDict['editions'][0]['edition_id'] == 'ed2'
assert testWorkDict['editions'][1]['edition_id'] == 'ed1'

def test_formatEditionOutput(self, mocker, testApp):
mockFormatEdition = mocker.patch.object(APIUtils, 'formatEdition')
Expand Down Expand Up @@ -668,8 +672,7 @@ def test_getPresignedUrlFromNons3Url(self):
with pytest.raises(ValueError):
APIUtils.getPresignedUrlFromObjectUrl({"Some Client"}, "https://example.com")

def test_ReplaceWithPrivateLink(self):
testApp = Flask('test')
def test_ReplaceWithPrivateLink(self, testApp):
with testApp.test_request_context('/', base_url="http://localhost:5000"):
testLoginLinkObj = {
'link_id':'12345',
Expand All @@ -684,7 +687,7 @@ def test_ReplaceWithPrivateLink(self):
'flags':{'nypl_login': True}
}

def test_noLinkReplacement(self):
def test_noLinkReplacement(self, testApp):
testElectronicDeliveryLink = {
'link_id':'6789',
'media_type' : "application/html+edd",
Expand All @@ -695,7 +698,6 @@ def test_noLinkReplacement(self):
"reader": False
}
}
testApp = Flask('test')
with testApp.test_request_context('/'):
assert APIUtils.replacePrivateLinkUrl(
testElectronicDeliveryLink, request
Expand Down

0 comments on commit 149958c

Please sign in to comment.