@@ -18,7 +18,7 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
1818 vi . clearAllMocks ( ) ;
1919 } ) ;
2020
21- it ( 'should render and initialize device flow ' , async ( ) => {
21+ it ( 'should render scope choice buttons ' , async ( ) => {
2222 const loginWithDeviceFlowStartMock = vi . fn ( ) . mockResolvedValueOnce ( {
2323 hostname : 'github.com' ,
2424 clientId : 'test-id' ,
@@ -33,10 +33,39 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
3333 loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
3434 } ) ;
3535
36- expect ( loginWithDeviceFlowStartMock ) . toHaveBeenCalled ( ) ;
36+ expect ( screen . getByText ( 'Receive notifications for:' ) ) . toBeInTheDocument ( ) ;
37+ expect ( screen . getByTestId ( 'device-scope-public' ) ) . toBeInTheDocument ( ) ;
38+ expect ( screen . getByTestId ( 'device-scope-full' ) ) . toBeInTheDocument ( ) ;
3739
38- await screen . findByText ( / U S E R - 1 2 3 4 / ) ;
39- expect ( screen . getByText ( / g i t h u b .c o m \/ l o g i n \/ d e v i c e / ) ) . toBeInTheDocument ( ) ;
40+ // Device flow should not start until user makes a choice
41+ expect ( loginWithDeviceFlowStartMock ) . not . toHaveBeenCalled ( ) ;
42+ } ) ;
43+
44+ it ( 'should start device flow with public scope when clicking Public' , async ( ) => {
45+ const loginWithDeviceFlowStartMock = vi . fn ( ) . mockResolvedValueOnce ( {
46+ hostname : 'github.com' ,
47+ clientId : 'test-id' ,
48+ deviceCode : 'device-code' ,
49+ userCode : 'USER-1234' ,
50+ verificationUri : 'https://github.com/login/device' ,
51+ intervalSeconds : 5 ,
52+ expiresAt : Date . now ( ) + 900000 ,
53+ } ) ;
54+
55+ renderWithAppContext ( < LoginWithDeviceFlowRoute /> , {
56+ loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
57+ } ) ;
58+
59+ await userEvent . click ( screen . getByTestId ( 'device-scope-public' ) ) ;
60+
61+ expect ( loginWithDeviceFlowStartMock ) . toHaveBeenCalledWith ( undefined , [
62+ 'notifications' ,
63+ 'read:user' ,
64+ 'public_repo' ,
65+ ] ) ;
66+
67+ await screen . findByTestId ( 'device-user-code' ) ;
68+ expect ( screen . getByTestId ( 'device-verification-link' ) ) . toBeInTheDocument ( ) ;
4069
4170 // Verify auto-copy and auto-open were called
4271 expect ( copyToClipboardSpy ) . toHaveBeenCalledWith ( 'USER-1234' ) ;
@@ -45,6 +74,32 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
4574 ) ;
4675 } ) ;
4776
77+ it ( 'should start device flow with full scope when clicking Public and Private' , async ( ) => {
78+ const loginWithDeviceFlowStartMock = vi . fn ( ) . mockResolvedValueOnce ( {
79+ hostname : 'github.com' ,
80+ clientId : 'test-id' ,
81+ deviceCode : 'device-code' ,
82+ userCode : 'USER-1234' ,
83+ verificationUri : 'https://github.com/login/device' ,
84+ intervalSeconds : 5 ,
85+ expiresAt : Date . now ( ) + 900000 ,
86+ } ) ;
87+
88+ renderWithAppContext ( < LoginWithDeviceFlowRoute /> , {
89+ loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
90+ } ) ;
91+
92+ await userEvent . click ( screen . getByTestId ( 'device-scope-full' ) ) ;
93+
94+ expect ( loginWithDeviceFlowStartMock ) . toHaveBeenCalledWith ( undefined , [
95+ 'notifications' ,
96+ 'read:user' ,
97+ 'repo' ,
98+ ] ) ;
99+
100+ await screen . findByTestId ( 'device-user-code' ) ;
101+ } ) ;
102+
48103 it ( 'should copy user code to clipboard when clicking copy button' , async ( ) => {
49104 const loginWithDeviceFlowStartMock = vi . fn ( ) . mockResolvedValueOnce ( {
50105 hostname : 'github.com' ,
@@ -60,12 +115,13 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
60115 loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
61116 } ) ;
62117
63- await screen . findByText ( / U S E R - 1 2 3 4 / ) ;
118+ await userEvent . click ( screen . getByTestId ( 'device-scope-public' ) ) ;
119+ await screen . findByTestId ( 'device-user-code' ) ;
64120
65121 // Clear the auto-copy call from initialization
66122 copyToClipboardSpy . mockClear ( ) ;
67123
68- await userEvent . click ( screen . getByLabelText ( 'Copy device code') ) ;
124+ await userEvent . click ( screen . getByTestId ( 'copy- device- code') ) ;
69125
70126 expect ( copyToClipboardSpy ) . toHaveBeenCalledWith ( 'USER-1234' ) ;
71127 } ) ;
@@ -79,10 +135,12 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
79135 loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
80136 } ) ;
81137
138+ await userEvent . click ( screen . getByTestId ( 'device-scope-full' ) ) ;
139+
82140 await screen . findByText ( / F a i l e d t o s t a r t a u t h e n t i c a t i o n / ) ;
83141 } ) ;
84142
85- it ( 'should navigate back on cancel' , async ( ) => {
143+ it ( 'should navigate back on cancel from scope choice ' , async ( ) => {
86144 const loginWithDeviceFlowStartMock = vi . fn ( ) . mockResolvedValueOnce ( {
87145 hostname : 'github.com' ,
88146 clientId : 'test-id' ,
@@ -97,9 +155,7 @@ describe('renderer/routes/LoginWithDeviceFlow.tsx', () => {
97155 loginWithDeviceFlowStart : loginWithDeviceFlowStartMock ,
98156 } ) ;
99157
100- await screen . findByText ( / U S E R - 1 2 3 4 / ) ;
101-
102- await userEvent . click ( screen . getByText ( 'Cancel' ) ) ;
158+ await userEvent . click ( screen . getByTestId ( 'cancel-button' ) ) ;
103159
104160 expect ( navigateMock ) . toHaveBeenCalledWith ( - 1 ) ;
105161 } ) ;
0 commit comments