Skip to content

Commit

Permalink
GH-163: Added additional tests for static resource.
Browse files Browse the repository at this point in the history
  • Loading branch information
jirenius committed Jun 10, 2020
1 parent b5c49a2 commit fed577d
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 55 deletions.
64 changes: 58 additions & 6 deletions test/01subscribe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestResponseOnPrimitiveModelRetrieval(t *testing.T) {
modelGetResponse := json.RawMessage(`{"model":` + model + `}`)
fullAccess := json.RawMessage(`{"get":true}`)
noAccess := json.RawMessage(`{"get":false}`)
modelClientResponse := json.RawMessage(`{"models":{"test.model":` + model + `}}`)
modelClientResponse := json.RawMessage(`{"models":{"test.resource":` + model + `}}`)

// *reserr.Error implies an error response. requestTimeout implies a timeout. Otherwise success.
tbl := []struct {
Expand Down Expand Up @@ -97,6 +97,11 @@ func TestResponseOnPrimitiveModelRetrieval(t *testing.T) {
{json.RawMessage(`{"collection":["prop",{"action":"delete"}]}`), fullAccess, reserr.CodeInternalError},
{json.RawMessage(`{"collection":["prop",{"action":"unknown"}]}`), fullAccess, reserr.CodeInternalError},
{json.RawMessage(`{"collection":["prop",{"unknown":"property"}]}`), fullAccess, reserr.CodeInternalError},
// Multiple resource types
{json.RawMessage(`{"model":{"foo":"bar"},"collection":[1,2,3],"static":{"foo":["bar"]}}`), fullAccess, reserr.CodeInternalError},
{json.RawMessage(`{"model":{"foo":"bar"},"collection":[1,2,3]}`), fullAccess, reserr.CodeInternalError},
{json.RawMessage(`{"model":{"foo":"bar"},"static":{"foo":["bar"]}}`), fullAccess, reserr.CodeInternalError},
{json.RawMessage(`{"collection":[1,2,3],"static":{"foo":["bar"]}}`), fullAccess, reserr.CodeInternalError},
// Invalid get error response
{[]byte(`{"error":[]}`), fullAccess, reserr.CodeInternalError},
{[]byte(`{"error":{"message":"missing code"}}`), fullAccess, ""},
Expand All @@ -119,16 +124,16 @@ func TestResponseOnPrimitiveModelRetrieval(t *testing.T) {
var creq *ClientRequest
switch method {
case "get":
creq = c.Request("get.test.model", nil)
creq = c.Request("get.test.resource", nil)
case "subscribe":
creq = c.Request("subscribe.test.model", nil)
creq = c.Request("subscribe.test.resource", nil)
}
mreqs := s.GetParallelRequests(t, 2)

var req *Request
if getFirst {
// Send get response
req = mreqs.GetRequest(t, "get.test.model")
req = mreqs.GetRequest(t, "get.test.resource")
if l.GetResponse == requestTimeout {
req.Timeout()
} else if err, ok := l.GetResponse.(*reserr.Error); ok {
Expand All @@ -141,7 +146,7 @@ func TestResponseOnPrimitiveModelRetrieval(t *testing.T) {
}

// Send access response
req = mreqs.GetRequest(t, "access.test.model")
req = mreqs.GetRequest(t, "access.test.resource")
if l.AccessResponse == requestTimeout {
req.Timeout()
} else if err, ok := l.AccessResponse.(*reserr.Error); ok {
Expand All @@ -154,7 +159,7 @@ func TestResponseOnPrimitiveModelRetrieval(t *testing.T) {

if !getFirst {
// Send get response
req := mreqs.GetRequest(t, "get.test.model")
req := mreqs.GetRequest(t, "get.test.resource")
if l.GetResponse == nil {
req.Timeout()
} else if err, ok := l.GetResponse.(*reserr.Error); ok {
Expand Down Expand Up @@ -378,3 +383,50 @@ func TestSubscribe_WithCIDPlaceholder_ReplacesCID(t *testing.T) {
c.GetEvent(t).AssertEventName(t, "test.{cid}.model.custom")
})
}

func TestSubscribe_MultipleClientSubscribingResource_FetchedFromCache(t *testing.T) {
tbl := []struct {
RID string
}{
{"test.model"},
{"test.collection"},
{"test.static"},
}
for i, l := range tbl {
runNamedTest(t, fmt.Sprintf("#%d", i+1), func(s *Session) {
rid := l.RID
c1 := s.Connect()
subscribeToResource(t, s, c1, rid)

// Connect with second client
c2 := s.Connect()
// Send subscribe request
c2req := c2.Request("subscribe."+rid, nil)
s.GetRequest(t).
AssertSubject(t, "access."+rid).
RespondSuccess(json.RawMessage(`{"get":true}`))
// Handle resource and validate client response
rsrc, ok := resources[rid]
if !ok {
panic("no resource named " + rid)
}
var r string
if rsrc.typ == typeError {
b, _ := json.Marshal(rsrc.err)
r = string(b)
} else {
r = rsrc.data
}
switch rsrc.typ {
case typeModel:
c2req.GetResponse(t).AssertResult(t, json.RawMessage(`{"models":{"`+rid+`":`+r+`}}`))
case typeCollection:
c2req.GetResponse(t).AssertResult(t, json.RawMessage(`{"collections":{"`+rid+`":`+r+`}}`))
case typeStatic:
c2req.GetResponse(t).AssertResult(t, json.RawMessage(`{"statics":{"`+rid+`":`+r+`}}`))
default:
panic("invalid type")
}
})
}
}
17 changes: 17 additions & 0 deletions test/03unsubscribe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,23 @@ func TestUnsubscribeOnOverlappingLinkedCollection(t *testing.T) {
})
}

// Test that a client can unsubscribe to a static
func TestUnsubscribeStatic(t *testing.T) {
runTest(t, func(s *Session) {
event := json.RawMessage(`{"foo":"bar"}`)

c := s.Connect()
subscribeToResource(t, s, c, "test.static")

// Call unsubscribe
c.Request("unsubscribe.test.static", nil).GetResponse(t)

// Send event on static and validate no event was sent to client
s.ResourceEvent("test.static", "custom", event)
c.AssertNoEvent(t, "test.static")
})
}

func TestUnsubscribe_FollowedByResourceResponse_IncludesResource(t *testing.T) {
for useCount := true; useCount; useCount = false {
runNamedTest(t, fmt.Sprintf("with useCount set to %+v", useCount), func(s *Session) {
Expand Down
79 changes: 78 additions & 1 deletion test/11system_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,27 @@ func TestSystemResetTriggersGetRequestOnCollection(t *testing.T) {
})
}

// Test that a system.reset event triggers get requests on matching static
func TestSystemResetTriggersGetRequestOnStatic(t *testing.T) {
runTest(t, func(s *Session) {
static := resourceData("test.static")

c := s.Connect()

// Get static
subscribeToResource(t, s, c, "test.static")

// Send system reset
s.SystemEvent("reset", json.RawMessage(`{"resources":["test.>"]}`))

// Validate a get request is sent
s.GetRequest(t).AssertSubject(t, "get.test.static").RespondSuccess(json.RawMessage(`{"static":` + static + `}`))

// Validate no events are sent to client
c.AssertNoEvent(t, "test.static")
})
}

func TestSystemReset_WithUpdatedResource_GeneratesEvents(t *testing.T) {
type event struct {
Event string
Expand Down Expand Up @@ -89,6 +110,7 @@ func TestSystemReset_WithUpdatedResource_GeneratesEvents(t *testing.T) {
{"test.collection.soft", `{"collection":["soft"]}`, []event{
{"remove", `{"idx":1}`},
}},
{"test.static", `{"static":{"foo":null}}`, []event{}},
}

for i, l := range tbl {
Expand Down Expand Up @@ -260,6 +282,23 @@ func TestSystemReset_NotFoundResponseOnCollection_GeneratesDeleteEvent(t *testin
})
}

func TestSystemReset_NotFoundResponseOnStatic_GeneratesDeleteEvent(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
// Get model
subscribeToResource(t, s, c, "test.static")
// Send system reset
s.SystemEvent("reset", json.RawMessage(`{"resources":["test.>"]}`))
// Respond to get request with system.notFound error
s.GetRequest(t).AssertSubject(t, "get.test.static").RespondError(reserr.ErrNotFound)
// Validate delete event is sent to client
c.GetEvent(t).AssertEventName(t, "test.static.delete").AssertData(t, nil)
// Validate subsequent events are not sent to client
s.ResourceEvent("test.static", "custom", common.CustomEvent())
c.AssertNoEvent(t, "test.static")
})
}

func TestSystemReset_InternalErrorResponseOnModel_LogsError(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
Expand Down Expand Up @@ -298,6 +337,25 @@ func TestSystemReset_InternalErrorResponseOnCollection_LogsError(t *testing.T) {
})
}

func TestSystemReset_InternalErrorResponseOnStatic_LogsError(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
// Get static
subscribeToResource(t, s, c, "test.static")
// Send system reset
s.SystemEvent("reset", json.RawMessage(`{"resources":["test.>"]}`))
// Respond to get request with system.notFound error
s.GetRequest(t).AssertSubject(t, "get.test.static").RespondError(reserr.ErrInternalError)
// Validate no delete event is sent to client
c.AssertNoEvent(t, "test.static")
// Validate subsequent events are sent to client
s.ResourceEvent("test.static", "custom", common.CustomEvent())
c.GetEvent(t).Equals(t, "test.static.custom", common.CustomEvent())
// Assert error is logged
s.AssertErrorsLogged(t, 1)
})
}

func TestSystemReset_MismatchingResourceTypeResponseOnModel_LogsError(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
Expand Down Expand Up @@ -325,7 +383,7 @@ func TestSystemReset_MismatchingResourceTypeResponseOnCollection_LogsError(t *te
// Send system reset
s.SystemEvent("reset", json.RawMessage(`{"resources":["test.>"]}`))
// Respond to get request with mismatching type
s.GetRequest(t).AssertSubject(t, "get.test.collection").RespondSuccess(json.RawMessage(`{"model":{"string":"foo","int":42,"bool":true,"null":null}}`))
s.GetRequest(t).AssertSubject(t, "get.test.collection").RespondSuccess(json.RawMessage(`{"static":{"foo":{"bar":[null],"baz":42}}}`))
// Validate no delete event is sent to client
c.AssertNoEvent(t, "test.collection")
// Validate subsequent events are sent to client
Expand All @@ -335,3 +393,22 @@ func TestSystemReset_MismatchingResourceTypeResponseOnCollection_LogsError(t *te
s.AssertErrorsLogged(t, 1)
})
}

func TestSystemReset_MismatchingResourceTypeResponseOnStatic_LogsError(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
// Get static
subscribeToResource(t, s, c, "test.static")
// Send system reset
s.SystemEvent("reset", json.RawMessage(`{"resources":["test.>"]}`))
// Respond to get request with mismatching type
s.GetRequest(t).AssertSubject(t, "get.test.static").RespondSuccess(json.RawMessage(`{"model":{"string":"foo","int":42,"bool":true,"null":null}}`))
// Validate no delete event is sent to client
c.AssertNoEvent(t, "test.static")
// Validate subsequent events are sent to client
s.ResourceEvent("test.static", "custom", common.CustomEvent())
c.GetEvent(t).Equals(t, "test.static.custom", common.CustomEvent())
// Assert error is logged
s.AssertErrorsLogged(t, 1)
})
}
17 changes: 17 additions & 0 deletions test/13query_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,23 @@ func TestQueryEvent_DeleteEventOnCollection_DeletesFromCache(t *testing.T) {
})
}

