import sinon from "sinon" ; import { ERROR_CODES } from "coral-common/errors" ; import { pureMerge } from "coral-common/utils" ; import { InvalidRequestError } from "coral-framework/lib/errors" ; import { GQLResolver } from "coral-framework/schema" ; import { act , createAccessToken , createResolversStub , CreateTestRendererParams , replaceHistoryLocation , waitForElement , within , } from "coral-framework/testHelpers" ; import create from "../create" ; import { settings , users } from "../fixtures" ; const user = users . moderators [ 0 ] ; const token = createAccessToken ( { email : user . email ! } ) ; const createTestRenderer = async ( params = { } ) => { const { testRenderer , context } = create ( { ... params , resolvers : pureMerge ( createResolversStub < GQLResolver > ( { Query : { settings : ( ) => settings , } , } ) , params . resolvers ) , initLocalState : ( localRecord , source , environment ) => { if ( params . initLocalState ) { params . initLocalState ( localRecord , source , environment ) ; } } , } ) ; return { context , root : testRenderer . root } ; } ; it ( "renders missing the token" , async ( ) => { replaceHistoryLocation ( "http://localhost/admin/invite" ) ; const { root } = await createTestRenderer ( ) ; await waitForElement ( ( ) => within ( root ) . getByTestID ( "invalid-link" ) ) ; expect ( within ( root ) . toJSON ( ) ) . toMatchSnapshot ( ) ; } ) ; it ( "renders form" , async ( ) => { replaceHistoryLocation ( `http://localhost/admin/invite#inviteToken=${ token }` ) ; const { root , context } = await createTestRenderer ( ) ; const mock = sinon . mock ( context . rest ) ; mock . expects ( "fetch" ) . withArgs ( "/account/invite" , { method : "GET" , token , } ) . once ( ) ; await act ( async ( ) => { await waitForElement ( ( ) => within ( root ) . getByTestID ( "invite-complete-form" ) ) ; } ) ; expect ( within ( root ) . toJSON ( ) ) . toMatchSnapshot ( ) ; mock . verify ( ) ; } ) ; it ( "renders error from server" , async ( ) => { replaceHistoryLocation ( `http://localhost/admin/invite#inviteToken=${ token }` ) ; const codes = [ ERROR_CODES . RATE_LIMIT_EXCEEDED , ERROR_CODES . INVITE_TOKEN_EXPIRED , ERROR_CODES . INTEGRATION_DISABLED , ERROR_CODES . USER_NOT_FOUND , ERROR_CODES . TOKEN_INVALID , ] ; for ( const code of codes ) { const { root , context } = await createTestRenderer ( ) ; const mock = sinon . mock ( context . rest ) ; mock . expects ( "fetch" ) . withArgs ( "/account/invite" , { method : "GET" , token , } ) . once ( ) . throwsException ( new InvalidRequestError ( { code , traceID : "traceID" , } ) ) ; await act ( async ( ) => { await waitForElement ( ( ) => within ( root ) . getByTestID ( "invite-complete-sorry" ) ) ; } ) ; mock . verify ( ) ; } } ) ; it ( "submits form" , async ( ) => { replaceHistoryLocation ( `http://localhost/admin/invite#inviteToken=${ token }` ) ; const { context , root } = await createTestRenderer ( ) ; const mock = sinon . mock ( context . rest ) ; mock . expects ( "fetch" ) . withArgs ( "/account/invite" , { method : "GET" , token , } ) . once ( ) ; mock . expects ( "fetch" ) . withArgs ( "/account/invite" , { method : "PUT" , token , body : { username : user . username ! , password : "testtest" , } , } ) . once ( ) ; await act ( async ( ) => { await waitForElement ( ( ) => within ( root ) . getByTestID ( "invite-complete-form" ) ) ; await waitForElement ( ( ) => within ( root ) . getByText ( user . email ! , { exact : false } ) ) ; } ) ; const form = within ( root ) . getByType ( "form" ) ; const usernameField = within ( root ) . getByLabelText ( "Username" ) ; const passwordField = within ( root ) . getByLabelText ( "Password" ) ; await act ( async ( ) => { await form . props . onSubmit ( ) ; } ) ; within ( root ) . getAllByText ( "field is required" , { exact : false , } ) ; act ( ( ) => { usernameField . props . onChange ( user . username ! ) ; passwordField . props . onChange ( "test" ) ; } ) ; within ( root ) . getByText ( "Password must contain at least 8 characters" , { exact : false , } ) ; await act ( ( ) => { passwordField . props . onChange ( "testtest" ) ; return form . props . onSubmit ( ) ; } ) ; await waitForElement ( ( ) => within ( root ) . getByTestID ( "invite-complete-success" ) ) ; mock . verify ( ) ; } ) ;