RecordProcessorTest.scala 4.75 KB
Newer Older
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
1
/*
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
2
 * Media Converter
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 * Extracts media files from Fedora repository
 * Copyright (C) 2020  Memoriav
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

20
package ch.memobase
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
21

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
22
import java.io.ByteArrayOutputStream
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
23

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
24
25
26
27
import ch.memobase.models._
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.scalamock.scalatest.MockFactory
import org.scalatest.funsuite.AnyFunSuite
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
28

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import scala.io.Source
import scala.util.Success

class RecordProcessorTest extends AnyFunSuite with MockFactory {

  def createIncomingMessage(eventType: Event, mimeType: MediaFileType, hasBinaryResource: Boolean = true): (String, ByteArrayOutputStream) = {
    if (hasBinaryResource) {
      val eT = eventType match {
        case Create => "Create"
        case Delete => "Delete"
        case Update => "Update"
      }

      val mT = mimeType match {
        case JpegFile => "image/jpeg"
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
44
        case Mp3File => "audio/mpeg"
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
45
46
47
48
49
50
51
52
53
        case VideoMpeg4File => "video/mpeg"
      }
      replaceTokensInIncomingMessage(eT, mT)
    } else {
      val is = Source.fromFile("src/test/resources/incoming_message_without_binary.json")
      val incomingMessage = is.mkString
      val baos = copyIncomingMessage(incomingMessage)
      is.close
      (incomingMessage, baos)
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
54
    }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
55
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
56

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
57
  private def replaceTokensInIncomingMessage(eventType: String, mimeType: String, locator: String = "https://memobase.ch/digital/BAZ-MEI_77466-1/binary") = {
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
58
59
60
61
    val is = Source.fromFile("src/test/resources/incoming_message_with_binary.json")
    val incomingMessage = is.mkString
      .replaceAll(raw"\{\{mimeType\}\}", mimeType)
      .replaceAll(raw"\{\{eventType\}\}", eventType)
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
62
      .replaceAll(raw"\{\{locator\}\}", locator)
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
63
64
65
66
    val baos = copyIncomingMessage(incomingMessage)
    is.close
    (incomingMessage, baos)
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
67

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
68
69
70
71
72
73
  private def copyIncomingMessage(incomingMessage: String): ByteArrayOutputStream = {
    val incomingMessageAsBytes = incomingMessage.getBytes()
    val baos = new ByteArrayOutputStream()
    baos.write(incomingMessageAsBytes, 0, incomingMessageAsBytes.length)
    baos
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
74

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
75
76
77
  private val fixture = new {
    val externalBaseUrl = "https://memobase.ch"
    val resourceId = "BAZ-MEI_77466-1"
78
    val pathToResource = s"$externalBaseUrl/digital/$resourceId/binary"
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
79
80
81
    val mockDisseminationCopyHandler: DisseminationCopyHandler = mock[DisseminationCopyHandler]
    val mockFedoraClientWrapper: FedoraClientWrapper = mock[FedoraClientWrapper]
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
82

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
83
  test("an object of mimeType image/jpeg and eventType Create should trigger copyImage") {
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
84
85
86
87
88
    val f = fixture
    val mockDCH = f.mockDisseminationCopyHandler
    val mockFCW = f.mockFedoraClientWrapper
    val (incomingMessage, baos) = createIncomingMessage(Create, JpegFile)
    (mockFCW.fetchBinaryResource _).expects(f.pathToResource).returning(Success(FileWithMetadata(baos, JpegFile)))
89
    (mockDCH.createImageCopy _).expects(baos, f.resourceId, JpegFile)
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
90
91
92
93
    val rP = new RecordProcessor(mockDCH, mockFCW, f.externalBaseUrl)
    val cR = new ConsumerRecord[String, String]("_void", 1, 0, "1", incomingMessage)
    rP.process(cR)
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
94

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
95
96
97
98
99
100
101
102
103
104
105
  test("an object of mimeType audio/mpeg and eventType Delete should trigger deleteAudio") {
    val f = fixture
    val mockDCH = f.mockDisseminationCopyHandler
    val mockFCW = f.mockFedoraClientWrapper
    val (incomingMessage, baos) = createIncomingMessage(Delete, Mp3File)
    (mockFCW.fetchBinaryResource _).expects(f.pathToResource).returning(Success(FileWithMetadata(baos, Mp3File)))
    (mockDCH.deleteAudioCopy _).expects(f.resourceId)
    val rP = new RecordProcessor(mockDCH, mockFCW, f.externalBaseUrl)
    val cR = new ConsumerRecord[String, String]("_void", 1, 0, "1", incomingMessage)
    rP.process(cR)
  }
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
106

Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
107
108
109
110
111
112
113
114
115
  test("a message which does not refer to a binary file should be ignored") {
    val f = fixture
    val mockDCH = f.mockDisseminationCopyHandler
    val mockFCW = f.mockFedoraClientWrapper
    val (incomingMessage, _) = createIncomingMessage(Delete, Mp3File, hasBinaryResource = false)
    (mockFCW.fetchBinaryResource _).expects(*).never()
    val rP = new RecordProcessor(mockDCH, mockFCW, f.externalBaseUrl)
    val cR = new ConsumerRecord[String, String]("_void", 1, 0, "1", incomingMessage)
    rP.process(cR)
Sebastian Schüpbach's avatar
Sebastian Schüpbach committed
116
117
  }
}