mirror of
https://github.com/edufeed-org/eventstore.git
synced 2025-12-10 00:34:32 +00:00
Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dc0744041 | ||
|
|
5e16129e4c |
7 changed files with 1216 additions and 490 deletions
8
go.mod
8
go.mod
|
|
@ -3,7 +3,7 @@ module github.com/edufeed-org/eventstore
|
|||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/fiatjaf/eventstore v0.16.2
|
||||
github.com/fiatjaf/eventstore v0.16.4
|
||||
github.com/nbd-wtf/go-nostr v0.51.8
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
|
@ -12,10 +12,10 @@ require (
|
|||
github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
|
||||
github.com/bytedance/sonic v1.13.1 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||
github.com/coder/websocket v1.8.12 // indirect
|
||||
github.com/coder/websocket v1.8.13 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
|
|
@ -33,6 +33,8 @@ require (
|
|||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
golang.org/x/arch v0.15.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
|
|
|||
17
go.sum
17
go.sum
|
|
@ -4,16 +4,14 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurT
|
|||
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
|
||||
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
||||
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -22,8 +20,7 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPc
|
|||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/fiatjaf/eventstore v0.16.2 h1:h4rHwSwPcqAKqWUsAbYWUhDeSgm2Kp+PBkJc3FgBYu4=
|
||||
github.com/fiatjaf/eventstore v0.16.2/go.mod h1:0gU8fzYO/bG+NQAVlHtJWOlt3JKKFefh5Xjj2d1dLIs=
|
||||
github.com/fiatjaf/eventstore v0.16.4 h1:pENYeuhawxMxlJk8HpRy3pb2oap0fwbphzUgsy7QPws=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
|
|
@ -33,6 +30,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
|
|||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
|
@ -46,6 +45,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
|||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
|
|
@ -70,12 +70,11 @@ golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
|
|||
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
func TestNostrToAmbEvent(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
sk := nostr.GeneratePrivateKey()
|
||||
|
|
@ -38,7 +37,6 @@ func TestNostrToAmbEvent(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
// Helper function to create a test event with a specific tag
|
||||
func createTestEvent(tags nostr.Tags) *nostr.Event {
|
||||
sk := nostr.GeneratePrivateKey()
|
||||
|
|
@ -54,24 +52,24 @@ func createTestEvent(tags nostr.Tags) *nostr.Event {
|
|||
|
||||
func TestNostrToAMB_BasicFields(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"name", "Test Resource"},
|
||||
{"description", "This is a test resource"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(event.ID, amb.ID)
|
||||
assert.Equal("test-resource-id", amb.D)
|
||||
assert.Equal("Test Resource", amb.Name)
|
||||
assert.Equal("This is a test resource", amb.Description)
|
||||
|
||||
|
||||
assert.Equal(event.ID, amb.EventID)
|
||||
assert.Equal(event.PubKey, amb.EventPubKey)
|
||||
assert.Equal(event.Content, amb.EventContent)
|
||||
|
|
@ -82,39 +80,45 @@ func TestNostrToAMB_BasicFields(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_About(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"about", "http://w3id.org/kim/schulfaecher/s1009", "Französisch", "de"},
|
||||
{"about:id", "http://w3id.org/kim/schulfaecher/s1009"},
|
||||
{"about:prefLabel", "Französisch"},
|
||||
{"about:inLanguage", "de"},
|
||||
{"about:type", "Concept"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.NotEmpty(amb.About)
|
||||
assert.Equal(1, len(amb.About))
|
||||
assert.Equal("http://w3id.org/kim/schulfaecher/s1009", amb.About[0].ID)
|
||||
assert.Equal("Französisch", amb.About[0].PrefLabel)
|
||||
assert.Equal("de", amb.About[0].InLanguage)
|
||||
assert.Equal("Concept", amb.About[0].Type)
|
||||
}
|
||||
|
||||
func TestNostrToAMB_Keywords(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"keywords", "Französisch", "Niveau A2", "Sprache"},
|
||||
{"t", "Französisch"},
|
||||
{"t", "Niveau A2"},
|
||||
{"t", "Sprache"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(3, len(amb.Keywords))
|
||||
assert.Contains(amb.Keywords, "Französisch")
|
||||
assert.Contains(amb.Keywords, "Niveau A2")
|
||||
|
|
@ -123,19 +127,19 @@ func TestNostrToAMB_Keywords(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_InLanguage(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"inLanguage", "fr"},
|
||||
{"inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.InLanguage))
|
||||
assert.Contains(amb.InLanguage, "fr")
|
||||
assert.Contains(amb.InLanguage, "de")
|
||||
|
|
@ -143,43 +147,47 @@ func TestNostrToAMB_InLanguage(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Image(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
imageURL := "https://www.tutory.de/worksheet/fbbadf1a-145a-463d-9a43-1ae9965c86b9.jpg?width=1000"
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"image", imageURL},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(imageURL, amb.Image)
|
||||
}
|
||||
|
||||
func TestNostrToAMB_Creator(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"creator", "http://author1.org", "Autorin 1", "Person"},
|
||||
{"creator", "http://author2.org", "Autorin 2", "Person"},
|
||||
{"creator:id", "http://author1.org"},
|
||||
{"creator:name", "Autorin 1"},
|
||||
{"creator:type", "Person"},
|
||||
{"creator:id", "http://author2.org"},
|
||||
{"creator:name", "Autorin 2"},
|
||||
{"creator:type", "Person"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Creator))
|
||||
|
||||
|
||||
assert.Equal("http://author1.org", amb.Creator[0].ID)
|
||||
assert.Equal("Autorin 1", amb.Creator[0].Name)
|
||||
assert.Equal("Person", amb.Creator[0].Type)
|
||||
|
||||
|
||||
assert.Equal("http://author2.org", amb.Creator[1].ID)
|
||||
assert.Equal("Autorin 2", amb.Creator[1].Name)
|
||||
assert.Equal("Person", amb.Creator[1].Type)
|
||||
|
|
@ -187,25 +195,29 @@ func TestNostrToAMB_Creator(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Contributor(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"contributor", "http://author1.org", "Autorin 1", "Person"},
|
||||
{"contributor", "http://author2.org", "Autorin 2", "Person"},
|
||||
{"contributor:id", "http://author1.org"},
|
||||
{"contributor:name", "Autorin 1"},
|
||||
{"contributor:type", "Person"},
|
||||
{"contributor:id", "http://author2.org"},
|
||||
{"contributor:name", "Autorin 2"},
|
||||
{"contributor:type", "Person"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Contributor))
|
||||
|
||||
|
||||
assert.Equal("http://author1.org", amb.Contributor[0].ID)
|
||||
assert.Equal("Autorin 1", amb.Contributor[0].Name)
|
||||
assert.Equal("Person", amb.Contributor[0].Type)
|
||||
|
||||
|
||||
assert.Equal("http://author2.org", amb.Contributor[1].ID)
|
||||
assert.Equal("Autorin 2", amb.Contributor[1].Name)
|
||||
assert.Equal("Person", amb.Contributor[1].Type)
|
||||
|
|
@ -213,7 +225,7 @@ func TestNostrToAMB_Contributor(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Dates(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"dateCreated", "2019-07-02"},
|
||||
|
|
@ -221,12 +233,12 @@ func TestNostrToAMB_Dates(t *testing.T) {
|
|||
{"dateModified", "2019-07-04"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal("2019-07-02", amb.DateCreated)
|
||||
assert.Equal("2019-07-03", amb.DatePublished)
|
||||
assert.Equal("2019-07-04", amb.DateModified)
|
||||
|
|
@ -234,25 +246,29 @@ func TestNostrToAMB_Dates(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Publisher(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"publisher", "http://publisher1.org", "Publisher 1", "Person"},
|
||||
{"publisher", "http://publisher2.org", "Publisher 2", "Organization"},
|
||||
{"publisher:id", "http://publisher1.org"},
|
||||
{"publisher:name", "Publisher 1"},
|
||||
{"publisher:type", "Person"},
|
||||
{"publisher:id", "http://publisher2.org"},
|
||||
{"publisher:name", "Publisher 2"},
|
||||
{"publisher:type", "Organization"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Publisher))
|
||||
|
||||
|
||||
assert.Equal("http://publisher1.org", amb.Publisher[0].ID)
|
||||
assert.Equal("Publisher 1", amb.Publisher[0].Name)
|
||||
assert.Equal("Person", amb.Publisher[0].Type)
|
||||
|
||||
|
||||
assert.Equal("http://publisher2.org", amb.Publisher[1].ID)
|
||||
assert.Equal("Publisher 2", amb.Publisher[1].Name)
|
||||
assert.Equal("Organization", amb.Publisher[1].Type)
|
||||
|
|
@ -260,25 +276,29 @@ func TestNostrToAMB_Publisher(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Funder(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"funder", "http://funder1.org", "Funder 1", "Person"},
|
||||
{"funder", "http://funder2.org", "Funder 2", "Organization"},
|
||||
{"funder:id", "http://funder1.org"},
|
||||
{"funder:name", "Funder 1"},
|
||||
{"funder:type", "Person"},
|
||||
{"funder:id", "http://funder2.org"},
|
||||
{"funder:name", "Funder 2"},
|
||||
{"funder:type", "Organization"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Funder))
|
||||
|
||||
|
||||
assert.Equal("http://funder1.org", amb.Funder[0].ID)
|
||||
assert.Equal("Funder 1", amb.Funder[0].Name)
|
||||
assert.Equal("Person", amb.Funder[0].Type)
|
||||
|
||||
|
||||
assert.Equal("http://funder2.org", amb.Funder[1].ID)
|
||||
assert.Equal("Funder 2", amb.Funder[1].Name)
|
||||
assert.Equal("Organization", amb.Funder[1].Type)
|
||||
|
|
@ -286,49 +306,50 @@ func TestNostrToAMB_Funder(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_IsAccessibleForFree(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"isAccessibleForFree", "true"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.True(amb.IsAccessibleForFree)
|
||||
|
||||
|
||||
// Test with "false" value
|
||||
tags = nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"isAccessibleForFree", "false"},
|
||||
}
|
||||
event = createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err = NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.False(amb.IsAccessibleForFree)
|
||||
}
|
||||
|
||||
func TestNostrToAMB_License(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"license", "https://creativecommons.org/publicdomain/zero/1.0/", "CC-0"},
|
||||
{"license:id", "https://creativecommons.org/publicdomain/zero/1.0/"},
|
||||
{"license:name", "CC-0"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.NotNil(amb.License)
|
||||
assert.Equal("https://creativecommons.org/publicdomain/zero/1.0/", amb.License.ID)
|
||||
assert.Equal("CC-0", amb.License.Name)
|
||||
|
|
@ -336,18 +357,21 @@ func TestNostrToAMB_License(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_ConditionsOfAccess(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"conditionsOfAccess", "http://w3id.org/kim/conditionsOfAccess/no_login", "Kein Login", "de"},
|
||||
{"conditionsOfAccess:id", "http://w3id.org/kim/conditionsOfAccess/no_login"},
|
||||
{"conditionsOfAccess:prefLabel", "Kein Login"},
|
||||
{"conditionsOfAccess:inLanguage", "de"},
|
||||
{"conditionsOfAccess:type", "Concept"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.NotNil(amb.ConditionsOfAccess)
|
||||
assert.Equal("http://w3id.org/kim/conditionsOfAccess/no_login", amb.ConditionsOfAccess.ID)
|
||||
assert.Equal("Kein Login", amb.ConditionsOfAccess.PrefLabel)
|
||||
|
|
@ -356,25 +380,29 @@ func TestNostrToAMB_ConditionsOfAccess(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_LearningResourceType(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"learningResourceType", "http://w3id.org/openeduhub/vocabs/new_lrt/video", "Video", "de"},
|
||||
{"learningResourceType", "http://w3id.org/openeduhub/vocabs/new_lrt/tutorial", "Tutorial", "en"},
|
||||
{"learningResourceType:id", "http://w3id.org/openeduhub/vocabs/new_lrt/video"},
|
||||
{"learningResourceType:prefLabel", "Video"},
|
||||
{"learningResourceType:inLanguage", "de"},
|
||||
{"learningResourceType:id", "http://w3id.org/openeduhub/vocabs/new_lrt/tutorial"},
|
||||
{"learningResourceType:prefLabel", "Tutorial"},
|
||||
{"learningResourceType:inLanguage", "en"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.LearningResourceType))
|
||||
|
||||
|
||||
assert.Equal("http://w3id.org/openeduhub/vocabs/new_lrt/video", amb.LearningResourceType[0].ID)
|
||||
assert.Equal("Video", amb.LearningResourceType[0].PrefLabel)
|
||||
assert.Equal("de", amb.LearningResourceType[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("http://w3id.org/openeduhub/vocabs/new_lrt/tutorial", amb.LearningResourceType[1].ID)
|
||||
assert.Equal("Tutorial", amb.LearningResourceType[1].PrefLabel)
|
||||
assert.Equal("en", amb.LearningResourceType[1].InLanguage)
|
||||
|
|
@ -382,25 +410,29 @@ func TestNostrToAMB_LearningResourceType(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Audience(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"audience", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student", "Schüler:in", "de"},
|
||||
{"audience", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/teacher", "Lehrer:in", "de"},
|
||||
{"audience:id", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student"},
|
||||
{"audience:prefLabel", "Schüler:in"},
|
||||
{"audience:inLanguage", "de"},
|
||||
{"audience:id", "http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/teacher"},
|
||||
{"audience:prefLabel", "Lehrer:in"},
|
||||
{"audience:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Audience))
|
||||
|
||||
|
||||
assert.Equal("http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/student", amb.Audience[0].ID)
|
||||
assert.Equal("Schüler:in", amb.Audience[0].PrefLabel)
|
||||
assert.Equal("de", amb.Audience[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("http://purl.org/dcx/lrmi-vocabs/educationalAudienceRole/teacher", amb.Audience[1].ID)
|
||||
assert.Equal("Lehrer:in", amb.Audience[1].PrefLabel)
|
||||
assert.Equal("de", amb.Audience[1].InLanguage)
|
||||
|
|
@ -408,25 +440,29 @@ func TestNostrToAMB_Audience(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Teaches(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"teaches", "http://awesome-skills.org/1", "Zuhören", "de"},
|
||||
{"teaches", "http://awesome-skills.org/2", "Sprechen", "de"},
|
||||
{"teaches:id", "http://awesome-skills.org/1"},
|
||||
{"teaches:prefLabel", "Zuhören"},
|
||||
{"teaches:inLanguage", "de"},
|
||||
{"teaches:id", "http://awesome-skills.org/2"},
|
||||
{"teaches:prefLabel", "Sprechen"},
|
||||
{"teaches:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Teaches))
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/1", amb.Teaches[0].ID)
|
||||
assert.Equal("Zuhören", amb.Teaches[0].PrefLabel)
|
||||
assert.Equal("de", amb.Teaches[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/2", amb.Teaches[1].ID)
|
||||
assert.Equal("Sprechen", amb.Teaches[1].PrefLabel)
|
||||
assert.Equal("de", amb.Teaches[1].InLanguage)
|
||||
|
|
@ -434,25 +470,29 @@ func TestNostrToAMB_Teaches(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Assesses(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"assesses", "http://awesome-skills.org/1", "Hörverständnis", "de"},
|
||||
{"assesses", "http://awesome-skills.org/2", "Grammatik", "de"},
|
||||
{"assesses:id", "http://awesome-skills.org/1"},
|
||||
{"assesses:prefLabel", "Hörverständnis"},
|
||||
{"assesses:inLanguage", "de"},
|
||||
{"assesses:id", "http://awesome-skills.org/2"},
|
||||
{"assesses:prefLabel", "Grammatik"},
|
||||
{"assesses:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.Assesses))
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/1", amb.Assesses[0].ID)
|
||||
assert.Equal("Hörverständnis", amb.Assesses[0].PrefLabel)
|
||||
assert.Equal("de", amb.Assesses[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/2", amb.Assesses[1].ID)
|
||||
assert.Equal("Grammatik", amb.Assesses[1].PrefLabel)
|
||||
assert.Equal("de", amb.Assesses[1].InLanguage)
|
||||
|
|
@ -460,25 +500,29 @@ func TestNostrToAMB_Assesses(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_CompetencyRequired(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"competencyRequired", "http://awesome-skills.org/1", "Basisvokabular", "de"},
|
||||
{"competencyRequired", "http://awesome-skills.org/2", "Grundkenntnisse", "de"},
|
||||
{"competencyRequired:id", "http://awesome-skills.org/1"},
|
||||
{"competencyRequired:prefLabel", "Basisvokabular"},
|
||||
{"competencyRequired:inLanguage", "de"},
|
||||
{"competencyRequired:id", "http://awesome-skills.org/2"},
|
||||
{"competencyRequired:prefLabel", "Grundkenntnisse"},
|
||||
{"competencyRequired:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.CompetencyRequired))
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/1", amb.CompetencyRequired[0].ID)
|
||||
assert.Equal("Basisvokabular", amb.CompetencyRequired[0].PrefLabel)
|
||||
assert.Equal("de", amb.CompetencyRequired[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("http://awesome-skills.org/2", amb.CompetencyRequired[1].ID)
|
||||
assert.Equal("Grundkenntnisse", amb.CompetencyRequired[1].PrefLabel)
|
||||
assert.Equal("de", amb.CompetencyRequired[1].InLanguage)
|
||||
|
|
@ -486,25 +530,29 @@ func TestNostrToAMB_CompetencyRequired(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_EducationalLevel(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"educationalLevel", "https://w3id.org/kim/educationalLevel/level_2", "Sekundarstufe 1", "de"},
|
||||
{"educationalLevel", "https://w3id.org/kim/educationalLevel/level_3", "Sekundarstufe 2", "de"},
|
||||
{"educationalLevel:id", "https://w3id.org/kim/educationalLevel/level_2"},
|
||||
{"educationalLevel:prefLabel", "Sekundarstufe 1"},
|
||||
{"educationalLevel:inLanguage", "de"},
|
||||
{"educationalLevel:id", "https://w3id.org/kim/educationalLevel/level_3"},
|
||||
{"educationalLevel:prefLabel", "Sekundarstufe 2"},
|
||||
{"educationalLevel:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.EducationalLevel))
|
||||
|
||||
|
||||
assert.Equal("https://w3id.org/kim/educationalLevel/level_2", amb.EducationalLevel[0].ID)
|
||||
assert.Equal("Sekundarstufe 1", amb.EducationalLevel[0].PrefLabel)
|
||||
assert.Equal("de", amb.EducationalLevel[0].InLanguage)
|
||||
|
||||
|
||||
assert.Equal("https://w3id.org/kim/educationalLevel/level_3", amb.EducationalLevel[1].ID)
|
||||
assert.Equal("Sekundarstufe 2", amb.EducationalLevel[1].PrefLabel)
|
||||
assert.Equal("de", amb.EducationalLevel[1].InLanguage)
|
||||
|
|
@ -512,18 +560,20 @@ func TestNostrToAMB_EducationalLevel(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_InteractivityType(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"interactivityType", "http://purl.org/dcx/lrmi-vocabs/interactivityType/active", "aktiv", "de"},
|
||||
{"interactivityType:id", "http://purl.org/dcx/lrmi-vocabs/interactivityType/active"},
|
||||
{"interactivityType:prefLabel", "aktiv"},
|
||||
{"interactivityType:inLanguage", "de"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.NotNil(amb.InteractivityType)
|
||||
assert.Equal("http://purl.org/dcx/lrmi-vocabs/interactivityType/active", amb.InteractivityType.ID)
|
||||
assert.Equal("aktiv", amb.InteractivityType.PrefLabel)
|
||||
|
|
@ -532,18 +582,19 @@ func TestNostrToAMB_InteractivityType(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_IsBasedOn(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"isBasedOn", "http://an-awesome-resource.org", "Französisch I"},
|
||||
{"isBasedOn:id", "http://an-awesome-resource.org"},
|
||||
{"isBasedOn:name", "Französisch I"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(1, len(amb.IsBasedOn))
|
||||
assert.Equal("http://an-awesome-resource.org", amb.IsBasedOn[0].ID)
|
||||
assert.Equal("Französisch I", amb.IsBasedOn[0].Name)
|
||||
|
|
@ -551,18 +602,20 @@ func TestNostrToAMB_IsBasedOn(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_IsPartOf(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"isPartOf", "http://whole.org", "Whole", "PresentationDigitalDocument"},
|
||||
{"isPartOf:id", "http://whole.org"},
|
||||
{"isPartOf:name", "Whole"},
|
||||
{"isPartOf:type", "PresentationDigitalDocument"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(1, len(amb.IsPartOf))
|
||||
assert.Equal("http://whole.org", amb.IsPartOf[0].ID)
|
||||
assert.Equal("Whole", amb.IsPartOf[0].Name)
|
||||
|
|
@ -571,24 +624,28 @@ func TestNostrToAMB_IsPartOf(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_HasPart(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"hasPart", "http://part1.org", "Part 1", "LearningResource"},
|
||||
{"hasPart", "http://part2.org", "Part 2", "LearningResource"},
|
||||
{"hasPart:id", "http://part1.org"},
|
||||
{"hasPart:name", "Part 1"},
|
||||
{"hasPart:type", "LearningResource"},
|
||||
{"hasPart:id", "http://part2.org"},
|
||||
{"hasPart:name", "Part 2"},
|
||||
{"hasPart:type", "LearningResource"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(2, len(amb.HasPart))
|
||||
assert.Equal("http://part1.org", amb.HasPart[0].ID)
|
||||
assert.Equal("Part 1", amb.HasPart[0].Name)
|
||||
assert.Equal("LearningResource", amb.HasPart[0].Type)
|
||||
|
||||
|
||||
assert.Equal("http://part2.org", amb.HasPart[1].ID)
|
||||
assert.Equal("Part 2", amb.HasPart[1].Name)
|
||||
assert.Equal("LearningResource", amb.HasPart[1].Type)
|
||||
|
|
@ -596,42 +653,47 @@ func TestNostrToAMB_HasPart(t *testing.T) {
|
|||
|
||||
func TestNostrToAMB_Duration(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"duration", "PT30M"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal("PT30M", amb.Duration)
|
||||
}
|
||||
|
||||
func TestNostrToAMB_Trailer(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
|
||||
tags := nostr.Tags{
|
||||
{"d", "test-resource-id"},
|
||||
{"trailer", "https://example.com/video.mp4", "Video", "video/mp4", "10MB", "abc123", "https://example.com/embed", "1Mbps"},
|
||||
{"trailer:contentUrl", "https://example.com/video.mp4"},
|
||||
{"trailer:type", "VideoObject"},
|
||||
{"trailer:encodingFormat", "video/mp4"},
|
||||
{"trailer:contentSize", "10MB"},
|
||||
{"trailer:sha256", "abc123"},
|
||||
{"trailer:embedUrl", "https://example.com/embed"},
|
||||
{"trailer:bitrate", "1Mbps"},
|
||||
}
|
||||
event := createTestEvent(tags)
|
||||
|
||||
|
||||
amb, err := NostrToAMB(event)
|
||||
|
||||
|
||||
assert.NoError(err)
|
||||
assert.NotNil(amb)
|
||||
|
||||
|
||||
assert.Equal(1, len(amb.Trailer))
|
||||
assert.Equal("https://example.com/video.mp4", amb.Trailer[0].ContentUrl)
|
||||
assert.Equal("Video", amb.Trailer[0].Type)
|
||||
assert.Equal("VideoObject", amb.Trailer[0].Type)
|
||||
assert.Equal("video/mp4", amb.Trailer[0].EncodingFormat)
|
||||
assert.Equal("10MB", amb.Trailer[0].ContentSize)
|
||||
assert.Equal("abc123", amb.Trailer[0].Sha256)
|
||||
assert.Equal("https://example.com/embed", amb.Trailer[0].EmbedUrl)
|
||||
assert.Equal("1Mbps", amb.Trailer[0].Bitrate)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,22 @@ func (ts *TSBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (chan
|
|||
ch := make(chan *nostr.Event)
|
||||
|
||||
log.Printf("Processing query with search: %s", filter.Search)
|
||||
|
||||
// If we have no search parameter, return an empty channel
|
||||
if filter.Search == "" {
|
||||
log.Printf("No search parameter provided, returning empty result")
|
||||
close(ch)
|
||||
return ch, nil
|
||||
|
||||
// Determine the limit for results (default to 100 if not specified)
|
||||
limit := 100
|
||||
if filter.Limit > 0 {
|
||||
limit = filter.Limit
|
||||
}
|
||||
|
||||
nostrsearch, err := ts.SearchResources(filter.Search)
|
||||
// Use empty search string or the provided search string
|
||||
searchStr := filter.Search
|
||||
if searchStr == "" {
|
||||
log.Printf("No search parameter provided, querying all documents with limit %d", limit)
|
||||
} else {
|
||||
log.Printf("Processing query with search: %s and limit %d", searchStr, limit)
|
||||
}
|
||||
|
||||
nostrsearch, err := ts.SearchResourcesWithLimit(searchStr, limit)
|
||||
if err != nil {
|
||||
log.Printf("Search failed: %v", err)
|
||||
// Return the channel anyway, but close it immediately
|
||||
|
|
@ -57,7 +64,7 @@ func (ts *TSBackend) QueryEvents(ctx context.Context, filter nostr.Filter) (chan
|
|||
close(ch)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
|
|
@ -126,6 +133,76 @@ func (ts *TSBackend) SearchResources(searchStr string) ([]nostr.Event, error) {
|
|||
return parseSearchResponse(body)
|
||||
}
|
||||
|
||||
// searches for resources with limit support and returns both the AMB metadata and converted Nostr events
|
||||
func (ts *TSBackend) SearchResourcesWithLimit(searchStr string, limit int) ([]nostr.Event, error) {
|
||||
parsedQuery := ParseSearchQuery(searchStr)
|
||||
|
||||
mainQuery, params, err := BuildTypesenseQuery(parsedQuery)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error building Typesense query: %v", err)
|
||||
}
|
||||
|
||||
// If no search terms provided, use wildcard to match all documents
|
||||
if mainQuery == "" {
|
||||
mainQuery = "*"
|
||||
}
|
||||
|
||||
// URL encode the main query
|
||||
encodedQuery := url.QueryEscape(mainQuery)
|
||||
|
||||
// Default fields to search in
|
||||
queryBy := "name,description,about,learningResourceType,keywords,creator,publisher"
|
||||
|
||||
// Start building the search URL with limit
|
||||
searchURL := fmt.Sprintf("%s/collections/%s/documents/search?validate_field_names=false&q=%s&query_by=%s&per_page=%d",
|
||||
ts.Host, ts.CollectionName, encodedQuery, queryBy, limit)
|
||||
|
||||
// Add additional parameters
|
||||
for key, value := range params {
|
||||
searchURL += fmt.Sprintf("&%s=%s", key, url.QueryEscape(value))
|
||||
}
|
||||
|
||||
// Debug information
|
||||
fmt.Printf("Search URL: %s\n", searchURL)
|
||||
|
||||
resp, body, err := ts.makehttpRequest(searchURL, http.MethodGet, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading response body: %v", err)
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("search failed with status code %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
// Try to parse the raw JSON to understand its structure
|
||||
var rawResponse interface{}
|
||||
if err := json.Unmarshal(body, &rawResponse); err != nil {
|
||||
fmt.Printf("Warning: Could not parse raw response as JSON: %v\n", err)
|
||||
} else {
|
||||
// Check if we got a hits array
|
||||
responseMap, ok := rawResponse.(map[string]interface{})
|
||||
if ok {
|
||||
if hits, exists := responseMap["hits"]; exists {
|
||||
hitsArray, ok := hits.([]interface{})
|
||||
if ok {
|
||||
fmt.Printf("Response contains %d hits\n", len(hitsArray))
|
||||
if len(hitsArray) > 0 {
|
||||
// Look at the structure of the first hit
|
||||
firstHit, ok := hitsArray[0].(map[string]interface{})
|
||||
if ok {
|
||||
fmt.Printf("First hit keys: %v\n", getMapKeys(firstHit))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parseSearchResponse(body)
|
||||
}
|
||||
|
||||
// SearchQuery represents a parsed search query with raw terms and field filters
|
||||
type SearchQuery struct {
|
||||
RawTerms []string
|
||||
|
|
@ -154,7 +231,7 @@ func ParseSearchQuery(searchStr string) SearchQuery {
|
|||
// This is a field:value pair with dot notation
|
||||
fieldName := match[2]
|
||||
fieldValue := match[3]
|
||||
|
||||
|
||||
// Add to the array of values for this field
|
||||
query.FieldFilters[fieldName] = append(query.FieldFilters[fieldName], fieldValue)
|
||||
} else if match[4] != "" {
|
||||
|
|
@ -164,7 +241,7 @@ func ParseSearchQuery(searchStr string) SearchQuery {
|
|||
// Simple field:value without dot notation
|
||||
fieldName := parts[0]
|
||||
fieldValue := parts[1]
|
||||
|
||||
|
||||
// Add to the array of values for this field
|
||||
query.FieldFilters[fieldName] = append(query.FieldFilters[fieldName], fieldValue)
|
||||
} else {
|
||||
|
|
@ -198,7 +275,7 @@ func BuildTypesenseQuery(query SearchQuery) (string, map[string]string, error) {
|
|||
for _, value := range values {
|
||||
// Create the filter expression
|
||||
filterExpr := fmt.Sprintf("%s:%s", field, value)
|
||||
|
||||
|
||||
// Add to the corresponding field group
|
||||
fieldGroups[baseName] = append(fieldGroups[baseName], filterExpr)
|
||||
}
|
||||
|
|
@ -234,44 +311,44 @@ func parseSearchResponse(responseBody []byte) ([]nostr.Event, error) {
|
|||
|
||||
// Debug: Print the raw response structure
|
||||
fmt.Printf("Search response found %d hits\n", searchResponse.Found)
|
||||
|
||||
|
||||
nostrResults := make([]nostr.Event, 0, len(searchResponse.Hits))
|
||||
|
||||
for i, hit := range searchResponse.Hits {
|
||||
// Debug: Print hit structure information
|
||||
fmt.Printf("Processing hit %d, keys: %v\n", i, getMapKeys(hit))
|
||||
|
||||
|
||||
// Check if document exists in the hit
|
||||
docRaw, exists := hit["document"]
|
||||
if !exists {
|
||||
fmt.Printf("Warning: hit %d has no 'document' field\n", i)
|
||||
continue // Skip this hit
|
||||
}
|
||||
|
||||
|
||||
// Extract document directly as a map[string]interface{}
|
||||
docMap, ok := docRaw.(map[string]interface{})
|
||||
if !ok {
|
||||
fmt.Printf("Warning: hit %d document is not a map, type: %T\n", i, docRaw)
|
||||
continue // Skip this hit
|
||||
}
|
||||
|
||||
|
||||
// Debug: Print document keys
|
||||
fmt.Printf("Document keys: %v\n", getMapKeys(docMap))
|
||||
|
||||
|
||||
// Check for EventRaw field directly
|
||||
eventRawVal, hasEventRaw := docMap["eventRaw"]
|
||||
if !hasEventRaw {
|
||||
fmt.Printf("Warning: document has no 'eventRaw' field\n")
|
||||
continue // Skip this document
|
||||
}
|
||||
|
||||
|
||||
// Try to extract EventRaw as string
|
||||
eventRawStr, ok := eventRawVal.(string)
|
||||
if !ok {
|
||||
fmt.Printf("Warning: eventRaw is not a string, type: %T\n", eventRawVal)
|
||||
continue // Skip this document
|
||||
}
|
||||
|
||||
|
||||
// Convert the EventRaw string to a Nostr event
|
||||
nostrEvent, err := StringifiedJSONToNostrEvent(eventRawStr)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,2 +1,106 @@
|
|||
package typesense30142
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
)
|
||||
|
||||
func TestQueryEventsWithLimit(t *testing.T) {
|
||||
// Test that limit is properly handled
|
||||
tests := []struct {
|
||||
name string
|
||||
filter nostr.Filter
|
||||
expectedLimit int
|
||||
}{
|
||||
{
|
||||
name: "No limit specified - should default to 100",
|
||||
filter: nostr.Filter{
|
||||
Search: "",
|
||||
},
|
||||
expectedLimit: 100,
|
||||
},
|
||||
{
|
||||
name: "Limit of 2 specified",
|
||||
filter: nostr.Filter{
|
||||
Search: "",
|
||||
Limit: 2,
|
||||
},
|
||||
expectedLimit: 2,
|
||||
},
|
||||
{
|
||||
name: "Limit of 50 specified",
|
||||
filter: nostr.Filter{
|
||||
Search: "test",
|
||||
Limit: 50,
|
||||
},
|
||||
expectedLimit: 50,
|
||||
},
|
||||
{
|
||||
name: "Zero limit - should default to 100",
|
||||
filter: nostr.Filter{
|
||||
Search: "test",
|
||||
Limit: 0,
|
||||
},
|
||||
expectedLimit: 100,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Test the limit logic
|
||||
limit := 100
|
||||
if tt.filter.Limit > 0 {
|
||||
limit = tt.filter.Limit
|
||||
}
|
||||
|
||||
if limit != tt.expectedLimit {
|
||||
t.Errorf("Expected limit %d, got %d", tt.expectedLimit, limit)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTypesenseQueryWithEmptySearch(t *testing.T) {
|
||||
// Test that empty search strings are handled correctly
|
||||
query := ParseSearchQuery("")
|
||||
mainQuery, params, err := BuildTypesenseQuery(query)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("BuildTypesenseQuery failed: %v", err)
|
||||
}
|
||||
|
||||
// Empty search should result in empty main query
|
||||
if mainQuery != "" {
|
||||
t.Errorf("Expected empty main query, got: %s", mainQuery)
|
||||
}
|
||||
|
||||
// Should have no filter parameters for empty search
|
||||
if len(params) != 0 {
|
||||
t.Errorf("Expected no filter params for empty search, got: %v", params)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchResourcesWithLimitHandlesEmptySearch(t *testing.T) {
|
||||
// Test that SearchResourcesWithLimit properly handles empty search by using wildcard
|
||||
query := ParseSearchQuery("")
|
||||
mainQuery, _, err := BuildTypesenseQuery(query)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("BuildTypesenseQuery failed: %v", err)
|
||||
}
|
||||
|
||||
// Empty search should result in empty main query initially
|
||||
if mainQuery != "" {
|
||||
t.Errorf("Expected empty main query from ParseSearchQuery, got: %s", mainQuery)
|
||||
}
|
||||
|
||||
// SearchResourcesWithLimit should convert empty query to "*"
|
||||
if mainQuery == "" {
|
||||
mainQuery = "*"
|
||||
}
|
||||
|
||||
if mainQuery != "*" {
|
||||
t.Errorf("Expected wildcard query '*', got: %s", mainQuery)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,17 +77,17 @@ type Audience struct {
|
|||
|
||||
// Teaches represents what the content teaches
|
||||
type Teaches struct {
|
||||
ControlledVocabulary
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// Assesses represents what the content assesses
|
||||
type Assesses struct {
|
||||
ControlledVocabulary
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// CompetencyRequired represents required competencies
|
||||
type CompetencyRequired struct {
|
||||
ControlledVocabulary
|
||||
ControlledVocabulary
|
||||
}
|
||||
|
||||
// EducationalLevel represents the educational level
|
||||
|
|
@ -102,7 +102,7 @@ type InteractivityType struct {
|
|||
|
||||
// IsBasedOn represents a reference to source material
|
||||
type IsBasedOn struct {
|
||||
ID string `json:"id"`
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Creator *Creator `json:"creator,omitempty"`
|
||||
|
|
@ -135,6 +135,41 @@ type License struct {
|
|||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// MainEntityProvider represents the provider of a web page
|
||||
type MainEntityProvider struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// MainEntityOfPage represents meta-metadata about web pages
|
||||
type MainEntityOfPage struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
Provider *MainEntityProvider `json:"provider,omitempty"`
|
||||
DateCreated string `json:"dateCreated,omitempty"`
|
||||
DateModified string `json:"dateModified,omitempty"`
|
||||
}
|
||||
|
||||
// Encoding represents a media encoding (MediaObject)
|
||||
type Encoding struct {
|
||||
Type string `json:"type"`
|
||||
ContentUrl string `json:"contentUrl,omitempty"`
|
||||
EmbedUrl string `json:"embedUrl,omitempty"`
|
||||
EncodingFormat string `json:"encodingFormat,omitempty"`
|
||||
ContentSize string `json:"contentSize,omitempty"`
|
||||
Sha256 string `json:"sha256,omitempty"`
|
||||
Bitrate string `json:"bitrate,omitempty"`
|
||||
}
|
||||
|
||||
// Caption represents a caption/subtitle file (MediaObject)
|
||||
type Caption struct {
|
||||
ID string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
EncodingFormat string `json:"encodingFormat,omitempty"`
|
||||
InLanguage string `json:"inLanguage,omitempty"`
|
||||
}
|
||||
|
||||
// NostrMetadata contains Nostr-specific metadata
|
||||
type NostrMetadata struct {
|
||||
EventID string `json:"eventID"`
|
||||
|
|
@ -190,9 +225,12 @@ type AMBMetadata struct {
|
|||
HasPart []*HasPart `json:"hasPart,omitempty"`
|
||||
|
||||
// Technical
|
||||
Duration string `json:"duration,omitempty"`
|
||||
// TODO Encoding ``
|
||||
// TODO Caption
|
||||
Duration string `json:"duration,omitempty"`
|
||||
Encoding []*Encoding `json:"encoding,omitempty"`
|
||||
Caption []*Caption `json:"caption,omitempty"`
|
||||
|
||||
// Meta-Metadata
|
||||
MainEntityOfPage []*MainEntityOfPage `json:"mainEntityOfPage,omitempty"`
|
||||
|
||||
// Nostr integration
|
||||
NostrMetadata `json:",inline"`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue