@@ -67,7 +67,7 @@ func main() {
|
|||||||
|
|
||||||
// Initialize services
|
// Initialize services
|
||||||
humanSvc := human.NewService(db.Pool())
|
humanSvc := human.NewService(db.Pool())
|
||||||
networkSvc := network.NewService(db.Pool())
|
networkSvc := network.NewService(db.Pool(), aeroSvc)
|
||||||
|
|
||||||
slog.Info("starting email notification cycle")
|
slog.Info("starting email notification cycle")
|
||||||
if err := runNotificationCycle(ctx, firestoreClient, aeroSvc, pusherSvc, humanSvc, networkSvc); err != nil {
|
if err := runNotificationCycle(ctx, firestoreClient, aeroSvc, pusherSvc, humanSvc, networkSvc); err != nil {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ func main() {
|
|||||||
// Initialize services
|
// Initialize services
|
||||||
authSvc := auth.NewAuthService(redisClient, aeroSvc)
|
authSvc := auth.NewAuthService(redisClient, aeroSvc)
|
||||||
humanSvc := human.NewService(db.Pool())
|
humanSvc := human.NewService(db.Pool())
|
||||||
networkSvc := network.NewService(db.Pool())
|
networkSvc := network.NewService(db.Pool(), aeroSvc)
|
||||||
particleSvc := particle.NewService(db.Pool(), networkSvc)
|
particleSvc := particle.NewService(db.Pool(), networkSvc)
|
||||||
depotSvc := depot.NewService(db.Pool(), storageClient, depot.Config{
|
depotSvc := depot.NewService(db.Pool(), storageClient, depot.Config{
|
||||||
GoogleServiceAccountEmail: utils.MustGetEnv("GOOGLE_SERVICE_ACCOUNT_EMAIL"),
|
GoogleServiceAccountEmail: utils.MustGetEnv("GOOGLE_SERVICE_ACCOUNT_EMAIL"),
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func main() {
|
|||||||
|
|
||||||
// Services
|
// Services
|
||||||
authSvc := auth.NewAuthService(authRedis, nil) // nil aeroSvc — pusher only calls GetSession
|
authSvc := auth.NewAuthService(authRedis, nil) // nil aeroSvc — pusher only calls GetSession
|
||||||
networkSvc := network.NewService(db.Pool())
|
networkSvc := network.NewService(db.Pool(), nil) // nil aeroSvc — pusher never calls InviteByEmail
|
||||||
|
|
||||||
// Pod identity (use hostname in k8s, which is the pod name)
|
// Pod identity (use hostname in k8s, which is the pod name)
|
||||||
podID, err := os.Hostname()
|
podID, err := os.Hostname()
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ type Human struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Network struct {
|
type Network struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
AdminHuman Human `json:"admin_human"`
|
AdminHuman Human `json:"admin_human"`
|
||||||
Humans []Human `json:"humans"`
|
Humans []Human `json:"humans"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auth Request/Response DTOs
|
// Auth Request/Response DTOs
|
||||||
@@ -1008,11 +1008,11 @@ func (h *Handler) networkToDTO(ctx context.Context, n *network.Network) (Network
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Network{
|
return Network{
|
||||||
Id: n.ID,
|
Id: n.ID,
|
||||||
Name: n.Name,
|
Name: n.Name,
|
||||||
AdminHuman: humanToDTO(adminHuman),
|
AdminHuman: humanToDTO(adminHuman),
|
||||||
Humans: humans,
|
Humans: humans,
|
||||||
CreatedAt: n.CreatedAt,
|
CreatedAt: n.CreatedAt,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: /Users/talksik/Documents/code/llink/go/genproto/aero/main_grpc.pb.go
|
||||||
|
//
|
||||||
|
// Generated by this command:
|
||||||
|
//
|
||||||
|
// mockgen -source=/Users/talksik/Documents/code/llink/go/genproto/aero/main_grpc.pb.go -destination=/Users/talksik/Documents/code/llink/go/internal/network/mocks/mock_aero.go -package=mocks
|
||||||
|
//
|
||||||
|
|
||||||
|
// Package mocks is a generated GoMock package.
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
pbaero "github.com/flowy-live/llink/genproto/aero"
|
||||||
|
gomock "go.uber.org/mock/gomock"
|
||||||
|
grpc "google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockPrimaryClient is a mock of PrimaryClient interface.
|
||||||
|
type MockPrimaryClient struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockPrimaryClientMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPrimaryClientMockRecorder is the mock recorder for MockPrimaryClient.
|
||||||
|
type MockPrimaryClientMockRecorder struct {
|
||||||
|
mock *MockPrimaryClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockPrimaryClient creates a new mock instance.
|
||||||
|
func NewMockPrimaryClient(ctrl *gomock.Controller) *MockPrimaryClient {
|
||||||
|
mock := &MockPrimaryClient{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockPrimaryClientMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockPrimaryClient) EXPECT() *MockPrimaryClientMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShootEmail mocks base method.
|
||||||
|
func (m *MockPrimaryClient) ShootEmail(ctx context.Context, in *pbaero.ShootEmailRequest, opts ...grpc.CallOption) (*pbaero.ShootEmailResponse, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
varargs := []any{ctx, in}
|
||||||
|
for _, a := range opts {
|
||||||
|
varargs = append(varargs, a)
|
||||||
|
}
|
||||||
|
ret := m.ctrl.Call(m, "ShootEmail", varargs...)
|
||||||
|
ret0, _ := ret[0].(*pbaero.ShootEmailResponse)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShootEmail indicates an expected call of ShootEmail.
|
||||||
|
func (mr *MockPrimaryClientMockRecorder) ShootEmail(ctx, in any, opts ...any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
varargs := append([]any{ctx, in}, opts...)
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShootEmail", reflect.TypeOf((*MockPrimaryClient)(nil).ShootEmail), varargs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPrimaryServer is a mock of PrimaryServer interface.
|
||||||
|
type MockPrimaryServer struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockPrimaryServerMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockPrimaryServerMockRecorder is the mock recorder for MockPrimaryServer.
|
||||||
|
type MockPrimaryServerMockRecorder struct {
|
||||||
|
mock *MockPrimaryServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockPrimaryServer creates a new mock instance.
|
||||||
|
func NewMockPrimaryServer(ctrl *gomock.Controller) *MockPrimaryServer {
|
||||||
|
mock := &MockPrimaryServer{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockPrimaryServerMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockPrimaryServer) EXPECT() *MockPrimaryServerMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShootEmail mocks base method.
|
||||||
|
func (m *MockPrimaryServer) ShootEmail(arg0 context.Context, arg1 *pbaero.ShootEmailRequest) (*pbaero.ShootEmailResponse, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "ShootEmail", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(*pbaero.ShootEmailResponse)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShootEmail indicates an expected call of ShootEmail.
|
||||||
|
func (mr *MockPrimaryServerMockRecorder) ShootEmail(arg0, arg1 any) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShootEmail", reflect.TypeOf((*MockPrimaryServer)(nil).ShootEmail), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustEmbedUnimplementedPrimaryServer mocks base method.
|
||||||
|
func (m *MockPrimaryServer) mustEmbedUnimplementedPrimaryServer() {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
m.ctrl.Call(m, "mustEmbedUnimplementedPrimaryServer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustEmbedUnimplementedPrimaryServer indicates an expected call of mustEmbedUnimplementedPrimaryServer.
|
||||||
|
func (mr *MockPrimaryServerMockRecorder) mustEmbedUnimplementedPrimaryServer() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustEmbedUnimplementedPrimaryServer", reflect.TypeOf((*MockPrimaryServer)(nil).mustEmbedUnimplementedPrimaryServer))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockUnsafePrimaryServer is a mock of UnsafePrimaryServer interface.
|
||||||
|
type MockUnsafePrimaryServer struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockUnsafePrimaryServerMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockUnsafePrimaryServerMockRecorder is the mock recorder for MockUnsafePrimaryServer.
|
||||||
|
type MockUnsafePrimaryServerMockRecorder struct {
|
||||||
|
mock *MockUnsafePrimaryServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockUnsafePrimaryServer creates a new mock instance.
|
||||||
|
func NewMockUnsafePrimaryServer(ctrl *gomock.Controller) *MockUnsafePrimaryServer {
|
||||||
|
mock := &MockUnsafePrimaryServer{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockUnsafePrimaryServerMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockUnsafePrimaryServer) EXPECT() *MockUnsafePrimaryServerMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustEmbedUnimplementedPrimaryServer mocks base method.
|
||||||
|
func (m *MockUnsafePrimaryServer) mustEmbedUnimplementedPrimaryServer() {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
m.ctrl.Call(m, "mustEmbedUnimplementedPrimaryServer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustEmbedUnimplementedPrimaryServer indicates an expected call of mustEmbedUnimplementedPrimaryServer.
|
||||||
|
func (mr *MockUnsafePrimaryServerMockRecorder) mustEmbedUnimplementedPrimaryServer() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustEmbedUnimplementedPrimaryServer", reflect.TypeOf((*MockUnsafePrimaryServer)(nil).mustEmbedUnimplementedPrimaryServer))
|
||||||
|
}
|
||||||
@@ -4,8 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html"
|
||||||
|
"log/slog"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
pbaero "github.com/flowy-live/llink/genproto/aero"
|
||||||
"github.com/flowy-live/llink/internal/utils"
|
"github.com/flowy-live/llink/internal/utils"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
)
|
)
|
||||||
@@ -38,11 +41,12 @@ type Service interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type serviceImpl struct {
|
type serviceImpl struct {
|
||||||
repo repository
|
repo repository
|
||||||
|
aeroSvc pbaero.PrimaryClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(pool *pgxpool.Pool) Service {
|
func NewService(pool *pgxpool.Pool, aeroSvc pbaero.PrimaryClient) Service {
|
||||||
return &serviceImpl{repo: newRepository(pool)}
|
return &serviceImpl{repo: newRepository(pool), aeroSvc: aeroSvc}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceImpl) Create(ctx context.Context, name, adminHumanId string) (*Network, error) {
|
func (s *serviceImpl) Create(ctx context.Context, name, adminHumanId string) (*Network, error) {
|
||||||
@@ -125,6 +129,11 @@ func (s *serviceImpl) ListAll(ctx context.Context) ([]*Network, error) {
|
|||||||
// Invitation methods
|
// Invitation methods
|
||||||
|
|
||||||
func (s *serviceImpl) InviteByEmail(ctx context.Context, networkID string, emails []string) error {
|
func (s *serviceImpl) InviteByEmail(ctx context.Context, networkID string, emails []string) error {
|
||||||
|
network, err := s.repo.getByID(ctx, networkID)
|
||||||
|
if err != nil {
|
||||||
|
return ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
for _, email := range emails {
|
for _, email := range emails {
|
||||||
normalized, err := utils.NormalizeEmail(email)
|
normalized, err := utils.NormalizeEmail(email)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,6 +142,19 @@ func (s *serviceImpl) InviteByEmail(ctx context.Context, networkID string, email
|
|||||||
if err := s.repo.createInvitation(ctx, networkID, normalized); err != nil {
|
if err := s.repo.createInvitation(ctx, networkID, normalized); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = s.aeroSvc.ShootEmail(ctx, &pbaero.ShootEmailRequest{
|
||||||
|
ToEmails: []string{email},
|
||||||
|
Subject: fmt.Sprintf("Invitation to Join %s on Flowy.llink", network.Name),
|
||||||
|
TemplateData: &pbaero.ShootEmailRequest_SimpleHtmlData{
|
||||||
|
SimpleHtmlData: &pbaero.SimpleHtmlData{
|
||||||
|
Html: buildInvitationHTML(network.Name),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.Warn("unable to send email notification", "email", email, "network", network.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -171,3 +193,38 @@ func (s *serviceImpl) RevokeInvitation(ctx context.Context, networkID, email str
|
|||||||
}
|
}
|
||||||
return s.repo.deleteInvitation(ctx, networkID, normalized)
|
return s.repo.deleteInvitation(ctx, networkID, normalized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildInvitationHTML(networkName string) string {
|
||||||
|
const downloadURL = "https://flowylabs.ai/llink"
|
||||||
|
safeName := html.EscapeString(networkName)
|
||||||
|
return fmt.Sprintf(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body style="margin:0;padding:0;background-color:#f5f5f7;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
|
||||||
|
<table role="presentation" width="100%%" cellspacing="0" cellpadding="0" border="0" style="background-color:#f5f5f7;padding:48px 16px;">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<table role="presentation" width="100%%" cellspacing="0" cellpadding="0" border="0" style="max-width:480px;background-color:#ffffff;border-radius:12px;padding:40px;">
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:22px;font-weight:600;color:#111111;padding-bottom:16px;">
|
||||||
|
You've been invited to join %s on Flowy.llink
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="font-size:15px;line-height:1.5;color:#444444;padding-bottom:32px;">
|
||||||
|
Download the app to accept your invitation and connect with your team.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="%s" style="display:inline-block;background-color:#111111;color:#ffffff;text-decoration:none;font-size:15px;font-weight:500;padding:12px 24px;border-radius:8px;">
|
||||||
|
Download Flowy.llink
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>`, safeName, downloadURL)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,10 +5,13 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
pbaero "github.com/flowy-live/llink/genproto/aero"
|
||||||
"github.com/flowy-live/llink/internal/network"
|
"github.com/flowy-live/llink/internal/network"
|
||||||
|
"github.com/flowy-live/llink/internal/network/mocks"
|
||||||
"github.com/flowy-live/llink/internal/testhelper"
|
"github.com/flowy-live/llink/internal/testhelper"
|
||||||
"github.com/jackc/pgx/v5/pgxpool"
|
"github.com/jackc/pgx/v5/pgxpool"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"go.uber.org/mock/gomock"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dbPool *pgxpool.Pool
|
var dbPool *pgxpool.Pool
|
||||||
@@ -21,9 +24,19 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(ret)
|
os.Exit(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newTestService(t *testing.T) network.Service {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
mockAero := mocks.NewMockPrimaryClient(ctrl)
|
||||||
|
mockAero.EXPECT().
|
||||||
|
ShootEmail(gomock.Any(), gomock.Any()).
|
||||||
|
Return(&pbaero.ShootEmailResponse{}, nil).
|
||||||
|
AnyTimes()
|
||||||
|
return network.NewService(dbPool, mockAero)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNetworkService(t *testing.T) {
|
func TestNetworkService(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
svc := network.NewService(dbPool)
|
svc := newTestService(t)
|
||||||
|
|
||||||
adminHumanId := "human_admin123"
|
adminHumanId := "human_admin123"
|
||||||
member1HumanId := "human_member1abc"
|
member1HumanId := "human_member1abc"
|
||||||
@@ -115,7 +128,7 @@ func TestNetworkService(t *testing.T) {
|
|||||||
|
|
||||||
func TestNetworkInvitations(t *testing.T) {
|
func TestNetworkInvitations(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
svc := network.NewService(dbPool)
|
svc := newTestService(t)
|
||||||
|
|
||||||
adminHumanId := "human_invtest_admin"
|
adminHumanId := "human_invtest_admin"
|
||||||
inviteeEmail := "[email protected]"
|
inviteeEmail := "[email protected]"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func getStreamStatus(data json.RawMessage) string {
|
|||||||
|
|
||||||
func TestParticleService_CreateAndGet(t *testing.T) {
|
func TestParticleService_CreateAndGet(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network first
|
// Create a network first
|
||||||
@@ -72,7 +72,7 @@ func TestParticleService_CreateAndGet(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_NestedParticles(t *testing.T) {
|
func TestParticleService_NestedParticles(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network
|
// Create a network
|
||||||
@@ -118,7 +118,7 @@ func TestParticleService_NestedParticles(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_CustomVisibility(t *testing.T) {
|
func TestParticleService_CustomVisibility(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network with a member
|
// Create a network with a member
|
||||||
@@ -160,7 +160,7 @@ func TestParticleService_CustomVisibility(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_UpdateAndDelete(t *testing.T) {
|
func TestParticleService_UpdateAndDelete(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network
|
// Create a network
|
||||||
@@ -198,7 +198,7 @@ func TestParticleService_UpdateAndDelete(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_ListRootParticles(t *testing.T) {
|
func TestParticleService_ListRootParticles(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network
|
// Create a network
|
||||||
@@ -224,7 +224,7 @@ func TestParticleService_ListRootParticles(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_OpenCloseStream(t *testing.T) {
|
func TestParticleService_OpenCloseStream(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network
|
// Create a network
|
||||||
@@ -272,7 +272,7 @@ func TestParticleService_OpenCloseStream(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_NotAStream(t *testing.T) {
|
func TestParticleService_NotAStream(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network
|
// Create a network
|
||||||
@@ -301,7 +301,7 @@ func TestParticleService_NotAStream(t *testing.T) {
|
|||||||
|
|
||||||
func TestParticleService_AccessInheritance(t *testing.T) {
|
func TestParticleService_AccessInheritance(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
networkSvc := network.NewService(dbPool)
|
networkSvc := network.NewService(dbPool, nil)
|
||||||
svc := particle.NewService(dbPool, networkSvc)
|
svc := particle.NewService(dbPool, networkSvc)
|
||||||
|
|
||||||
// Create a network with members
|
// Create a network with members
|
||||||
|
|||||||
Reference in New Issue
Block a user