func TestQueryEvent_DeleteEventOnStatic_DeletesFromCache(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
subscribeToQueryResource(t, s, c, "test.static", "q=foo&f=bar", "q=foo&f=bar")
// Send query event
s.ResourceEvent("test.static", "query", json.RawMessage(`{"subject":"_EVENT_01_"}`))
// Respond to query request with an error
s.GetRequest(t).RespondSuccess(json.RawMessage(`{"events":[{"event":"delete"},{"event":"custom","data":{"foo":"bar"}}]}`))
// Validate only delete event is sent to client
c.GetEvent(t).AssertEventName(t, "test.static?q=foo&f=bar.delete").AssertData(t, nil)
c.AssertNoEvent(t, "test.static")
// Validate subsequent query events does not send request
s.ResourceEvent("test.static", "query", json.RawMessage(`{"subject":"_EVENT_02_"}`))
c.AssertNoNATSRequest(t, "test.static")
})
}

func TestQueryEvent_MultipleClientsWithDifferentQueries_SendsMultipleQueryRequest(t *testing.T) {
runTest(t, func(s *Session) {
c1 := s.Connect()
Expand Down
42 changes: 42 additions & 0 deletions test/29delete_event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ func TestDeleteEvent_OnCollection_SentToClient(t *testing.T) {
})
}

func TestDeleteEvent_OnStatic_SentToClient(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
subscribeToResource(t, s, c, "test.static")

// Send delete event
s.ResourceEvent("test.static", "delete", nil)

// Validate the delete event is sent to client
c.GetEvent(t).Equals(t, "test.static.delete", nil)
})
}

