diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28ee723d..f941c171 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,9 +84,9 @@ jobs: - uses: actions/checkout@v2 - uses: google-github-actions/setup-gcloud@master with: - project_id: ${{ secrets.GOOGLE_CLOUD_PROJECT }} - service_account_key: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} - export_default_credentials: true + project_id: ${{ secrets.GOOGLE_CLOUD_PROJECT }} + service_account_key: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} + export_default_credentials: true - name: Install Go uses: actions/setup-go@v2 with: @@ -124,7 +124,7 @@ jobs: gocov convert coverage.out > coverage.json gocov report coverage.json > coverage_report.txt tail coverage_report.txt - + - name: Install goveralls env: GO111MODULE: off diff --git a/go.mod b/go.mod index 69da5ea3..5f4e540d 100644 --- a/go.mod +++ b/go.mod @@ -38,13 +38,13 @@ require ( github.com/savannahghi/converterandformatter v0.0.9 github.com/savannahghi/enumutils v0.0.2 github.com/savannahghi/errorcodeutil v0.0.1 - github.com/savannahghi/feedlib v0.0.1 + github.com/savannahghi/feedlib v0.0.5 github.com/savannahghi/firebasetools v0.0.13 github.com/savannahghi/interserviceclient v0.0.13 github.com/savannahghi/profileutils v0.0.7 github.com/savannahghi/pubsubtools v0.0.2 github.com/savannahghi/scalarutils v0.0.2 // indirect - github.com/savannahghi/serverutils v0.0.3 + github.com/savannahghi/serverutils v0.0.4 github.com/segmentio/ksuid v1.0.4 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index 421a4b7f..7dc17e0b 100644 --- a/go.sum +++ b/go.sum @@ -388,8 +388,8 @@ github.com/savannahghi/enumutils v0.0.2/go.mod h1:DDdjQBO1qyf5BxLzhTs1uN91drCIHH github.com/savannahghi/errorcodeutil v0.0.1 h1:q5JYMrzXDAJ9/99fV7Mj2bFF1XOidlRgSlYHy73q2GA= github.com/savannahghi/errorcodeutil v0.0.1/go.mod h1:nNBaBjatvoRusnDr2aRoNr4Rpmz9Z779mjcL0tr/IXk= github.com/savannahghi/feedlib v0.0.0-20210628122532-ef88e353d4d6/go.mod h1:P6YHmWsa/TK/qTb2U1ryjuASotTQmbarArB0LYLjMo4= -github.com/savannahghi/feedlib v0.0.1 h1:BixXDyfj1Kj+f8AOwd32A/xXr5CZxrOqLitp09xDQcg= -github.com/savannahghi/feedlib v0.0.1/go.mod h1:P6YHmWsa/TK/qTb2U1ryjuASotTQmbarArB0LYLjMo4= +github.com/savannahghi/feedlib v0.0.5 h1:LQRLQoWCLFjCp4mkQncCNHJ/v9tg2D3yyzvSCnk3xRY= +github.com/savannahghi/feedlib v0.0.5/go.mod h1:PzEP7gw4w1Xuw36uIRr1H2ffd+kozWHyJCuGWO06AtQ= github.com/savannahghi/firebasetools v0.0.5/go.mod h1:obAxyBfPaGTx/g86LF19gSmmEh5x+Tbnziatk514mUQ= github.com/savannahghi/firebasetools v0.0.6/go.mod h1:obAxyBfPaGTx/g86LF19gSmmEh5x+Tbnziatk514mUQ= github.com/savannahghi/firebasetools v0.0.13 h1:2eBFwzsnmhRUzxfgQZxOjedlMuyef2dz4tvpw59pJkE= @@ -404,11 +404,10 @@ github.com/savannahghi/pubsubtools v0.0.2/go.mod h1:FQ+BxO4uA1ZkcziY4dR0uT9CKHVH github.com/savannahghi/scalarutils v0.0.0-20210622091443-bad5089abdad/go.mod h1:Z+Dl3wc3vy5zKvthctHAtYzol1p8w27zEVRfOYueoks= github.com/savannahghi/scalarutils v0.0.2 h1:naX6Zhv/tDbwKAKVY4bksyhnE43f2583xWesAKHb1CU= github.com/savannahghi/scalarutils v0.0.2/go.mod h1:Z+Dl3wc3vy5zKvthctHAtYzol1p8w27zEVRfOYueoks= -github.com/savannahghi/server_utils v0.0.1 h1:q6SL4BRvkpYJujXvWwCl4vU1U+VTzKRGfNXnl0H6tfw= github.com/savannahghi/server_utils v0.0.1/go.mod h1:Tldm4Op4ARxk8xaP3BA0V52XVZEJenkq0ck4FCdEp+I= github.com/savannahghi/serverutils v0.0.2/go.mod h1:sLX0El0i0DKN/9cUkB8xqm5cVMP79qCZvK60EzB7Pa4= -github.com/savannahghi/serverutils v0.0.3 h1:1gX/zD6tt4tAEpcQFyzXBUp70BvUiqmJpjADqjdvFwI= -github.com/savannahghi/serverutils v0.0.3/go.mod h1:3VCEJ8BTHf/DW3WFjLqV4SznzrXaul/As2RJ5eNOO7U= +github.com/savannahghi/serverutils v0.0.4 h1:mQGAwhNgS1NPSBXqCeyywuGQFnvRxiOmHJEHPgzhWQE= +github.com/savannahghi/serverutils v0.0.4/go.mod h1:3VCEJ8BTHf/DW3WFjLqV4SznzrXaul/As2RJ5eNOO7U= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= diff --git a/gqlgen.yml b/gqlgen.yml index 2547ff72..36934d36 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -11,7 +11,7 @@ exec: # model: # filename: pkg/engagement/domain/model/models_gen.go -# package: model +# package: model resolver: layout: follow-schema diff --git a/pkg/engagement/infrastructure/database/firestore/default_content.go b/pkg/engagement/infrastructure/database/firestore/default_content.go index 68541641..b90f667d 100644 --- a/pkg/engagement/infrastructure/database/firestore/default_content.go +++ b/pkg/engagement/infrastructure/database/firestore/default_content.go @@ -34,12 +34,23 @@ const ( partnerAccountSetupActionName = "PARTNER_ACCOUNT_SETUP" verifyEmailActionName = "VERIFY_EMAIL" - defaultOrg = "default-org-id-please-change" - defaultLocation = "default-location-id-please-change" - defaultContentDir = "/static/" - defaultAuthor = "Be.Well Team" - defaultInsuranceText = "Insurance Simplified" - onboardingService = "profile" + defaultOrg = "default-org-id-please-change" + defaultLocation = "default-location-id-please-change" + defaultContentDir = "/static/" + defaultAuthor = "Be.Well Team" + defaultInsuranceText = "Insurance Simplified" + onboardingService = "profile" + mp4Link1 = "https://a.bewell.co.ke/videos/what_you_can_do.mp4" + mp4Link2 = "https://a.bewell.co.ke/videos/how_to_add_cover.mp4" + youtubeLink1 = "https://youtu.be/-mlr9rjRXmc" + youtubeLink2 = "https://a.bewell.co.ke/videos/how_to_add_cover.mp4" + defaultTaglineorSummary = "See what you can do on your Be.Well app." + defaultText = "How to add your health insurance cover to your Be.Well app." + addCovertaglineorSummary = "Learn how to add your cover in 3 easy steps" + addCovertext = "View your health insurance cover benefits on your Be.Well app." + sladeTagline = "Learn what is Be.Well and how you can benefit from using it" + sladeSummary = "Be.Well is a virtual and physical healthcare community." + sladeText = "Be.Well is a virtual and physical healthcare community. Our goal is to make it easy for you to access affordable high-quality healthcare - whether online or in person." ) // embed default content assets (e.g images and documents) in the binary @@ -1198,7 +1209,7 @@ func getFeedWelcomeVideos(flavour feedlib.Flavour) []feedlib.Link { return videos } -func feedItemsFromCMSFeedTag(ctx context.Context, flavour feedlib.Flavour) []feedlib.Item { +func feedItemsFromCMSFeedTag(ctx context.Context, flavour feedlib.Flavour, playMP4 bool) []feedlib.Item { ctx, span := tracer.Start(ctx, "feedItemsFromCMSFeedTag") defer span.End() // Initialize ISC clients @@ -1227,15 +1238,103 @@ func feedItemsFromCMSFeedTag(ctx context.Context, flavour feedlib.Flavour) []fee text := "" sequenceNumber := int(time.Now().Unix()) - if videoLink.URL == "https://youtu.be/-mlr9rjRXmc" { - tagline = "See what you can do on your Be.Well app" - summary = "See what you can do on your Be.Well app" - text = "How to add your health insurance cover to your Be.Well app." + if playMP4 { + //Change urls MP4 videos + if videoLink.URL == mp4Link1 { + tagline = defaultTaglineorSummary + summary = defaultTaglineorSummary + text = defaultText + } + if videoLink.URL == mp4Link2 { + tagline = addCovertaglineorSummary + summary = addCovertaglineorSummary + text = addCovertext + sequenceNumber = int(time.Now().Unix()) + 1 + } + items = append(items, feedlib.Item{ + ID: ksuid.New().String(), + SequenceNumber: sequenceNumber, + Expiry: future, + Persistent: false, + Status: feedlib.StatusPending, + Visibility: feedlib.VisibilityShow, + Icon: feedlib.GetPNGImageLink(common.DefaultIconPath, "Icon", "Feed Item Icon", common.DefaultIconPath), + Author: defaultAuthor, + Tagline: tagline, + Label: common.DefaultLabel, + Summary: summary, + Timestamp: time.Now(), + Text: text, + TextType: feedlib.TextTypeHTML, + Links: []feedlib.Link{ + feedlib.GetMP4Link( + videoLink.URL, + videoLink.Title, + videoLink.Description, + videoLink.Thumbnail, + ), + }, + Actions: []feedlib.Action{}, + Conversations: []feedlib.Message{}, + Users: []string{}, + Groups: []string{}, + NotificationChannels: []feedlib.Channel{}, + }) + + for _, post := range feedPosts { + if post == nil { + // non fatal, intentionally + log.Printf("ERROR: nil CMS post when adding welcome posts to feed") + continue + } + items = append(items, feedItemFromCMSPost(*post)) + } + + // add the slade 360 video last + items = append(items, feedlib.Item{ + ID: ksuid.New().String(), + SequenceNumber: int(time.Now().Unix()), + Expiry: future, + Persistent: false, + Status: feedlib.StatusPending, + Visibility: feedlib.VisibilityShow, + Icon: feedlib.GetPNGImageLink(common.DefaultIconPath, "Icon", "Feed Item Icon", common.DefaultIconPath), + Author: defaultAuthor, + Tagline: sladeTagline, + Label: common.DefaultLabel, + Summary: sladeSummary, + Timestamp: time.Now(), + Text: sladeText, + TextType: feedlib.TextTypeHTML, + Links: []feedlib.Link{ + feedlib.GetMP4Link( + "healthcare_simplified.mp4 ", + "Slade 360", + "Slade 360. HealthCare. Simplified.", + common.StaticBase+"/items/videos/thumbs/04_slade.png", + ), + }, + Actions: []feedlib.Action{}, + Conversations: []feedlib.Message{}, + Users: []string{}, + Groups: []string{}, + NotificationChannels: []feedlib.Channel{}, + }) + + return items + + } + + // play youTube videos + if videoLink.URL == youtubeLink1 { + tagline = defaultTaglineorSummary + summary = defaultTaglineorSummary + text = defaultText } - if videoLink.URL == "https://youtu.be/-iSB8yrSIps" { - tagline = "Learn how to add your cover in 3 easy steps" - summary = "Learn how to add your cover in 3 easy steps" - text = "View your health insurance cover benefits on your Be.Well app." + if videoLink.URL == youtubeLink2 { + tagline = addCovertaglineorSummary + summary = addCovertaglineorSummary + text = addCovertext sequenceNumber = int(time.Now().Unix()) + 1 } @@ -1289,11 +1388,11 @@ func feedItemsFromCMSFeedTag(ctx context.Context, flavour feedlib.Flavour) []fee Visibility: feedlib.VisibilityShow, Icon: feedlib.GetPNGImageLink(common.DefaultIconPath, "Icon", "Feed Item Icon", common.DefaultIconPath), Author: defaultAuthor, - Tagline: "Learn what is Be.Well and how you can benefit from using it", + Tagline: sladeTagline, Label: common.DefaultLabel, - Summary: "Be.Well is a virtual and physical healthcare community.", + Summary: sladeSummary, Timestamp: time.Now(), - Text: "Be.Well is a virtual and physical healthcare community. Our goal is to make it easy for you to access affordable high-quality healthcare - whether online or in person.", + Text: sladeText, TextType: feedlib.TextTypeHTML, Links: []feedlib.Link{ feedlib.GetYoutubeVideoLink( diff --git a/pkg/engagement/infrastructure/database/firestore/firebase.go b/pkg/engagement/infrastructure/database/firestore/firebase.go index a0ef8eb4..bc35ba24 100644 --- a/pkg/engagement/infrastructure/database/firestore/firebase.go +++ b/pkg/engagement/infrastructure/database/firestore/firebase.go @@ -127,6 +127,7 @@ func (fr Repository) GetFeed( uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, @@ -201,6 +202,7 @@ func (fr Repository) GetFeed( uid, isAnonymous, flavour, + playMP4, persistent, status, visibility, @@ -214,7 +216,7 @@ func (fr Repository) GetFeed( Flavour: flavour, Actions: actions, Nudges: nudges, - Items: feedItemsFromCMSFeedTag(ctx, flavour), + Items: feedItemsFromCMSFeedTag(ctx, flavour,playMP4), IsAnonymous: isAnonymous, } diff --git a/pkg/engagement/infrastructure/database/firestore/firebase_test.go b/pkg/engagement/infrastructure/database/firestore/firebase_test.go index 6130a0e3..0d3d2825 100644 --- a/pkg/engagement/infrastructure/database/firestore/firebase_test.go +++ b/pkg/engagement/infrastructure/database/firestore/firebase_test.go @@ -154,6 +154,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { uid string isAnonymous bool flavour feedlib.Flavour + playMP4 bool persistent feedlib.BooleanFilter status *feedlib.Status visibility *feedlib.Visibility @@ -172,6 +173,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { uid: uid, isAnonymous: false, flavour: flavour, + playMP4: false, persistent: feedlib.BooleanFilterBoth, }, wantErr: false, @@ -183,6 +185,24 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { uid: uid, isAnonymous: false, flavour: flavour, + playMP4: false, + persistent: feedlib.BooleanFilterFalse, + status: &status, + visibility: &visibility, + expired: &expired, + filterParams: &helpers.FilterParams{ + Labels: []string{ksuid.New().String()}, + }, + }, + wantErr: false, + }, + { + name: "MP4 player set to true", + args: args{ + uid: uid, + isAnonymous: false, + flavour: flavour, + playMP4: true, persistent: feedlib.BooleanFilterFalse, status: &status, visibility: &visibility, @@ -201,6 +221,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, tt.args.persistent, tt.args.status, tt.args.visibility, @@ -244,6 +265,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, tt.args.persistent, tt.args.status, tt.args.visibility, @@ -281,6 +303,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterTrue, nil, nil, @@ -306,6 +329,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterFalse, nil, nil, @@ -331,6 +355,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, nil, nil, @@ -357,6 +382,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, nil, &show, @@ -383,6 +409,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, nil, &hide, @@ -412,6 +439,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, @@ -438,6 +466,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &done, &show, @@ -467,6 +496,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &inProgress, &show, @@ -496,6 +526,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, @@ -522,6 +553,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, @@ -548,6 +580,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, @@ -576,6 +609,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, @@ -603,6 +637,7 @@ func TestFirebaseRepository_GetFeed(t *testing.T) { &tt.args.uid, &tt.args.isAnonymous, tt.args.flavour, + tt.args.playMP4, feedlib.BooleanFilterBoth, &pending, &show, diff --git a/pkg/engagement/infrastructure/database/mock/repository_mock.go b/pkg/engagement/infrastructure/database/mock/repository_mock.go index 87ca47d7..f8bca310 100644 --- a/pkg/engagement/infrastructure/database/mock/repository_mock.go +++ b/pkg/engagement/infrastructure/database/mock/repository_mock.go @@ -18,6 +18,7 @@ type FakeEngagementRepository struct { uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, @@ -255,13 +256,14 @@ func (f *FakeEngagementRepository) GetFeed( uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams, ) (*domain.Feed, error) { - return f.GetFeedFn(ctx, uid, isAnonymous, flavour, persistent, status, visibility, expired, filterParams) + return f.GetFeedFn(ctx, uid, isAnonymous, flavour,playMP4, persistent, status, visibility, expired, filterParams) } // GetFeedItem ... diff --git a/pkg/engagement/infrastructure/database/service.go b/pkg/engagement/infrastructure/database/service.go index ee94c67b..ec3335a7 100644 --- a/pkg/engagement/infrastructure/database/service.go +++ b/pkg/engagement/infrastructure/database/service.go @@ -23,6 +23,7 @@ type Repository interface { uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, @@ -293,13 +294,14 @@ func (d *DbService) GetFeed( uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams, ) (*domain.Feed, error) { - return d.firestore.GetFeed(ctx, uid, isAnonymous, flavour, persistent, status, visibility, expired, filterParams) + return d.firestore.GetFeed(ctx, uid, isAnonymous, flavour, playMP4, persistent, status, visibility, expired, filterParams) } // GetFeedItem ... diff --git a/pkg/engagement/infrastructure/mock/infrastructure_mock.go b/pkg/engagement/infrastructure/mock/infrastructure_mock.go index 18d966b6..f388041e 100644 --- a/pkg/engagement/infrastructure/mock/infrastructure_mock.go +++ b/pkg/engagement/infrastructure/mock/infrastructure_mock.go @@ -22,6 +22,7 @@ type FakeInfrastructure struct { uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, @@ -473,13 +474,14 @@ func (f *FakeInfrastructure) GetFeed( uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams, ) (*domain.Feed, error) { - return f.GetFeedFn(ctx, uid, isAnonymous, flavour, persistent, status, visibility, expired, filterParams) + return f.GetFeedFn(ctx, uid, isAnonymous, flavour, playMP4, persistent, status, visibility, expired, filterParams) } // GetFeedItem ... diff --git a/pkg/engagement/presentation/graph/feed.graphql b/pkg/engagement/presentation/graph/feed.graphql index 91797497..e7bc6ee4 100644 --- a/pkg/engagement/presentation/graph/feed.graphql +++ b/pkg/engagement/presentation/graph/feed.graphql @@ -211,6 +211,7 @@ input FilterParamsInput { extend type Query { getFeed( flavour: Flavour! + playMP4: Boolean! isAnonymous: Boolean! persistent: BooleanFilter! status: Status diff --git a/pkg/engagement/presentation/graph/feed.resolvers.go b/pkg/engagement/presentation/graph/feed.resolvers.go index 227cd924..8a21709b 100644 --- a/pkg/engagement/presentation/graph/feed.resolvers.go +++ b/pkg/engagement/presentation/graph/feed.resolvers.go @@ -201,7 +201,7 @@ func (r *mutationResolver) ProcessEvent(ctx context.Context, flavour feedlib.Fla return true, nil } -func (r *queryResolver) GetFeed(ctx context.Context, flavour feedlib.Flavour, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) (*domain.Feed, error) { +func (r *queryResolver) GetFeed(ctx context.Context, flavour feedlib.Flavour, playMp4 bool, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) (*domain.Feed, error) { startTime := time.Now() uid, err := r.getLoggedInUserUID(ctx) @@ -213,6 +213,7 @@ func (r *queryResolver) GetFeed(ctx context.Context, flavour feedlib.Flavour, is &uid, &isAnonymous, flavour, + playMp4, persistent, status, visibility, diff --git a/pkg/engagement/presentation/graph/generated/generated.go b/pkg/engagement/presentation/graph/generated/generated.go index b836358b..f8d2b20f 100644 --- a/pkg/engagement/presentation/graph/generated/generated.go +++ b/pkg/engagement/presentation/graph/generated/generated.go @@ -340,7 +340,7 @@ type ComplexityRoot struct { GenerateOtp func(childComplexity int, msisdn string, appID *string) int GenerateRetryOtp func(childComplexity int, msisdn string, retryStep int, appID *string) int GetFaqsContent func(childComplexity int, flavour feedlib.Flavour) int - GetFeed func(childComplexity int, flavour feedlib.Flavour, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) int + GetFeed func(childComplexity int, flavour feedlib.Flavour, playMp4 bool, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) int GetLibraryContent func(childComplexity int) int Labels func(childComplexity int, flavour feedlib.Flavour) int ListNPSResponse func(childComplexity int) int @@ -416,7 +416,7 @@ type QueryResolver interface { GetLibraryContent(ctx context.Context) ([]*domain.GhostCMSPost, error) GetFaqsContent(ctx context.Context, flavour feedlib.Flavour) ([]*domain.GhostCMSPost, error) Notifications(ctx context.Context, registrationToken string, newerThan time.Time, limit int) ([]*dto.SavedNotification, error) - GetFeed(ctx context.Context, flavour feedlib.Flavour, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) (*domain.Feed, error) + GetFeed(ctx context.Context, flavour feedlib.Flavour, playMp4 bool, isAnonymous bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, expired *feedlib.BooleanFilter, filterParams *helpers.FilterParams) (*domain.Feed, error) Labels(ctx context.Context, flavour feedlib.Flavour) ([]string, error) UnreadPersistentItems(ctx context.Context, flavour feedlib.Flavour) (int, error) GenerateOtp(ctx context.Context, msisdn string, appID *string) (string, error) @@ -2065,7 +2065,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return 0, false } - return e.complexity.Query.GetFeed(childComplexity, args["flavour"].(feedlib.Flavour), args["isAnonymous"].(bool), args["persistent"].(feedlib.BooleanFilter), args["status"].(*feedlib.Status), args["visibility"].(*feedlib.Visibility), args["expired"].(*feedlib.BooleanFilter), args["filterParams"].(*helpers.FilterParams)), true + return e.complexity.Query.GetFeed(childComplexity, args["flavour"].(feedlib.Flavour), args["playMP4"].(bool), args["isAnonymous"].(bool), args["persistent"].(feedlib.BooleanFilter), args["status"].(*feedlib.Status), args["visibility"].(*feedlib.Visibility), args["expired"].(*feedlib.BooleanFilter), args["filterParams"].(*helpers.FilterParams)), true case "Query.getLibraryContent": if e.complexity.Query.GetLibraryContent == nil { @@ -2682,6 +2682,7 @@ input FilterParamsInput { extend type Query { getFeed( flavour: Flavour! + playMP4: Boolean! isAnonymous: Boolean! persistent: BooleanFilter! status: Status @@ -3732,59 +3733,68 @@ func (ec *executionContext) field_Query_getFeed_args(ctx context.Context, rawArg } args["flavour"] = arg0 var arg1 bool + if tmp, ok := rawArgs["playMP4"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("playMP4")) + arg1, err = ec.unmarshalNBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["playMP4"] = arg1 + var arg2 bool if tmp, ok := rawArgs["isAnonymous"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("isAnonymous")) - arg1, err = ec.unmarshalNBoolean2bool(ctx, tmp) + arg2, err = ec.unmarshalNBoolean2bool(ctx, tmp) if err != nil { return nil, err } } - args["isAnonymous"] = arg1 - var arg2 feedlib.BooleanFilter + args["isAnonymous"] = arg2 + var arg3 feedlib.BooleanFilter if tmp, ok := rawArgs["persistent"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("persistent")) - arg2, err = ec.unmarshalNBooleanFilter2githubᚗcomᚋsavannahghiᚋfeedlibᚐBooleanFilter(ctx, tmp) + arg3, err = ec.unmarshalNBooleanFilter2githubᚗcomᚋsavannahghiᚋfeedlibᚐBooleanFilter(ctx, tmp) if err != nil { return nil, err } } - args["persistent"] = arg2 - var arg3 *feedlib.Status + args["persistent"] = arg3 + var arg4 *feedlib.Status if tmp, ok := rawArgs["status"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("status")) - arg3, err = ec.unmarshalOStatus2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐStatus(ctx, tmp) + arg4, err = ec.unmarshalOStatus2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐStatus(ctx, tmp) if err != nil { return nil, err } } - args["status"] = arg3 - var arg4 *feedlib.Visibility + args["status"] = arg4 + var arg5 *feedlib.Visibility if tmp, ok := rawArgs["visibility"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("visibility")) - arg4, err = ec.unmarshalOVisibility2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐVisibility(ctx, tmp) + arg5, err = ec.unmarshalOVisibility2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐVisibility(ctx, tmp) if err != nil { return nil, err } } - args["visibility"] = arg4 - var arg5 *feedlib.BooleanFilter + args["visibility"] = arg5 + var arg6 *feedlib.BooleanFilter if tmp, ok := rawArgs["expired"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("expired")) - arg5, err = ec.unmarshalOBooleanFilter2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐBooleanFilter(ctx, tmp) + arg6, err = ec.unmarshalOBooleanFilter2ᚖgithubᚗcomᚋsavannahghiᚋfeedlibᚐBooleanFilter(ctx, tmp) if err != nil { return nil, err } } - args["expired"] = arg5 - var arg6 *helpers.FilterParams + args["expired"] = arg6 + var arg7 *helpers.FilterParams if tmp, ok := rawArgs["filterParams"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filterParams")) - arg6, err = ec.unmarshalOFilterParamsInput2ᚖgithubᚗcomᚋsavannahghiᚋengagementcoreᚋpkgᚋengagementᚋapplicationᚋcommonᚋhelpersᚐFilterParams(ctx, tmp) + arg7, err = ec.unmarshalOFilterParamsInput2ᚖgithubᚗcomᚋsavannahghiᚋengagementcoreᚋpkgᚋengagementᚋapplicationᚋcommonᚋhelpersᚐFilterParams(ctx, tmp) if err != nil { return nil, err } } - args["filterParams"] = arg6 + args["filterParams"] = arg7 return args, nil } @@ -11238,7 +11248,7 @@ func (ec *executionContext) _Query_getFeed(ctx context.Context, field graphql.Co fc.Args = args resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().GetFeed(rctx, args["flavour"].(feedlib.Flavour), args["isAnonymous"].(bool), args["persistent"].(feedlib.BooleanFilter), args["status"].(*feedlib.Status), args["visibility"].(*feedlib.Visibility), args["expired"].(*feedlib.BooleanFilter), args["filterParams"].(*helpers.FilterParams)) + return ec.resolvers.Query().GetFeed(rctx, args["flavour"].(feedlib.Flavour), args["playMP4"].(bool), args["isAnonymous"].(bool), args["persistent"].(feedlib.BooleanFilter), args["status"].(*feedlib.Status), args["visibility"].(*feedlib.Visibility), args["expired"].(*feedlib.BooleanFilter), args["filterParams"].(*helpers.FilterParams)) }) if err != nil { ec.Error(ctx, err) diff --git a/pkg/engagement/presentation/rest/handler_helpers.go b/pkg/engagement/presentation/rest/handler_helpers.go index 9a5d302a..4c0b311a 100644 --- a/pkg/engagement/presentation/rest/handler_helpers.go +++ b/pkg/engagement/presentation/rest/handler_helpers.go @@ -153,7 +153,17 @@ func patchNudge( respondWithJSON(w, http.StatusOK, marshalled) } +func getplayMP4QueryParam(r *http.Request, paramName string) (bool, error) { + if r == nil { + return false, fmt.Errorf("can't get string var from a nil request") + } + val := r.FormValue(paramName) + if val == "true" { + return true, nil + } + return false, nil +} func getOptionalBooleanFilterQueryParam( r *http.Request, paramName string, diff --git a/pkg/engagement/presentation/rest/handler_helpers_test.go b/pkg/engagement/presentation/rest/handler_helpers_test.go new file mode 100644 index 00000000..45f0b99b --- /dev/null +++ b/pkg/engagement/presentation/rest/handler_helpers_test.go @@ -0,0 +1,295 @@ +package rest + +import ( + "net/http" + "testing" +) + +func Test_getplayMP4QueryParam(t *testing.T) { + + type args struct { + r *http.Request + } + r, err := http.NewRequest(http.MethodGet, + "localhost/feed/?persistent=BOTH&playMP4=false", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + r2, err := http.NewRequest(http.MethodGet, + "localhost/feed/?persistent=BOTH&playMP4=true", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: " happy: getplayMP4param success", + args: args{ + r: r, + }, + + wantErr: false, + }, + { + name: " happy: getplayMP4param success", + args: args{ + r: r2, + }, + + wantErr: false, + }, + { + name: "sad: getplayMP4param failed", + args: args{ + r: nil, + }, + + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := getplayMP4QueryParam(tt.args.r, "playMP4") + if (err != nil) != tt.wantErr { + t.Errorf("getplayMP4QueryParam() error = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} + +func Test_getOptionalVisibilityQueryParam(t *testing.T) { + + type args struct { + r *http.Request + } + r, err := http.NewRequest(http.MethodGet, + "localhost/feed/?visibility=HIDE&playMP4=false", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + r2, err := http.NewRequest(http.MethodGet, + "localhost/feed/?visibility=SHOW&playMP4=true", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: " happy: getOptionalVisibilityQueryParam success", + args: args{ + r: r, + }, + + wantErr: false, + }, + { + name: " happy: getOptionalVisibilityQueryParam success", + args: args{ + r: r2, + }, + + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := getOptionalVisibilityQueryParam(tt.args.r, "visibility") + if (err != nil) != tt.wantErr { + t.Errorf("getOptionalVisibilityQueryParam error = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} + +func Test_getStringVar(t *testing.T) { + + type args struct { + r *http.Request + value string + } + r, err := http.NewRequest(http.MethodGet, + "/feed/nudges/{nudgeID}/unresolve/", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: " sad: getStringVar failed", + args: args{ + r: r, + value: "visibility", + }, + + wantErr: true, + }, + { + name: " sad: getStringVar failed", + args: args{ + r: r, + value: "expired", + }, + + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := getStringVar(tt.args.r, tt.args.value) + if (err != nil) != tt.wantErr { + t.Errorf("getStringVarerror = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} + +func Test_getRequiredBooleanFilterQueryParam(t *testing.T) { + + type args struct { + r *http.Request + value string + } + r, err := http.NewRequest(http.MethodGet, + "localhost/feed/?persistent=BOTH&playMP4=true", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + r2, err := http.NewRequest(http.MethodGet, + "localhost/feed/?persistent=ANY&playMP4=true", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: " happy: getRequiredBooleanFilterQueryParam", + args: args{ + r: r, + value: "persistent", + }, + + wantErr: false, + }, + { + name: " sad: getRequiredBooleanFilterQueryParam failed", + args: args{ + r: r, + value: "expired", + }, + + wantErr: true, + }, + { + name: " sad: getRequiredBooleanFilterQueryParam failed", + args: args{ + r: r2, + value: "persistent", + }, + + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := getRequiredBooleanFilterQueryParam(tt.args.r, tt.args.value) + if (err != nil) != tt.wantErr { + t.Errorf("getStringVarerror = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} + +func Test_getOptionalStatusQueryParam(t *testing.T) { + + type args struct { + r *http.Request + value string + } + r, err := http.NewRequest(http.MethodGet, + "localhost/feed/?persistent=BOTH&playMP4=true", nil) + if err != nil { + t.Errorf("error in the request %v", err) + return + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: " happy: getOptionalStatusQueryParam", + args: args{ + r: r, + value: "persistent", + }, + + wantErr: false, + }, + { + name: " happy: getOptionalStatusQueryParam passed", + args: args{ + r: r, + value: "expired", + }, + + wantErr: false, + }, + { + name: " sad: getOptionalStatusQueryParam failed", + args: args{ + r: nil, + value: "persistent", + }, + + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := getOptionalStatusQueryParam(tt.args.r, tt.args.value) + if (err != nil) != tt.wantErr { + t.Errorf("getOptionalStatusQueryParam = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} diff --git a/pkg/engagement/presentation/rest/handlers.go b/pkg/engagement/presentation/rest/handlers.go index 4cc3e4d3..0ed5902b 100644 --- a/pkg/engagement/presentation/rest/handlers.go +++ b/pkg/engagement/presentation/rest/handlers.go @@ -445,6 +445,12 @@ func (p PresentationHandlersImpl) GetFeed() http.HandlerFunc { return } + playMP4, err := getplayMP4QueryParam(r, "playMP4") + if err != nil { + respondWithError(w, http.StatusBadRequest, err) + return + } + filterParams, err := getOptionalFilterParamsQueryParam( r, "filterParams", @@ -459,6 +465,7 @@ func (p PresentationHandlersImpl) GetFeed() http.HandlerFunc { uid, anonymous, *flavour, + playMP4, persistent, status, visibility, @@ -469,13 +476,14 @@ func (p PresentationHandlersImpl) GetFeed() http.HandlerFunc { respondWithError(w, http.StatusInternalServerError, err) return } - marshalled, err := feed.ValidateAndMarshal() + bs, err := json.Marshal(feed) + if err != nil { respondWithError(w, http.StatusInternalServerError, err) return } - respondWithJSON(w, http.StatusOK, marshalled) + respondWithJSON(w, http.StatusOK, bs) } } diff --git a/pkg/engagement/presentation/rest/handlers_test.go b/pkg/engagement/presentation/rest/handlers_test.go index eac594ff..8801882d 100644 --- a/pkg/engagement/presentation/rest/handlers_test.go +++ b/pkg/engagement/presentation/rest/handlers_test.go @@ -672,7 +672,7 @@ func TestGetFeed(t *testing.T) { name: "successful fetch of a consumer feed", args: args{ url: fmt.Sprintf( - "%s/feed/%s/%s/%v/?persistent=BOTH", + "%s/feed/%s/%s/%v/?persistent=BOTH&playMP4=false", baseURL, uid, consumer, @@ -689,7 +689,7 @@ func TestGetFeed(t *testing.T) { name: "fetch with a status filter", args: args{ url: fmt.Sprintf( - "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING", + "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&playMP4=true", baseURL, uid, consumer, @@ -705,7 +705,7 @@ func TestGetFeed(t *testing.T) { name: "fetch with a visibility filter", args: args{ url: fmt.Sprintf( - "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&visibility=SHOW", + "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&visibility=SHOW&playMP4=true", baseURL, uid, consumer, @@ -721,7 +721,7 @@ func TestGetFeed(t *testing.T) { name: "fetch with an expired filter", args: args{ url: fmt.Sprintf( - "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&visibility=SHOW&expired=FALSE", + "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&visibility=SHOW&expired=FALSE&playMP4=true", baseURL, uid, consumer, @@ -737,7 +737,7 @@ func TestGetFeed(t *testing.T) { name: "fetch with an expired filter", args: args{ url: fmt.Sprintf( - "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&visibility=SHOW&expired=FALSE&filterParams=%s", + "%s/feed/%s/%s/%v/?persistent=BOTH&status=PENDING&playMP4=true&visibility=SHOW&expired=FALSE&filterParams=%s", baseURL, uid, consumer, @@ -807,7 +807,7 @@ func TestGetFeed(t *testing.T) { data, err := ioutil.ReadAll(resp.Body) if err != nil { - t.Errorf("can't read response body: %v", err) + t.Errorf("cannot read response body: %v", err) return } @@ -6034,7 +6034,7 @@ func TestPresentationHandlersImpl_UpdateMailgunDelivery(t *testing.T) { } if resp.StatusCode != tt.wantStatus { - t.Errorf("expected status %d, got %s", tt.wantStatus, resp.Status) + t.Errorf("expected status %d, got status %s", tt.wantStatus, resp.Status) return } }) diff --git a/pkg/engagement/repository/repository.go b/pkg/engagement/repository/repository.go index abf6a70d..8a12488b 100644 --- a/pkg/engagement/repository/repository.go +++ b/pkg/engagement/repository/repository.go @@ -21,6 +21,7 @@ type Repository interface { uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, diff --git a/pkg/engagement/usecases/fcm/fcm.go b/pkg/engagement/usecases/fcm/fcm.go index 9c5dbdc2..ef2c2049 100644 --- a/pkg/engagement/usecases/fcm/fcm.go +++ b/pkg/engagement/usecases/fcm/fcm.go @@ -74,7 +74,7 @@ func (f *ImplFCM) SendNotification( ) } -// Notifications gets notifications with the defined limit and set date +// Notifications fetches notifications with the defined limit and set date func (f *ImplFCM) Notifications( ctx context.Context, registrationToken string, diff --git a/pkg/engagement/usecases/feed/feed.go b/pkg/engagement/usecases/feed/feed.go index ead80d0f..7541968e 100644 --- a/pkg/engagement/usecases/feed/feed.go +++ b/pkg/engagement/usecases/feed/feed.go @@ -252,6 +252,7 @@ func (fe UseCaseImpl) GetFeed( uid *string, isAnonymous *bool, flavour feedlib.Flavour, + playMP4 bool, persistent feedlib.BooleanFilter, status *feedlib.Status, visibility *feedlib.Visibility, @@ -266,6 +267,7 @@ func (fe UseCaseImpl) GetFeed( uid, isAnonymous, flavour, + playMP4, persistent, status, visibility, diff --git a/tests/library_acceptance_test.go b/tests/library_acceptance_test.go index 2d1181d6..9075f7ae 100644 --- a/tests/library_acceptance_test.go +++ b/tests/library_acceptance_test.go @@ -22,12 +22,12 @@ func TestGraphQLGetFeed(t *testing.T) { headers := getGraphQLHeaders(t) gql := map[string]interface{}{} gql["query"] = ` - query getFeed($flavour: Flavour!,$isAnonymous: Boolean!, + query getFeed($flavour: Flavour!,$isAnonymous: Boolean!,$playMP4:Boolean!, $persistent: BooleanFilter!, $status: Status, $visibility: Visibility, $expired: BooleanFilter){ - getFeed(flavour:$flavour,isAnonymous:$isAnonymous, + getFeed(flavour:$flavour,playMP4:$playMP4, isAnonymous:$isAnonymous, persistent:$persistent, status:$status, visibility:$visibility, expired:$expired ){ id @@ -114,6 +114,7 @@ func TestGraphQLGetFeed(t *testing.T) { gql["variables"] = map[string]interface{}{ "flavour": "CONSUMER", + "playMP4": true, "isAnonymous": false, "persistent": "BOTH", "status": "PENDING",