11const { expect } = require ( 'chai' ) ;
2+ const sinon = require ( 'sinon' ) ;
3+ const { Readable } = require ( 'stream' ) ;
4+ const { HttpClient } = require ( '@contentstack/cli-utilities' ) ;
25const GitHubClient = require ( '../lib/bootstrap/github/client' ) . default ;
6+ const GithubError = require ( '../lib/bootstrap/github/github-error' ) . default ;
37
48describe ( 'Github Client' , function ( ) {
59 it ( 'Parse github url' , ( ) => {
@@ -16,4 +20,106 @@ describe('Github Client', function () {
1620 'https://api.github.com/repos/contentstack/contentstack-nextjs-react-universal-demo/tarball/cli-use' ,
1721 ) ;
1822 } ) ;
23+
24+ describe ( 'streamRelease' , function ( ) {
25+ let sandbox ;
26+
27+ beforeEach ( ( ) => {
28+ sandbox = sinon . createSandbox ( ) ;
29+ } ) ;
30+
31+ afterEach ( ( ) => {
32+ sandbox . restore ( ) ;
33+ } ) ;
34+
35+ it ( 'should throw GithubError with status 404 when the branch does not exist' , async ( ) => {
36+ const notFoundStream = new Readable ( { read ( ) { } } ) ;
37+ notFoundStream . push ( Buffer . from ( '404: Not Found' ) ) ;
38+ notFoundStream . push ( null ) ;
39+
40+ const httpStub = { get : sandbox . stub ( ) . resolves ( { status : 404 , data : notFoundStream } ) , options : sandbox . stub ( ) . returnsThis ( ) } ;
41+ sandbox . stub ( HttpClient , 'create' ) . returns ( httpStub ) ;
42+
43+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/kickstart-next' ) ) ;
44+
45+ try {
46+ await client . streamRelease ( client . gitTarBallUrl ) ;
47+ throw new Error ( 'Expected GithubError to be thrown' ) ;
48+ } catch ( err ) {
49+ expect ( err ) . to . be . instanceOf ( GithubError ) ;
50+ expect ( err . status ) . to . equal ( 404 ) ;
51+ }
52+ } ) ;
53+
54+ it ( 'should throw GithubError with status 500 on server error' , async ( ) => {
55+ const errStream = new Readable ( { read ( ) { } } ) ;
56+ errStream . push ( Buffer . from ( 'Internal Server Error' ) ) ;
57+ errStream . push ( null ) ;
58+
59+ const httpStub = { get : sandbox . stub ( ) . resolves ( { status : 500 , data : errStream } ) , options : sandbox . stub ( ) . returnsThis ( ) } ;
60+ sandbox . stub ( HttpClient , 'create' ) . returns ( httpStub ) ;
61+
62+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/kickstart-next' ) ) ;
63+
64+ try {
65+ await client . streamRelease ( client . gitTarBallUrl ) ;
66+ throw new Error ( 'Expected GithubError to be thrown' ) ;
67+ } catch ( err ) {
68+ expect ( err ) . to . be . instanceOf ( GithubError ) ;
69+ expect ( err . status ) . to . equal ( 500 ) ;
70+ }
71+ } ) ;
72+
73+ it ( 'should return the response stream when status is 200' , async ( ) => {
74+ const mockStream = new Readable ( { read ( ) { } } ) ;
75+ const httpStub = { get : sandbox . stub ( ) . resolves ( { status : 200 , data : mockStream } ) , options : sandbox . stub ( ) . returnsThis ( ) } ;
76+ sandbox . stub ( HttpClient , 'create' ) . returns ( httpStub ) ;
77+
78+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/kickstart-next' ) ) ;
79+ const result = await client . streamRelease ( client . gitTarBallUrl ) ;
80+
81+ expect ( result ) . to . equal ( mockStream ) ;
82+ } ) ;
83+
84+ it ( 'should pass Authorization header for private repos' , async ( ) => {
85+ const mockStream = new Readable ( { read ( ) { } } ) ;
86+ const httpStub = { get : sandbox . stub ( ) . resolves ( { status : 200 , data : mockStream } ) , options : sandbox . stub ( ) . returnsThis ( ) } ;
87+ sandbox . stub ( HttpClient , 'create' ) . returns ( httpStub ) ;
88+
89+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/private-repo' ) , true , 'my-token' ) ;
90+ await client . streamRelease ( client . gitTarBallUrl ) ;
91+
92+ const callOptions = httpStub . options . firstCall . args [ 0 ] ;
93+ expect ( callOptions . headers ) . to . deep . equal ( { Authorization : 'token my-token' } ) ;
94+ } ) ;
95+
96+ it ( 'should throw GithubError immediately for private repos with no access token' , async ( ) => {
97+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/private-repo' ) , true , undefined ) ;
98+
99+ try {
100+ await client . streamRelease ( client . gitTarBallUrl ) ;
101+ throw new Error ( 'Expected GithubError to be thrown' ) ;
102+ } catch ( err ) {
103+ expect ( err ) . to . be . instanceOf ( GithubError ) ;
104+ expect ( err . status ) . to . equal ( 1 ) ;
105+ }
106+ } ) ;
107+ } ) ;
108+
109+ describe ( 'extract' , function ( ) {
110+ it ( 'should reject (not crash the process) when the stream contains invalid gzip data' , async ( ) => {
111+ const client = new GitHubClient ( GitHubClient . parsePath ( 'contentstack/kickstart-next' ) ) ;
112+
113+ const badStream = new Readable ( { read ( ) { } } ) ;
114+ badStream . push ( Buffer . from ( '404: Not Found' ) ) ;
115+ badStream . push ( null ) ;
116+
117+ try {
118+ await client . extract ( '/tmp' , badStream ) ;
119+ throw new Error ( 'Expected extraction error to be thrown' ) ;
120+ } catch ( err ) {
121+ expect ( err . code ) . to . equal ( 'Z_DATA_ERROR' ) ;
122+ }
123+ } ) ;
124+ } ) ;
19125} ) ;
0 commit comments