Skip to content

Commit

Permalink
Fix/uppsf 5230 fix unrolling live blog packages in content unroller (#40
Browse files Browse the repository at this point in the history
)

* Made article unroller default

* Renamed Article and Internal Article unrollers to Default and Default internal

* Added content package test
  • Loading branch information
ilian2233 committed Apr 16, 2024
1 parent a50f7b5 commit 7adfe0c
Show file tree
Hide file tree
Showing 15 changed files with 908 additions and 69 deletions.
4 changes: 3 additions & 1 deletion content/clip_unroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ func TestClipUnroller_Unroll(t *testing.T) {
typeField: "wrong",
},
},
want: nil,
want: Content{
typeField: "wrong",
},
wantErr: assert.Error,
},
{
Expand Down
2 changes: 1 addition & 1 deletion content/clipset_unroller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestClipsetUnroller_Unroll(t *testing.T) {
tid: testTID,
uuid: testUUID,
},
want: nil,
want: invalidClipset,
wantErr: assert.Error,
},
{
Expand Down
28 changes: 14 additions & 14 deletions content/article_unroller.go → content/default_unroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ import (
"github.com/Financial-Times/go-logger/v2"
)

type ArticleUnroller struct {
type DefaultUnroller struct {
reader Reader
log *logger.UPPLogger
apiHost string
}

func NewArticleUnroller(r Reader, log *logger.UPPLogger, apiHost string) *ArticleUnroller {
return &ArticleUnroller{
func NewDefaultUnroller(r Reader, log *logger.UPPLogger, apiHost string) *DefaultUnroller {
return &DefaultUnroller{
reader: r,
log: log,
apiHost: apiHost,
}
}

func (u *ArticleUnroller) Unroll(req UnrollEvent) (Content, error) {
if !validateArticle(req.c) {
func (u *DefaultUnroller) Unroll(req UnrollEvent) (Content, error) {
if !validateDefaultContent(req.c) {
return req.c, ErrValidating
}

Expand Down Expand Up @@ -64,7 +64,7 @@ func (u *ArticleUnroller) Unroll(req UnrollEvent) (Content, error) {
return cc, nil
}

func (u *ArticleUnroller) createContentSchema(cc Content, acceptedTypes []string, tid string, uuid string) Schema {
func (u *DefaultUnroller) createContentSchema(cc Content, acceptedTypes []string, tid string, uuid string) Schema {
schema := make(Schema)

localLog := u.log.WithUUID(uuid).WithTransactionID(tid)
Expand Down Expand Up @@ -113,15 +113,15 @@ func (u *ArticleUnroller) createContentSchema(cc Content, acceptedTypes []string
return schema
}

func (u *ArticleUnroller) resolveModelsForSetsMembers(b Schema, imgMap map[string]Content, tid string, uuid string) {
func (u *DefaultUnroller) resolveModelsForSetsMembers(b Schema, imgMap map[string]Content, tid string, uuid string) {
mainImageUUID := b.get(mainImageField)
u.resolveImageSet(mainImageUUID, imgMap, tid, uuid)
for _, embeddedImgSet := range b.getAll(embeds) {
u.resolveImageSet(embeddedImgSet, imgMap, tid, uuid)
}
}

func (u *ArticleUnroller) resolveImageSet(imageSetUUID string, imgMap map[string]Content, tid string, uuid string) {
func (u *DefaultUnroller) resolveImageSet(imageSetUUID string, imgMap map[string]Content, tid string, uuid string) {
imageSet, found := resolveContent(imageSetUUID, imgMap)
if !found {
imgMap[imageSetUUID] = Content{id: createID(u.apiHost, "content", imageSetUUID)}
Expand Down Expand Up @@ -166,7 +166,7 @@ func (u *ArticleUnroller) resolveImageSet(imageSetUUID string, imgMap map[string
}
}

func (u *ArticleUnroller) resolvePoster(poster interface{}, tid, uuid string) (Content, error) {
func (u *DefaultUnroller) resolvePoster(poster interface{}, tid, uuid string) (Content, error) {
posterData, found := poster.(map[string]interface{})
if !found {
return Content{}, errors.New("problem in poster field")
Expand All @@ -184,10 +184,10 @@ func (u *ArticleUnroller) resolvePoster(poster interface{}, tid, uuid string) (C
return posterContent[pUUID], nil
}

func validateArticle(article Content) bool {
_, hasMainImage := article[mainImageField]
_, hasBody := article[bodyXMLField]
_, hasAltImg := article[altImagesField].(map[string]interface{})
func validateDefaultContent(content Content) bool {
_, hasMainImage := content[mainImageField]
_, hasBody := content[bodyXMLField]
_, hasAltImg := content[altImagesField].(map[string]interface{})

return (hasMainImage || hasBody || hasAltImg) && checkType(article, ArticleType)
return hasMainImage || hasBody || hasAltImg
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestUnrollContent(t *testing.T) {
cu := ArticleUnroller{
cu := DefaultUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-content-valid-response.json")
Expand Down Expand Up @@ -44,7 +44,7 @@ func TestUnrollContent(t *testing.T) {
}

func TestUnrollContent_NilSchema(t *testing.T) {
cu := ArticleUnroller{reader: nil}
cu := DefaultUnroller{reader: nil}
var c Content
err := json.Unmarshal([]byte(InvalidBodyRequest), &c)
assert.NoError(t, err, "Cannot build json body")
Expand All @@ -58,7 +58,7 @@ func TestUnrollContent_NilSchema(t *testing.T) {
}

func TestUnrollContent_ErrorExpandingFromContentStore(t *testing.T) {
cu := ArticleUnroller{
cu := DefaultUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
return nil, errors.New("Cannot expand content from content store")
Expand Down Expand Up @@ -89,7 +89,7 @@ func TestUnrollContent_SkipPromotionalImageWhenIdIsMissing(t *testing.T) {
},
}

cu := ArticleUnroller{
cu := DefaultUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-content-valid-response.json")
Expand Down Expand Up @@ -123,7 +123,7 @@ func TestUnrollContent_SkipPromotionalImageWhenUUIDIsInvalid(t *testing.T) {
},
}

cu := ArticleUnroller{
cu := DefaultUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-content-valid-response.json")
Expand Down Expand Up @@ -151,7 +151,7 @@ func TestUnrollContent_SkipPromotionalImageWhenUUIDIsInvalid(t *testing.T) {
}

func TestUnrollContent_EmbeddedContentSkippedWhenMissingBodyXML(t *testing.T) {
cu := ArticleUnroller{
cu := DefaultUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-content-valid-response-no-body.json")
Expand Down
35 changes: 0 additions & 35 deletions content/internal_article_unroller.go

This file was deleted.

35 changes: 35 additions & 0 deletions content/internal_default_unroller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package content

import "github.com/Financial-Times/go-logger/v2"

type DefaultInternalUnroller DefaultUnroller

func NewDefaultInternalUnroller(r Reader, log *logger.UPPLogger, apiHost string) *DefaultInternalUnroller {
return (*DefaultInternalUnroller)(NewDefaultUnroller(r, log, apiHost))
}

func (u *DefaultInternalUnroller) Unroll(req UnrollEvent) (Content, error) {
if !validateInternalDefaultContent(req.c) {
return req.c, ErrValidating
}

cc := req.c.clone()
expLeadImages, foundImages := unrollLeadImages(cc, u.reader, u.log, req.tid, req.uuid)
if foundImages {
cc[leadImages] = expLeadImages
}

dynContents, foundDyn := unrollDynamicContent(cc, u.log, req.tid, req.uuid, u.reader.GetInternal)
if foundDyn {
cc[embeds] = dynContents
}

return cc, nil
}

func validateInternalDefaultContent(content Content) bool {
_, hasLeadImages := content[leadImages]
_, hasBody := content[bodyXMLField]

return hasLeadImages || hasBody
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestUnrollInternalContent(t *testing.T) {
cu := InternalArticleUnroller{
cu := DefaultInternalUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-internalcontent-valid-response.json")
Expand Down Expand Up @@ -53,7 +53,7 @@ func TestUnrollInternalContent(t *testing.T) {
}

func TestUnrollInternalContent_LeadImagesSkippedWhenReadingError(t *testing.T) {
cu := InternalArticleUnroller{
cu := DefaultInternalUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
return nil, errors.New("Error retrieving content")
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestUnrollInternalContent_LeadImagesSkippedWhenReadingError(t *testing.T) {
}

func TestUnrollInternalContent_DynamicContentSkippedWhenReadingError(t *testing.T) {
cu := InternalArticleUnroller{
cu := DefaultInternalUnroller{
reader: &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-internalcontent-valid-response.json")
Expand Down
13 changes: 4 additions & 9 deletions content/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package content

import (
"errors"
"fmt"
"slices"

"github.com/Financial-Times/go-logger/v2"
Expand Down Expand Up @@ -50,30 +49,26 @@ func NewUniversalUnroller(r Reader, log *logger.UPPLogger, apiHost string) *Univ
}

func (u *UniversalUnroller) UnrollContent(event UnrollEvent) (Content, error) {
articleUnroller := NewArticleUnroller(u.reader, u.log, u.apiHost)
defaultUnroller := NewDefaultUnroller(u.reader, u.log, u.apiHost)

switch getEventType(event.c) {
case ArticleType:
return articleUnroller.Unroll(event)
case ClipSetType:
return u.unrollClipSet(event)
case ClipType:
return u.unrollClip(event)
case ImageSetType:
return u.unrollImageSet(event)
default:
return nil, errors.Join(ErrValidating, fmt.Errorf("unsupported content type %s", getEventType(event.c)))
return defaultUnroller.Unroll(event)
}
}

func (u *UniversalUnroller) UnrollInternalContent(event UnrollEvent) (Content, error) {
articleUnroller := NewInternalArticleUnroller(u.reader, u.log, u.apiHost)
defaultInternalUnroller := NewDefaultInternalUnroller(u.reader, u.log, u.apiHost)

switch getEventType(event.c) {
case ArticleType:
return articleUnroller.Unroll(event)
default:
return nil, errors.Join(ErrValidating, fmt.Errorf("unsupported content type %s", getEventType(event.c)))
return defaultInternalUnroller.Unroll(event)
}
}

Expand Down
71 changes: 71 additions & 0 deletions content/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"testing"

"github.com/Financial-Times/go-logger/v2"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -164,3 +165,73 @@ func Test_getEventType(t *testing.T) {
})
}
}

func TestUnrollContent_LiveBlogPackage(t *testing.T) {
testReader := &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-content-liveblogpackage-valid-response.json")
assert.NoError(t, err, "Cannot open file necessary for test case")
var res map[string]Content
err = json.Unmarshal(b, &res)
assert.NoError(t, err, "Cannot return valid response")
return res, nil
},
}
defaultAPIHost := "test.api.ft.com"
unroller := UniversalUnroller{
reader: testReader,
log: logger.NewUPPLogger("test", "debug"),
apiHost: defaultAPIHost,
}

expected, err := os.ReadFile("testdata/content-liveblogpackage-valid-response.json")
assert.NoError(t, err, "Cannot read necessary test file")

var c Content
fileBytes, err := os.ReadFile("testdata/content-liveblogpackage-valid-request.json")
assert.NoError(t, err, "Cannot read necessary test file")
err = json.Unmarshal(fileBytes, &c)
assert.NoError(t, err, "Cannot build json body")
req := UnrollEvent{c, "tid_sample", "sample_uuid"}
actual, err := unroller.UnrollContent(req)
assert.NoError(t, err, "Should not get an error when expanding clipset")

actualJSON, err := json.Marshal(actual)
assert.NoError(t, err, "Expected to marshall correctly")
assert.JSONEq(t, string(expected), string(actualJSON))
}

func TestUnrollContent_ContentPackage(t *testing.T) {
testReader := &ReaderMock{
mockGet: func(_ []string, _ string) (map[string]Content, error) {
b, err := os.ReadFile("testdata/reader-internalcontent-contentpackage-valid-response.json")
assert.NoError(t, err, "Cannot open file necessary for test case")
var res map[string]Content
err = json.Unmarshal(b, &res)
assert.NoError(t, err, "Cannot return valid response")
return res, nil
},
}
defaultAPIHost := "test.api.ft.com"
unroller := UniversalUnroller{
reader: testReader,
log: logger.NewUPPLogger("test", "debug"),
apiHost: defaultAPIHost,
}

expected, err := os.ReadFile("testdata/internalcontent-contentpackage-valid-response.json")
assert.NoError(t, err, "Cannot read necessary test file")

var c Content
fileBytes, err := os.ReadFile("testdata/internalcontent-contentpackage-valid-request.json")
assert.NoError(t, err, "Cannot read necessary test file")
err = json.Unmarshal(fileBytes, &c)
assert.NoError(t, err, "Cannot build json body")
req := UnrollEvent{c, "tid_sample", "sample_uuid"}
actual, err := unroller.UnrollInternalContent(req)
assert.NoError(t, err, "Should not get an error when expanding clipset")

actualJSON, err := json.Marshal(actual)
assert.NoError(t, err, "Expected to marshall correctly")
assert.JSONEq(t, string(expected), string(actualJSON))
}
Loading

0 comments on commit 7adfe0c

Please sign in to comment.