func TestDeleteEvent_AndCustomEventOnModel_CustomEventNotSentToClient(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
Expand All @@ -57,6 +70,19 @@ func TestDeleteEvent_AndCustomEventOnCollection_CustomEventNotSentToClient(t *te
})
}

func TestDeleteEvent_AndCustomEventOnStatic_CustomEventNotSentToClient(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
subscribeToResource(t, s, c, "test.static")
// Send delete event
s.ResourceEvent("test.static", "delete", nil)
c.GetEvent(t).Equals(t, "test.static.delete", nil)
// Send custom event on static and validate no event
s.ResourceEvent("test.static", "custom", common.CustomEvent())
c.AssertNoEvent(t, "test.static")
})
}

func TestDeleteEvent_PriorToGetResponse_IsDiscarded(t *testing.T) {
runTest(t, func(s *Session) {
model := resourceData("test.model")
Expand Down Expand Up @@ -155,3 +181,19 @@ func TestDeleteEvent_OnCollectionQueuedForEviction_DoesNothing(t *testing.T) {
c.AssertNoEvent(t, "test.collection")
})
}

func TestDeleteEvent_OnStaticQueuedForEviction_DoesNothing(t *testing.T) {
runTest(t, func(s *Session) {
c := s.Connect()
subscribeToResource(t, s, c, "test.static")

// Unsubscribe to resource
c.Request("unsubscribe.test.static", nil).GetResponse(t)

// Send delete event
s.ResourceEvent("test.static", "delete", nil)

// Validate the delete event is sent to client
c.AssertNoEvent(t, "test.static")
})
}
Loading

0 comments on commit fed577d

Please sign in to comment.